Selecting nearby dialog or parenthetical text happens enough that writers can benefit from a faster way, so we create a macro to accomplish the task. This version includes a validation check to ensure only dialog text selected.
Thanks for your interest
This content is part of a paid plan.
Select dialog or parenthetical text
Selecting specific chunks of a text is a relatively common task when writing and editing. While we can't create macros for every text variation, dialog or parenthetical text make good candidates for a set of targeted selection macros.

Selecting nearby dialog is an obvious task for fiction authors, but don't neglect the parentheses versions since they're useful in other work or notes documents, and they're trivial extensions.
The best implementation includes one macro to search forward in the document and another to search backward (see below for why). This set of macros extends the previous macros with a validation check to ensure dialog text is found before selecting it. This avoids issues with spurious selections when dialog doesn't exist in the search direction.
Create the empty macro
Open the VBA editor and create the following empty macro. If you prefer, a previous post covers creating it using the application interface.
The single quote tells VBA the rest of the text on that line is a comment meant for human readers. We start our macro steps on the empty line.
We'll need a second macro to search forward in the document. If you search for parenthetical text, create another two more like them. We'll work with the backward dialog version to be specific, but the changes for the other variations are simple.
Double quotes in VBA
To search for dialog, we need to specify the various double quotes in VBA. One issue is plain text strings are defined with straight double quotes like "some text." Our keyboards type straight quotes but not curly quotes which is why Word automatically corrects them to left or right quotes (Word calls them "smart quotes"). That's convenient when typing, but despite their visual similarity, they are distinct characters, so our macros need to distinguish between them.
The assignments below are clumsy since they never change, but we would still need to define them in every macro where they are used. A better approach is to define them as constant values for all macros. Either way, we can refer to the respective name when we need the character.
Represent double quote characters in VBA
VBA includes some special characters in a miscellaneous constants table, but it also includes a function ChrW(…) that allows us to specify other special characters like left and right quotes. Cross reference the necessary characters in a standard Unicode character table. This extensive table includes most modern written language symbols in the world. Use the assigned number with the character function ChrW(…). The respective left and right double quote characters are:
- Left double quote “ → ChrW(8220)
- Right double quote ” → ChrW(8221)
The result is a text character for Word. In VBA, we can assign the respective character to a variable for later use.
In macros dealing with dialog, we usually need to consider all three double quotes to ensure the macro doesn't miss obvious variations in a document. In these macros, left and right quotes indicate the respective dialog boundaries, so we'll ignore straight double quotes.
How will the macro work?
Before we create a macro, we need to decide what task it will accomplish. What will it search for in the document? What text will it select?
The questions sound obvious, but the specific steps matter if we want a specific result. We want to select all text within a pair of left and right double quotes, but this macro has two main options?
- Assume the writer runs the macro when the insertion point (i.e., the blinking I-bar) is between the double quotes.
- The writer can run the macro anywhere, and it finds nearby dialog before or after the current location in the document.
The first case is the obvious assumption, but the latter is more useful in practice since not having to manually click into or move between the quotes is convenient.
A macro is also more practical if we don’t need to remember details about how to use it correctly. It just works. The trade off is we need one version to search each direction in the document, but both versions still work if the insertion point begins inside the dialog text.
Macro outline
How can we accomplish our task regardless of the initial position in the document relative to the dialog text? We'll use a Range variable, but ranges work similar to the manipulating the Selection.
- Move backward in the document to a left double quote
- Extend the range over the left double quote character
- Extend the range forward to the matching right double quote
- Extend the range over the right double quote character
- Validate whether the identified document range is actually dialog text and exit if not
- Extend the range over any trailing spaces like Word does with its automatic selections
- Select the final range
The order of steps 1 and 3 is a key point in this macro. The steps do not require the insertion point to begin inside the dialog text. They work correctly as long as the insertion point begins somewhere to the right of the dialog. The range extensions over the quote characters in steps 2 and 4 are not immediately obvious. We want to include the quotes in the selection, but we must do so explicitly.
Using a working range variable rather than the Selection allows us to work invisibly in the background rather than having the Selection flicker on the page as the macro determines the dialog boundaries. A Range variable further allows an easy validation step before we reveal the result.
VBA include several Range commands (called "methods") that fit this sequence of steps perfectly. As we work through the steps below, we’ll assume we're searching backward in the document and tweak the sibling macro to search forward. Then we'll make the nearly trivial changes for macros that search for parenthetical text instead.
An older version of this macro, implements the validation in two stages and exits the macro as soon as it finds a discrepancy, but the steps used here are easier to follow and accomplish the same task. They just take an itsy bit more time, as in a handful of milliseconds, which we would almost never notice.
Assume smart double quotes
I try to be general, so macros act intuitively in most reasonable circumstances. However, in this macro, a straight double quote does not clearly indicate a specific side of the dialog text like the appropriately named left and right double quotes do.
It’s possible to work out the logic to detect the correct side of the dialog text when using straight double quotes, but the necessary steps quickly get messy. Moreover, we gain very little in functionality since Word usually converts the double quotes to smart quotes anyhow while we're typing, so allowing straight double quotes is not worth the time and effort for the few occasions we'll need them.
With this in mind, we'll assume smart quotes are used in the remainder of the article. This significantly reduces complications with interpreting the beginning and ending of dialog text. An exception might be if we're copying plain text into a document from another source, but we'll consider that beyond the scope of the current macro.
Find the beginning of previous dialog
We want to select all text between a set of double quotes somewhere before the current insertion point position. We outlined the steps above including declaring the double quote characters. Of course, the current macro improves upon its little brother, but many of the steps use similar methods just for a Range variable.
Declare the working range
When working on serious editing macros, I prefer to declare any important variables. I call this a "working range" as a practical term since we work with it to identify our document range of interest.
Dim is the keyword to declare a variable, and "As Range" tells VBA we want it to be a Range variable. The basic naming rules in VBA are: use only alphanumeric or underscore _ characters, and do not use any VBA keywords such as Const, Dim, or Range. The descriptive name rDialog includes an "r" as a personal reminder of the type of data it stores, but VBA only cares whether its own rules are followed.
Assign the working range
Since the macro is searching for nearby dialog based on the initial position in the document, we will assign it the starting position as a range.
We Set a Range variable because it is a VBA object that contains more data than just a plain value. We needed to reference the Range of the Selection because our variable stores a document Range, but the Selection is more than that. If any document text is selected at the beginning of the macro, this range will initially span the same text.
Move to a left double quote
We move the range to a specific character using the MoveUntil method.
If the range spans any content, the method automatically collapses it and moves the range until it finds a certain character (or any of several characters). If it finds a character, the range is positioned just to the right (when moving backward) or left (when moving forward) of the character.
The character set is specified as plain text, usually in double quotes like "abc", by assigning it to an option named Cset. At this point in the macro, we're only looking for a left double quote character which we named LeftDQ earlier.
The option assignment requires a colon equals := symbol. We're searching backward in the document, so we also need the Count option.
It may seem conceptually awkward to use the Count option to search backward, but this option tells the various "Until" and "While" move commands how many characters to check before stopping. It stops at the first match. If no matches were found within the specified Count, the range does not move. Positive values indicate forward searches and negative values indicate backward searches. The Word constant wdBackward is a large negative value from a Word constants table which means the move command would search backward in the document by as many characters as necessary to find a match. The two options must be separated by a comma.
No text is spanned yet
Once the left quote is located by the command, the working range is moved just to the right of the matched character. At this point in the macro, the Start and End positions of the range are at the same position in the document, so no content is spanned. We'll handle the case of a missing left double quote later.
Select the dialog text
Now, we extend the working range across the dialog text, but it takes a few steps to include everything.
Extend the range over the left double quote
At this point in the macro, the Start position of the rDialog range is positioned immediately after the left double quote. We probably want to include both quotes in the final selection, so we use the MoveStart method to extend the range backward over the quote.
As its name implies, MoveStart moves the Start position of the range by the given Unit type. We omit the Unit option here since the default is to move by a character.
Unfortunately, the default is to move forward, so we need to use the Count option to specify a backward move.
Unlike MoveUntil command above, the Count option with MoveStart moves it by a specific number of units. We specify -1 to tell the command to move backward (the negative) by 1 Unit which includes the quote character in the range.
This step is also necessary since we will use the left double quote to validate whether we actually found some dialog text.
We finally have something in the range!
Huzzah!
The End position of the range was not changed by this command, so the Start and End have different positions in the document. The range spans a whole character in the document now. Yay for progress!
Find the right double quote
Assuming we found a left double quote, we anticipate our working range is at the beginning of a pair of the left and right double quotes, so we extend the range over the rest of the dialog text. We will not change the start of the range for the rest of the macro.
Extend the range over the dialog text
More specifically, we move the End position of the working range to the next right double quote. As if made to order, the MoveEndUntil method moves the End position to a specific character (or any of a set of characters).
Like the MoveUntil method above, this command requires a character set assigned to a Cset option, but it only moves the End of the range. We assigned the right double quote to a variable named RightDQ earlier, so we assign this character to Cset.
The default direction is forward, so we can omit the Count option. The Start position is unchanged, so the command extends the range forward in the document to span all the dialog text.
Include the right double quote
At this point in the macro, the End position is just before the right double quote. We want to include it as part of the final selection, so we use the MoveEnd method.
We don’t need any options with this command because the default Unit is to move by characters, and the default Count is to move by one Unit forward.
This step is important because we're using the two double quotes for our dialog text validation step below.
Include any trailing spaces
Including any spaces on the right side of the selection mimics how Word usually works with automatic selections. For example, when we select only part of a word, Word spans the whole word for us (depending on the selection settings) including a space after the word. Unless we have a good reason to create our macros with a different behavior, it's a good practice to keep them consistent with how Word works.
We extend the selection over any trailing spaces using the MoveEndWhile method.
Similar to the MoveEndUntil command above, MoveEndWhile needs a character set to match in the document. We again assign the desired characters as a plain text string to a Cset command option.
Unlike MoveEndUntil, the MoveEndWhile command moves the End position of the Selection while it keeps finding any of the characters in the set immediately at the End position. At this point in the macro, we’re just extending the selection over any trailing spaces, so we assign a single space " " to the character set option.
The default is to extend the End of the selection forward in the document, so we omit the Count option. The Start position of the selection is unchanged by this command.
Select the final range
We're working with a range variable, so all the movement and extensions above only affect that variable. We haven't made any change to the document, so as far as the writer is concerned, nothing has happened yet. We need to select the resulting range using the obviously named Select method.
Of course, we should only select the final range if we actually found some dialog text.
Validate the dialog text
Using a working range variable makes it easier to validate the found dialog text before revealing it on screen. The easiest way to validate whether we've found any dialog text is to check whether the left and right double quotes are on the respective ends of the range.
Get the first character of the range
The left double quote would literally be the first character spanned by the range. We begin with the Characters collection of the range.
The first character is identified using the First property of the collection.
The first character is just a short document range, but we need the actual text not where it is located in the document. We get that using the Text property of the range.
For extra clarity, this is not giving us the text of the rDialog working range, just the first character.
Get the last character of the range
Getting the last character of the range is very similar except we use the Last property of the Characters collection.
If you like digging, an older implementation of the same macro task uses character counts of the above move methods for the validations steps, but the approach used in this macro is cleaner even it a teensy weensy, itty bit slower (we would never notice the difference in practice).
Store the characters
While I don't like taking up two or three extra lines to store the characters (we only use them once each), the conditional statement below is messy without these temporary assignments. I prefer to start with the variable declarations, but they're not required in regular Word VBA.
On the first line, we can include multiple variable declarations as long as we separate them with commas. Both variables are strings, but we're only storing a single character in each one. Now, assign the characters to their respective variable.
Dialog validation condition
We expect the first character to be a left double quote, so we can directly compare it the the previous LeftDQ character.
The corresponding condition for the last character of the range checks whether it is a right double quote which we called RightDQ earlier.
While these statements resemble assignments, VBA interprets them as a Boolean (True or False) values in the conditional statement below.
Compound condition for both double quotes
We only want to select the range if we find the both double quotes. This means both of the above conditions must be True if we have found some dialog text. This corresponds to the And operator.
And is a "Boolean operator" in the sense that + is an addition operator. A plus sign takes two numbers and gives a numerical result. And takes two Boolean values and gives a Boolean result. Specifically, And requires both conditions to be True before it gives a True result. Otherwise, the result is False. See our introduction to conditional statements in VBA for more explanation.
Dialog validation conditional statement
Insert the compound condition into an If statement:
Since we're using the double quotes to validate the dialog text, this statement should be placed before extending the range over any trailing spaces. More specifically, we include the last two commands inside the conditional statement, so they are only run if we've found a valid dialog text range.
If the dialog text does not start and end with the respective quotes, the extra steps are not run, and the macro just ends with nothing else happening. This saves our macro from accidentally selecting strange ranges of text when one of the double quote characters does not exist in the document.
Modifications for searching forward
The changes to search forward in the document are relatively obvious, but let's work through them at a quicker pace for completeness. Essentially, we're roughly reversing the core steps of the above macro.
Initial forward move to a right double quote
We begin by moving forward with the MoveUntil method again, but the options are different.
We're searching for the right side of the dialog, so the command moves until its find a right double quote character which we called RightDQ. The default direction is forward by any number of characters until we find a match, so we omit the Count option.
Select the right double quote
We move the End position of the Selection forward by one character over the right double quote using the MoveEnd method.
No options are necessary since the default behavior is to move the End position one character forward which is what we need.
Extend range backward to a left double quote
We extend the Start position of the working range backward until it finds a left double quote which we called LeftDQ earlier. The command is the MoveStartUntil method.
The Count option for backward is required because the default is to move forward.
Gotchas
What could go wrong? We're only selecting text, so we don't have to think like Mr. or Mrs. Murphy, but we should at least be careful.
Does an initial selection matter?
Does it matter if the user runs the macro with a selection already made in the document?
One of the first steps sets the working range equal to the initial selection, but it doesn’t matter in this macro because the next step moves the range to a left double quote. The MoveUntil method automatically collapses the range, but even something else goes wrong, the range validation should exclude any strange behavior.
Mixed smart or straight double quotes
Occasionally, Word will not properly apply the left or right smart quotes which may leave one or the other as a straight double quote as typed by the keyboard. Sometimes this is our fault because we unintentionally tapped undo immediately after the AutoCorrect action. Since these macros use the smart quotes to detect the extent of the dialog, they will likely select the wrong text. It's an infrequent issue that takes a lot of effort to catch, so it’s not worth the effort to rework the macro to account for it.
An exception would be if you regularly work with documents including text copied from plain text files, but those cases are outside the scope of this article.
Do both double quotes exist?
We assumed the pair of double quotes existed in the document in the desired search direction. These macro versions added the dialog text validation for this reason, so we should be safe from any spurious selections.
Using a Range variable versus the Selection side note
Using the range variable allowed us to almost easily validate the range of dialog text before selecting it in the document. This issue is an example of why manipulating the Selection directly is not ideal in more complex macros. If a problem is encountered later in the macro, previous changes have already been made to the Selection, so we're stuck somewhere in the middle of the process. The Range variable allows us to present the result only if it was what we expected.
Does it work for nested dialog?
Final macros
Putting the above steps together, the final macros are as follows. Neither version requires the user to run the macro with the insertion point between the pair of double quotes.
Select double quotes backward macro
To select all text between the previous set of double quotes in the document, the macro is:
The extra comments at the beginning of the macro are not required, but this macro has several points that should to be mentioned for clarity.
In Word for Windows, I assign this to Alt+Shift+Single quote.
Word for Mac (really MacOS, in general) has problems interpreting some shortcuts when modifier keys are combined with the punctuation marks. I prefer to assign this macro to something that makes sense like Command+Shift+Single quote or maybe as a second choice Command+Control+Shift+Single quote. Unfortunately, Word for Mac will not recognize these key combinations. I settled for Option+Control+Single quote which is a different shortcut pattern than most of my other selection shortcuts since it doesn’t include the Shift key.
Select double quotes forward macro
The version to search forward in the document is:
I assign this to Control+Shift+Single quote in Windows and Command+Control+Single quote in Word for Mac.
Why are there two macros?
We designed the macro to find dialog text even if we do not start with the insertion point between the double quotes. This behavior is more useful in practice than assuming we begin inside some dialog, but it means we need two slightly different versions. The little bit of extra work is worth the effort.
Adapt the macros for parentheses
Parentheses appear often enough in notes and work documents that it's nice to tweak the above macros to work with parenthetical text.

