Inserting notes into our manuscript allows us to move on with our writing and save the editing details for later. We improve upon a simpler note macro by including any selected text or a nearby word for extra context.
Thanks for your interest
This content is part of a paid plan.
Quickly insert contextual notes
We're in the zone. The words are flowing through our fingers onto the screen. Pages fill with amazing dialog, tantalizing scene descriptions … then we hit a speed bump. What year was a repeating rifle invented? Can this bandit have one for the train robbery? Seven rounds in the magazine is a lot different than sixteen.
Uhhhh … it doesn't matter, right? Right?
Just move on … but what if I forget to check it later?
We want to keep our writing momentum, but we also don't want to get a significant detail wrong about a scene. Our minds can freeze like stubborn neurological mules, but it's easy to lose focus if we stop to research it now.
Enter novel notes.
I can type the word I'm thinking and just throw in a note to remind myself. That's what editing is for.

Granted we don't want to leave everything for the editing phase, but getting a decent story on the page is a priority in the first draft. Some details just have to wait. This macro improves a previous simple novel note by including some context. Then we move on with writing (or more editing).
Novel note variations
A lot of personal variation exists in notes based on different the wording, placement, context, or style. We can't cover every variation, but we're introducing several variations that can be customized as needed. Previous note macros include:
- A simple inline note could be created with a formatted AutoCorrect entry, but we also implemented an inline note macro.
- The little sibling of the current macro inserts a simple novel note as a styled paragraph.
This article adds the note with some extra context based on the initial selection or nearby text if no text is selected. It further validates the applied paragraph style and solves some other tricky gotchas, so we don't get nasty error messages.
Skip to the macro steps or the final macro if you prefer to avoid the explanation.
Including note context
How do we include context with the note? Often a new note is related to the word just typed, or we could select the text we need for the context.
The macro needs to detect whether an initial selection exists and include that information in the note. If not, it should automatically get the previous word to include in the note text. The latter case just makes the macro more convenient in a common use case.
What are the manual steps using the selection?
We want to quickly insert a note in a new paragraph along with the contextual information. What manual steps would we use to add a new novel note paragraph? We'll assume an initial selection for now something like the following:

Several ways exist to manually add the note, so let's consider a direct route.
- Select and copy any relevant text for the note with the keyboard or mouse
- Move to the beginning of the current paragraph
- Tap Return to Insert a new paragraph and up arrow to move to the empty paragraph
- Type the note prefix text or use an AutoCorrect entry
- Paste the selected text
- Change the new paragraph style (optional)
- Move back to the original editing location to keep working
Several standard Word keyboard shortcuts exist to move by paragraphs, select text, and copy and paste content. Using an AutoCorrect entry will speed up the note text, and we have another macro to toggle paragraph styles with a shortcut. Regardless, it’s a lot of steps if we insert such notes often. Plus, we need to move back and forth in the document to get it done. It all adds up to wasted time.
What is an object in VBA?
Word VBA uses virtual (in the everyday sense) "objects" to represent various document elements. Typical examples include a Paragraph or a Document, but more practical and generalized types also exist such as a Range. Objects include various actions (called "methods") and data (called "properties") that allow us to manipulate them or any associated document content. The methods and properties are reminiscent of what we can manually do with the object in a document. Most VBA objects are named as expected just capitalized.
What is the Selection?
VBA represents the selection or insertion point of the document on the screen with an object called … the Selection (with a capital S). As such, only one Selection exists per document. It can also represent an insertion point (i.e., the blinking I-bar waiting for text) since that is just an empty selection in the document.
As a VBA object, the Selection includes any spanned content which is marked by Start and End position properties, but it also includes many other methods and properties that allow us to control its extent or position in the document, change settings, insert or delete content, and handle other details related to its purpose in a document. A separate article goes into more detail about the Selection.
What is a Range?
A Range object corresponds to a span of document content. It includes Start and End positions like the Selection, but a Range is more general. We can assign document ranges to a variable and treat that range much like an invisible selection or insertion point. Using various methods or properties, we could move it around the document, change its extent, delete or modify the spanned content, access collections of spanned content, etc. See a separate article for a brief introduction to Ranges.
What is a Paragraph?
A Paragraph is a specific VBA representation of the document element. It spans content bounded paragraph marks on both sides (unless it's at the beginning of the document). A Paragraph object stores specific information related to its formatting and other settings. We can create a Paragraph variable to refer to a specific paragraph in the document and use the various methods and properties to manipulate it.
Difference between a Paragraph and a Range
A Paragraph is its own object data type with properties and methods specific to describing paragraph attributes. A Range works more with its position or extent of its spanned content. A few Paragraph properties overlap with similar ones for a Range variable, but the two objects generally have different purposes in VBA. Given its name, a Paragraph object, accessed by any means, spans only a single document paragraph; but a Range can span any amount of document content.
Use Range variables in this macro
One goal of the current macro is to insert the contextual note but leave the insertion point in place, so we can keep writing with minimal interruption. Using a Range variable to carry out the task is the easiest way to make our changes without disturbing the position of the Selection.
Create the empty macro
Open the VBA editor and create the following macro. If you prefer, a previous post covers creating an empty macro using the Word interface. Either way, the result will look something like:
The single quotes tell VBA the rest of the text on that line is a comment meant for human readers. The note is longer in this macro because it does more than just insert a fixed note, and we make an extra assumption that should be mentioned. We start our macro steps on the empty line.
Insert a contextual novel note
We will determine the context of the note based on the initial selection or a nearby word if no selection exists. Then we'll insert it along with the note prefix.
Declare the working ranges
Let's tell VBA what Range variables we'll be using.
Dim is the keyword used to declare most variables, and As Range tells VBA what type of data it stores. I tend to include an "r" as a prefix for range variables to remind myself what type of data the variable stores. The note context variable is named rNote. I often call it a "working range" because we need to work with it to make it refer to the precise document content we need.
This statement also defines the working paragraph range rParagraph which we will use later. We just need to separate them with a comma and make sure to give the data type for both variables. We could reuse the same range variable (probably calling it something more generic like just r) since rNote is not needed after we get the note text, but this article uses separate variables for extra clarity.
The variable names are now set aside to store some undetermined document range, but at this point, they are literally assigned a value of Nothing by VBA.
Do I gotta tell VBA my variables?
Telling VBA what variables we will use is not required by default. I appreciate the freedom of letting VBA automatically assign the data types for variables. I use it for prototype macros, but for any significant macros with more than a few steps, I declare the variables explicitly.
Declaring variables is messier but clearer. It also avoids silly spelling mistakes where VBA just keeps going because it thinks I created another variable rather than reassigning an existing one. The downside is it makes our macros look a little more like programming than a series of editing steps.
Set the current paragraph Range
The note will eventually be placed in a styled paragraph above the current one, which is my preferred location, so the novel text remains clear. With this goal in mind, it is convenient to define a working range corresponding to the initial paragraph.
Get the current (first) paragraph Range
We start by referring to the Paragraphs collection of the Selection.
We get the first paragraph of the collection using its First property.
A Paragraph is its own data type in VBA. We want the paragraph's range, so we can access the text manipulation methods. We refer to the content it spans using its Range property.
If the Selection spans more than one paragraph, we only use the first one. In most cases, the macro will be run with an insertion point or with a selection spanning only a few words within a single paragraph.
Store the current paragraph range
We assign this paragraph range to our paragraph range variable.
We must use Set with any object assignment, which includes Range variables, since they contain more complicated data than just a value. This assignment works even if the starting selection doesn’t include the whole paragraph or if the selection spans multiple paragraphs (following paragraphs are ignored).
This range variable spans the first paragraph, but once its assigned, we can manipulate it independent of the paragraph range. In this macro, we use it to detect the beginning of the paragraph and to insert the note text.
Get the note text
We need to identify the appropriate note text based on whether an initial Selection exists or not.
Store the Selection Range for the note text
Since the context information is coming from the initial selection or a word at or near the insertion point, it's convenient to define our working note range based on the initial Selection. We specifically refer to its Range property.
While the Selection is like a Range since both span some document content, we need to refer to the Range of the Selection since the Selection is the distinct object related to what we manipulate on screen. Even though we assigned it based on the Selection, rNote can be manipulated independent of the Selection.
Expand over the nearest word
In preparation for our contextual note, we extend the range over the nearest word(s) using the appropriately named Expand method.
The default unit for Expand is by word, which is what we need, so we omit the Unit option. We could be explicit (and redundant) and include the Unit option with the wdWord constant from a table of unit constants.
How will the expansion by word work?
If the macro starts with just an insertion point in the document, the range will expand over the current or previous word. If more than one word is partially selected, the range will extend both ways until the words on both sides are included.
A side effect is it will extend the range over any trailing spaces (which is also the default Word behavior for automatic selections), so we need to account for that below.
No Selection Type detection needed (aside)
It is tempting to add an If statement to check whether the range is empty before expanding over the nearest word. Without much explanation, a knee-jerk solution might be something like the following steps:
This isn't necessary.
Word expansion works for either initial state
The expansion by a word unit does not interfere with either use case (whether an initial selection exists or not). If the range spans any text, it just makes sure all the words are fully included. If the range was empty, it expands over the nearest word as intended (mostly, see gotchas below). Both uses are convenient for this macro. Also, trimming any extra spaces around the range can to be done either way.
Trim extra spaces
I tend to keep article macros on the simpler side, but this improvement only needs two lines, and it keeps the note tidy without annoying extra spaces lurking anywhere.
Trim spaces from end of the Range
It's more likely that we'll need to trim spaces from the end of the range. The MoveEndWhile method moves the End position of the range across any desired characters while it keeps finding them at the end position.
The command requires a set of search characters which is just a space in this macro. We assign all desired search characters as plain text to the Cset option. The characters are usually given in double quotes (called a string), so our character set is just " ".
We're moving the End position of the range backward, so we need to specify the count option as wdBackward from a short Word constants table.
This constant tells the command to move any number of spaces backward in the document. We separate the options with a comma, and both require a colon equals := symbol for the assignments.
Trim spaces from start of the Range
We also trim any spaces from the beginning of the range. This will not usually matter since the above Expand command usually stops at the beginning of a word, but it avoids an unusual case where the user might include a preceding space in the initial selection at the beginning of the paragraph.
We use the corresponding MoveStartWhile method which obviously moves the Start position of the range.
We again use a space " " as the character set, but the default is to move the Start position forward in the document, so we can omit the Count option.
Store the contextual note
We'll define the note text as a String variable, and assign it a value later.
String variables only store plain text without any formatting, but they are a very common way to represent text. I tend to add an "s" at the beginning of string variables again as a reminder of the type of data it stores.
We refer to the Text property of the note text range to get its plain text contents.
Then we store it in our novel note string variable. This is not strictly necessary, but it makes the macro easier to read and modify later.
We used an equals = sign to store the note text in the variable since a string is basically (but not quite) a value like a number. We "concatenate" the strings together with a plus + sign which mimics addition with numbers, but the effect with strings is to just jam them together into a new longer string. The preface text included a space at the end with "Check " since the rNote text will not include a space at the beginning. We trimmed any potential spaces earlier, so building the note text this way ensures the have the spacing we want.
Insert the new paragraph
In the current macro, we're inserting the note into a separate paragraph to improve clarity, so we need to add the new paragraph using the InsertParagraphBefore method.
This command illustrates manipulating rParagraph as an independent range. Our rParagraph variable now spans the new, empty paragraph and the original paragraph. The original paragraph is still present, but its Range only spans its own paragraph content not the newly added empty paragraph.
Insert the note text
Finally, insert the actual note text using the InsertBefore method.
This is where it's nice to use a variable for the note text. We just assign it to the Text option of the command. Any changes made to the variable above will automatically be included here when the text is inserted into the document. All such text insertion commands extend the range to include the newly added characters.
Since InsertBefore only has one required option, we can exclude the Text:= part and just give it the text.
Change the note paragraph style
Using a distinct note paragraph style will set the note apart from the novel text.
Get the first Paragraph
The rParagraph working range now spans two paragraphs, the note and the original paragraphs. We need the first note paragraph of the range, so we use the First property of the Paragraphs collection.
This reference is a Paragraph object not a Range.
Assign the note paragraph style
A Paragraph includes a Style property, so we assign the desired paragraph style to it.
We already referred to the first paragraph, so the style assignment will only apply to that paragraph.
The Style property conveniently allows us to just use the plain text style name. This property actually stores a generic data called a Variant, so we could alternatively assign a Style variable to it, or we could use one of many default built-in styles from a table of constants. The property will understand the difference and apply the desired style to the paragraph, but it's usually easier to just use the plain text name.
See the gotchas below about validating the style because it is extra important in this macro.
Range reference is not necessary (aside)
We've often referred to the Range of the First or Last Paragraph of the Paragraphs collection, but in this case, a Paragraph already has a Style property, so we don't need to access its Range.
This also works because a Range also has a Style property, but the extra reference is unnecessary in this case since we're working with a specific paragraph.
Gotchas
So, what could go wrong?
At a minimum, don't neglect the style validation because it will likely bite you or at least annoy you at some point down the writing or editing road.
Of course, there's always the question of whether an issue is worth the time and effort to fix, but we should at least consider them, so we're not unpleasantly surprised sometime in the future. This collection of gotchas may feel more like swatting at a swarm of mosquitos than squashing typical macro bugs, so skip to the final macro if you prefer, but it does include three of the corrections below.
Is the style valid in the document?
Invalid styles cause a macro to crash … as in quit running immediately and pop up an annoying error message. Even worse, VBA doesn't give us a reasonable native way to validate a tentative style before trying to apply it to a paragraph (we basically have to resort to clunky error handling).
Validate the paragraph style
A rough conditional statement to detect a valid style and take an appropriate action might look like:
Style validation function
The process of validating whether a style is accessible in the current document is beyond the scope of this article, so another article creates a function to accomplish the task.
We just provide (called "pass") the function a plain text name of a style to validate. The function returns a True or False (Boolean) value answering whether the style is accessible in the current document.
A True result means the style is either defined in the current document or was already defined in the global template (usually Normal.dotm) used to create the current document. If the style is invalid (a False result), we just skip the style assignment, so we can just omit that part of the If statement. If so, the new note text paragraph will have the same paragraph style as the original paragraph.
As a Boolean value, we can use the result directly in a conditional statement to make a decision. This function is handy for any macro that applies styles to content.
Style validation conditional statement
What do we do if the style is valid?
Insert the function validation check and the style assignment command into the above conditional statement.
An If statement containing only one command is clunky, but it's too long to fit on one line. This correction assumes only one paragraph for the note which is a working assumption for the entire macro.
Is it worth the trouble?
You will almost inevitably forget to add the style in a future novel document, and the macro will crash. I convinced myself so on several occasions, but I eventually became annoyed enough at the crashes to add the style validations. The extra step or two is definitely worth the time and effort.
Does the macro work at the end of a paragraph?
When creating a macro, we inevitably have some particular use case in mind, and we construct the formative steps around it. Variations may appear based on exceptional (in the sense of unexpected or out of the norm) locations in the document where the macro may be used. In this mold, the end of the paragraph presents a small issue for this macro.
Why?
If the insertion point is next to the paragraph mark, the Expand command will extend over the paragraph mark not the previous word.
It's not a fringe case we can sweep under the rug. In fact, it's probably an unexpected common use case since the author might type a word, not like it, but want to add a note to look it up the word later. The solution is even a little tricky because the macro mysteriously works correctly if even one space exists between the insertion point and the paragraph mark.
Ughhh.
Unnecessarily specific solutions
We could immediately set out to find the quickest (and often dirtiest) solution to determine whether the insertion point is at the end of the paragraph and make a decision in the macro to fix it. For example, we might do one of the following:
- Test the next character to see whether it is a paragraph mark.
- After the expansion, test whether the range contains only a paragraph mark character.
These checks work, but each is super specific to this problem, and they feel clunky. If that's all we can do, okay, but we can probably find a better solution that also automatically handles or at least sidesteps a few other unusual cases.
Look for whitespace
A more general issue occurs after the initial range expansion if the range spans only spaces or paragraph marks. We call this whitespace. It typically includes tab characters as well, but we've omitted them in this solution.
We previously created a function to detect only whitespace in a Range, so we can use it in this macro. The function looks like:
It returns a True or False value based on whether the range contains only whitespace or not. We want to check the contents of the rNote range.
What do we do?
Absent an initial selection, the previous word is the most likely text to include in the note. If the note range is only whitespace, we'll extend the beginning of the range backward in the document by one word. The relevant command is the MoveStart method.
Including this command in the conditional statement, we get:
This check will also catch and correct a few strange initial selections, and it further sets up to detect a beginning of paragraph issue below.
Trim paragraph marks also
Earlier in the regular macro steps, we trimmed any trailing spaces from the working note range. Now we know the range can also span a paragraph mark, so we should include a paragraph mark character with the trim statement. The revised command is:
The extra trim character can cause a small issue at the beginning of a paragraph, but that exception is handled below anyhow with the empty range check.
Does it work at the beginning of a paragraph?
If a word begins the paragraph with the insertion point at or inside it, the macro works as expected. However, if spaces begin a paragraph with the insertion point in those spaces, the expanded range will span all the spaces up to the first word but not the word.
Huh?
Apparently, that's just how Word defines a word in this case.
Why worry about it?
This is admittedly a fringe case we could probably ignore by itself, but it is related to an empty paragraph gotcha below which we need to consider. It also ties into a quirk with ranges that should also be mentioned for your VBA knowledge, so let's press on.
We corrected the end of paragraph issue above, so we need to do something similar for the beginning of the paragraph. In fact, the solution to the two gotchas overlap (which was part of the reason for insisting on the whitespace check above).
Detecting the beginning of the paragraph
How can we detect whether the note range starts at the same position as the original paragraph?
We can simply check whether the two Start positions are the same value.
Document positions are stored as character counts from the be of the document. This condition will be evaluated as a Boolean value in a conditional statement.
Since we modify the rParagraph range later in the macro, it is important that this check is used before that change.
What is the fix?
If the note text spans just space at the beginning of a paragraph, we can include the word immediately to the right in the document. We use the MoveEnd method with a word unit:
Better paragraph position fix
This correction is related to the one above for the end of the paragraph. With that in mind, we combine them into one larger, but sadly messy, conditional statement. Combine the condition and the correction into another If-Then-Else statement, so it spans the best (most likely to be relevant) paragraph text in either case.
This is not bulletproof, but it catches most gotcha issues. However, nested If statements are unsightly, so the final macro below includes the simpler version which handles the most common case at the end of the paragraph.
Insertion point position quirk
I won't classify this issue as a gotcha, more of a quirk.
If the insertion point or the Start position of the Selection is positioned at the beginning of the original paragraph, the inserted note will force the Selection Start backward with it.

Ughhh.
It's not a big deal in that it only takes a single Down arrow key tap to sidestep the quirky behavior, but I prefer my macros to handle such issues automatically within reason.
Why should we care?
One of the points of this macro was to leave the initial selection unchanged, so the writer can just keep working after the note is added. Changing the Selection is not leaving it unchanged. More practically, digging into this will help us better understand how ranges work in Word VBA.
Why does it happen?
VBA adjusts existing Range variables or the Selection when inserting text into the document as it should [dramatic pause] … but there's a catch.
Suppose we insert some text into the document with a range variable. We would expect VBA to adjust any other working range variables that overlap that region (via changing their Start or End positions) to also span the new text.
Okay … that makes sense.
The quirky behavior arises because the range adjustments also happen when text is inserted at the Start position of other range variables. That is, the Start position of a range is considered to be inside the range (but not the End position).
What does that mean for this macro?
If the Selection begins exactly at the start of a paragraph, then our added note pushes the Start position of the Selection backward to include the newly added note paragraph. According to the above criterion, new content was added at the exact Start position of the Selection, so its extent was adjusted to include the content.
Problem with identifying the quirk
This change is a little tricky to catch in a general macro because the macro needs to work for any case.
What's so tricky?
The Selection may have changed, so we can't use its current extent for any test. It's what we need to correct. Moreover, any range we define based on the initial Selection (perhaps as an early step in the macro) with the intention of it being a fixed reference will have the same starting position. Our purported reference range would also be automatically adjusted by VBA when the note text is inserted.
Ughhh. Ughhh.
No, this isn't time to start considering a career change or regressing to quill and parchment. We just need to figure out how to squash an annoying bug.
How do we catch the quirk?
We need a test for whether the Selection changed as a result of inserting the note. We can compare its Start position to the adjusted rParagraph Start position to see if they are the same.
If the Selection Start position has moved with the new note paragraph, we want to move it back to the initial position one paragraph below (this macro is not for notes that span multiple paragraphs).
Fixing the quirk conditional statement
Putting it into a conditional statement, we have:
We're just moving the Start of the Selection by one paragraph because the End position was not affected when VBA inserted the note paragraph. It's a little clunky, but it works for solving a trivial but tricky issue. I don't like that this correction is specific to this particular macro … [drums fingers and squints at the screen for a while].
I tried to find a fancier and perhaps more general solution, but most of them didn't fit ever occasion. The most logically consistent solution was to check whether the Start positions are the same. This is a specific solution that solves a specific problem. Fine. VBA wins a round. Big deal.
Is the final range empty?
Running the macro on an empty paragraph might be logically out of bounds for a contextual note macro, but the macro should handle it anyhow. Moreover, given the trim steps above, an empty note range could occur in a few other special cases, particularly at the beginning or end of a macro. The following conditional statement catches these situations and just stores a general note text if so. The check is not super important, but it could save some mild confusion if an incomplete note were inserted into the document.
Rough empty paragraph conditional statement
Depending on whether the range is empty, we assign the generic note or the contextual note to a string variable.
Empty range condition (and function)
An explicit empty range condition just checks whether the Start end End positions are the same value.
It's nice when the macro reads clearly, so we can take advantage of a simple function called IsRangeEmpty from a previous article.
This function returns a True or False answer to the question posed by its name.
Adjusting the note text based on an empty range
In VBA, the revised conditional statement becomes:
With this correction, a valid note text is assigned either way, but the generic note avoids any confusion if a problem occurs. The writer can decide what to do after that.
At this point in the macro, we're not trying to isolate which problem occurs. It's more of a failsafe validation to make sure the note range contains something before we construct the contextual note.
Does the selection span more than one paragraph?
If the selection spans a paragraph break, the note will contain that break also. This is unsightly, but it's more of an annoyance than a logical error, so we will ignore—
Oh … you don't want to ignore it?
Yeah, I suppose we make some assumptions based on a short note, so we could at least consider the issue.
Detect more than one paragraph
The condition to detect more than one paragraph is:
We refer to the Paragraphs collection, but this time, we use its Count property which tells us how many paragraphs are in the collection.
More than one paragraph note correction
If the paragraph count is larger than one, we need to restrict the note text to a single paragraph of text.
If more than one paragraph is found by checking the Count property of the Paragraphs collection, we just set the range End position to the first paragraph's End position. The extra minus 1 also removes the paragraph mark character from the end of the range. This trims the range to be just contained within the first selected paragraph and forces a single paragraph note.
Is this worth it?
I don't like that this looks more like programming than most Word VBA editing macro steps, but we're in a little bit deeper gotcha territory for members. I would probably add it to my own macro, but it's a preference. It makes the macro messier and longer than it needs to be for most other use cases.
You may even prefer to let the note span a paragraph, but other steps in the macro would need to be adjusted. For example, the style assignment would need to account for more than just the first note paragraph.
This check is excluded from the final macro below.
Gotcha lessons?
A lot of talky talky happened above. While it's not ideal to add even more words, we might take a moment to contemplate some implications. What have we learned besides some cool VBA techniques?
Some gotchas (or quirks) are harder to fix than others
A Range extends to include any content inserted inside it, but this includes any content inserted at its Start position. This not as intuitive, but it's an important detail to remember when working with multiple ranges.
Testing is important. Experience warned me about some of the above gotchas in this macro, but I found several others by trying the macro out with several unusual initial positions or selections.
Creating bulletproof macros can be hard
Making a macro bulletproof can take some work and make it look more like a computer program than a macro.
Is it worth it?
In my mind, yes, but I've been programming for a long time. I also want my macros to catch most gotchas automatically and work as intuitively as possible, so I'm willing to put up with the mess and long macros.
Final contextual novel note macro
Now put the commands together to finish the macro. The macro includes three of the more important gotcha fixes mentioned above.
This macro helps me quickly include research reminders for later editing while allowing me to continue writing in the moment. I have several variants assigned to different keyboard shortcuts.
After the note is corrected in the text, usually on a later editing cycle, a simple Control+Shift+Delete (or Command+Shift+Delete on Mac) swiftly deletes the note paragraph using another super handy macro.
Functions used
This macro uses three previous functions to help with some of the error checks and validations.
- IsRangeWhitespace checks whether a range is whitespace (typically spaces, paragraph marks, or tabs).
- IsRangeEmpty in the same article checks whether the range spans no document content even whitespace.
- IsStyleValid checks whether a style is valid in the current document (important)
The first article catches two common use cases which could cause some small problems.
On the second article, it may seem inefficient to validate the style every time the macro runs, but it's easy to forget to create every style in a new manuscript. For example, we might change the style name but not transfer it to the newer document. The style error becomes annoying after only a few times. The handful of milliseconds VBA spends validating the style each time the macro is used will almost never be noticed.
I try not to overuse functions in articles even for members, but one point of creating them is to make other macros easier to write. The functions also make our macros read better. We just have a take the extra step to include them along with the main macro that performs the desired task.
Improvements
We can still improve several things the above macro.
Screen updates
While we are using a Range variable to insert the note text, the changes are still visible on the screen as they are made, so this macro is a good candidate to disable screen updates while running. On the other hand, the simple changes are probably fast enough that we wouldn't notice the difference.
Undo record
The multiple small changes made by the macro would need to be undone one-by-one, so this macro is also a good candidate for creating an undo record. They make a macro feel more "professional" since its acts more intuitively like a single action in the undo stack, but it is excluded even in this member article because they can cause significant problems with the undo action chain if not properly implemented.
Function version
If you like such novel notes, you'll probably add other variations with different text and/or note paragraph styles. It's cumbersome to copy the entire macros over. Repeating all the steps in each variation with only tiny changes between them clutters our macro file and makes any later changes tedious (we need to change the same thing in each macro). These note macros are begging for a few functions to encapsulate the common steps, but functions make the macros look significantly more technical.