The conversion is nearly trivial. The key changes are to swap out the left double quote for an open parenthesis and a right double quote for a close parenthesis. In the macro move commands and the validation conditions, change the two quote characters to the corresponding plain text parenthesis in each macro as follows:
- LeftDQ → "("
- RightDQ → ")"
Copy the macros and give them unique macro names. Make the two character changes in each macro. Delete the double quote variable declarations since they are not needed. Also edit the comments to refer to parentheses instead.
Final selection parentheses macros
Making the above changes, the final versions to select parenthetical text are included below for completeness.
Select parenthetical text backward macro
To select all text between the previous set of parentheses in the document, use:
I assigned my version to a Command+Shift+9 shortcut in Word for Mac and Control+Shift+9 in Windows.
Select parenthetical text forward macro
To select all text between the next set of parentheses in the document, use:
I assigned my version to the shortcuts Command+Shift+0 in Word for Mac and Control+Shift+0 in Windows.
Improvements
What could we do better?
Select the full sentence?
VBA allows us to tweak our macros to match our own workflow. If you prefer to select the full sentence of dialog including any dialog tags, it's easy to add. A separate macro already selects a whole sentence, but this improvement would still be useful if the dialog contains multiple sentences.
Unfortunately, it's outside the scope—[… can't resiiisst]:
Not a lot of explanation for brevity, but if you like this variation, replace the trailing spaces extension with this command just before selecting the result. It causes no additional problems if the dialog already spans a full sentence since the expansion simply does nothing in that case. Of course, change the range variable rDialog to rParentheses in the parenthetical versions.
Use an undo record?
Should we include an undo record?
When a macro contains multiple smaller changes, it's a good candidate to use an undo record. In these macros, most of the changes move and extend the range variable, but those are invisible to the writer. The only visible change in the document was the final selection step. Meaning,
So, nope. No undo record is needed in any of these macros.
Use functions?
Given the similarity in the macros, they seem to asking (not quite begging) to be reimplemented as functions. We could create two worker macros using generic left and right characters and simply call those functions. While it is annoying and clunky to have all the repeated steps, this is a case where these two sets of macros are the only two practical applications. What else would we do?
- We could add square brackets, but that will be rarely used compared to parentheses.
- Commas are a potential practical extension, but they would need to be implemented differently because they could cause logical problems. No direction is implied with commas in general text. Nearby commas could even be in different sentences, so we would need some extra sentence detection logic … so it needs a separate macro.
Given the complexity bump, my suggestion is save functions for macros with more practical applications (such as the novel note macros). At that point, the improved organizational aspect is more useful even with the increased complexity functions bring.