Heading

This is some text inside of a div block.
This is some text inside of a div block.
This is some text inside of a div block.
min read

Select Parentheses or Dialog

Word • Macros • Editing
Peter Ronhovde
18
min read

Automatically selecting all text in nearby parentheses happens enough that I wanted a macro to quickly do it for me.

I use this macro more for novel notes and work documents more than in my fiction manuscripts. It’s quite handy when I need it, and it easily extends to selecting dialog as well.

Thanks for your interest

This content is part of a paid plan.

Create the empty macro

A previous post covers creating an empty macro like the one shown below. When you’re done, you’ll have something like:

Sub SelectParenthesesBackward()
  ' Select all text between the next pair of open and close
  ' parentheses including the parentheses

End Sub

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.

Example macro selecting parenthetical text

We will also create a second macro to search for parentheses forward in the document.

This version again uses the Selection object, but see the member version where we write it more robustly using Ranges with some additional checks to prevent any spurious selections when parentheses do not exist in the document.

Assumptions, assumptions

Before we create the macro, we need to understand exactly what we are looking for in the document.

Sounds obvious, but do we assume the user runs the macro when the insertion point (i.e., the blinking I-bar waiting for new text to be typed) is already between the parentheses? Or do we want our macro to find any nearby parentheses?

The differences are slight, but the specific steps matter.

If we assume the former, it simplifies the macro steps since you don’t have to worry about which direction to move the insertion point in the document at the start of the macro.

Personally, I like the latter approach since it can find the parentheses anywhere in the document. Also a macro is more practical when the user doesn’t have to remember specifics about how it works to use it.

With that goal in mind, I created one version to search backward and another to search forward in the document. Both versions work the same if the insertion point happens to already be between the open and close parentheses.

As we develop the macro below, we’ll work on the search left version and tweak it to search right when we’re done by changing the order of the search and move commands.

Find open parenthesis

We previously covered a macro allowing us to quickly navigate to various punctuation marks in a document. This macro leans on some of the commands covered in that article but achieves a different effect.

Specifically, we first want to find a set of parentheses before the current insertion point, so we start by searching backward in the document for a left parenthesis “(”.

This step is quite general since the insertion point doesn’t need to be between open and close parentheses to do the search.

Move to open parenthesis

The basic command to move the Selection’s position to a specific character uses the MoveUntil command

  Selection.MoveUntil Cset:="(", Count:=wdBackward

The command does just as the name implies. It moves the insertion point until it finds any one of the characters given in the Cset option. Here we are only looking for a left parenthesis.

Most regular Cset characters are specified inside double quotes as shown, but some special characters have to be added separately using a few standard Word character constants or a character function for many other special characters.

The Count:=wdBackward option instructs the command to move backward in the document just as the name of the constant implies.

Some details

It’s useful to understand some details about the Selection and the document before moving forward.

This will also give us some practice understanding macros and how we can bridge the gap between specific macro steps and achieving the overall effect we wish in our document.

At an open parenthesis

When the macro is run, we have assumed the open parenthesis exists somewhere before the starting position in the document.

Once the open parenthesis is located, the insertion point is moved just to the right of the newly located open parenthesis. Specifically, the Start and End positions of the Selection are both set to that same position in the document.

No selection yet

Since the Start and End positions are the same, there is no selection in the document yet.

Assume a close parenthesis to the right

We will also assume a close parenthesis exists to the right of our current position in the document.

Ignore potential problems

We’re not going to worry about problems with whether or not the open or close parentheses actually exist in the proper order in this version of the macro.

Any gotchas in this macro are minor since nothing changes in the document except what text is selected. A spurious selection might be made, but presumably, the user would then just ignore the strange selection.

See member version

If you’re like me, you insist the gotchas are handled well in a macro, so see the member version to handle them more robustly based on the document conditions or lack thereof.

In that version, nothing happens if there are no parentheses to find or one of the parentheses is missing.

Include the open parenthesis

Now we start creating the desired selection of the parenthetical text.

At this point in the macro, the Start position of the Selection is just after the open parenthesis.

Most of the time, we’ll probably want to include the open parenthesis as part of the selection.

  Selection.MoveStart Count:=-1

MoveStart tells Word to move the Start position of the Selection by the given Unit type. We omit the Unit here since the default is to move by character (i.e., the command assumes a Unit:=wdCharacter option if it isn’t given).

The Count:=-1 option tells VBA to move backward (the negative) by 1 Unit to include the open parenthesis in the selection.

The End position of the selection is not changed with this command.

Since Start and End now have different positions in the document, we now have a real, albeit incomplete, selection. Yay!

Include any spaces

If you prefer to include any spaces on the left side of the selection (not my preference), you could also add

  Selection.MoveStartWhile Cset:=" ", Count:=wdBackward

This command acts similar to MoveStart except it keeps moving the Start position while it keeps finding any characters given in the Cset option which is just a space here.

Find close parenthesis

Now that we are somewhat confident our incomplete selection is currently in between a pair of the open and close parentheses, we can proceed by moving the End position of the Selection to the close parenthesis.

Since we have already found and included the open parenthesis, we don’t want to disturb the Start of the Selection for the rest of the macro.

Move the End position of the selection

The MoveEndUntil command moves the Selection’s End position to a specific character or any of a set of characters given by a Cset option

  Selection.MoveEndUntil Cset:=")"

The Start position is unchanged by this command, so we are extending the End of the Selection forward in the document.

Include the close parenthesis

At this point in the macro, the End position of the Selection is just before the close parenthesis.

Most of the time, we’ll want to include the close parenthesis as part of the selection

  Selection.MoveEnd

We don’t need any options here because the default Unit is to move by characters in the document, and the default Count option is to move by one Unit forward.

Include any spaces

Including any spaces on the right side of the selection mimics how Word usually works, so we add

  Selection.MoveEndWhile Cset:=")"

MoveEndWhile keeps adding characters to the Selection as long as it keeps finding any given in the Cset option. We’re just adding spaces.

The default is to extend the End of the selection forward in the document which is what we need here.

The Start position of the selection is unchanged by this command.

Final macros

Putting all of this together, the final versions of the macros are a little longer than some we have done, and there is one for each direction.

Neither of these macros require the user to run the macro with the insertion point between the parentheses which is a little bonus.

Select parentheses backward macro

To select all text between the previous set of parentheses backward in the document, use

Sub SelectParenthesesBackward()
  ' Select all text between the previous pair of open and close
  ' parentheses including the parentheses.
  ' Insertion point does not have to start between the parentheses.
  ' No checks are performed for whether the parentheses exist or not.

  ' Move backward to a previous open parenthesis
  Selection.MoveUntil Cset:="(", Count:=wdBackward

  ' Include the parenthesis and any spaces (optional) before it
  Selection.MoveStart Count:=-1
  'Selection.MoveStartWhile Cset:=" ", Count:=wdBackward

  ' Extend the end of the selection forward to the next close parenthesis
  Selection.MoveEndUntil Cset:=")"

  ' Include the parenthesis and any spaces on the end
  Selection.MoveEnd
  Selection.MoveEndWhile Cset:=" "
End Sub

If you want to include spaces on the left side of the Selection, then remove the single quote in your version of the macro on the line

  'Selection.MoveStartWhile Cset:=" ", Count:=wdBackward

Then delete or comment out the other line you no longer need.

In general, this is a nice way to remove a line from your macro without getting rid of it since VBA will see it as just a comment line.

I assigned my version to the keyboard shortcut Command+Shift+9 in Word for Mac and Control+Shift+9 in Windows.

Select parentheses forward macro

To select all text between the next set of parentheses forward in the document, we have to switch the directions of the searches and for which parentheses we are searching.

After making these changes (not on screen), the result is

Sub SelectParenthesesForward()
  ' Select all text between the next pair of open and close
  ' parentheses including the parentheses.
  ' Insertion point does not have to start between the parentheses.
  ' No checks are performed for whether the parentheses exist or not.

  ' Move forward to the next close parenthesis
  Selection.MoveUntil Cset:=")"

  ' Include the parenthesis and any spaces after it
  Selection.MoveEnd
  Selection.MoveEndWhile Cset:=" "

  ' Extend the start of the selection to the previous open parenthesis
  Selection.MoveStartUntil Cset:="(", Count:=wdBackward

  ' Include the parenthesis and any spaces (optional) at the start
  Selection.MoveStart Count:=-1
  'Selection.MoveStartWhile Cset:=" ", Count:=wdBackward
End Sub

I assigned my version to keyboard shortcuts Command+Shift+0 in Word for Mac and Control+Shift+0 in Windows.

If you’re interested in a more robust version that checks for whether the parentheses exist before committing to any changes, look at the member version.

Gotchas

Does an initial selection matter?

Does it matter if the user runs the macro with a starting selection instead of an insertion point?

The starting selection mostly doesn’t matter with this macro because we start by moving the insertion point to a parenthesis. Most move commands automatically collapse the Selection when the insertion point is moved, but some move commands do have an Extend option.

This could matter in some rare cases since the move command works from the “active” side of the selection, which is usually the Start of the selection, but the distinction will rarely affect everyday usage. The only way it would matter is if there is a starting selection, and the selection spanned a pair of parentheses, and the user expected it to select the current parenthetical text. That’s a lot of “ands” to worry about before it makes a difference.

Do the parentheses exist?

We ignored whether or not the open and close parentheses exist in the document in either direction. If they are missing, the macro will usually just create a spurious selection which the user would then ignore, but it would be nice to have the macro recognize when parentheses are missing and just do nothing.

If you’re interested in correcting this detail, see the member version.

Adapting for double quotes

Double quotes appear thousands of times in a typical novel, so it would be nice to tweak this macro to allow us to quickly select dialog text.

The obvious conversion is to swap out an open parenthesis to a left double quote and a close parenthesis for a right double quote, but there are a few details to handle along the way.

Chr() function for double quotes

The changes are relatively minor assuming we use left and right double quotes. Unfortunately, how we specify them is system dependent.

We use the Chr() function since the Cset option in our move command usually takes its search characters in double quotes. Unfortunately, we’re searching for double quotes, so we need an alternative way to specific them. The character function essentially maps a number in a table to the special character for us.

For a left double quote, Macs use Chr(210), and Windows systems use Chr(147). Similarly, a right double quote on a Mac is Chr(211), and Windows systems use Chr(148).

Assume smart double quotes are used

For simplicity, we will assume smart quotes are turned on (in AutoCorrect options), so your document uses left and right double quotes. This significantly reduces complications with interpreting the beginning and end of dialog compared to when straight double quotes are used.

Ignore straight double quotes

The Chr(34) is a straight double quote which is the same on both systems, but we won’t use it for this macro.

How would the macro “know” that a straight double quote is the beginning or the end of a bit of dialog. It’s possible, but there are more cases to properly handle general dialog than appears at first glance.

Command changes

On a Mac, revising the respective revised macro commands, the initial move command looks like

  Selection.MoveUntil Cset:=Chr(210), Count:=wdBackward

and the second command extending the End of the selection is

  Selection.MoveEndUntil Cset:=Chr(211)

On windows, the initial move command is

  Selection.MoveUntil Cset:=Chr(147), Count:=wdBackward

and the second command extending the End of the selection is

  Selection.MoveEndUntil Cset:=Chr(148)

And there is a second set of commands for the search forward version.

Resulting macros

We substitute the double quote changes into the parentheses macros.

Select double quotes backward macro

To select all text between the previous set of double quotes backward in the document, use

Sub SelectDialogBackward()
  ' Select all text between the previous pair of double quotes including
  ' the double quotes.
  ' Insertion point does not have to start between the double quotes.
  ' No checks are performed for whether the double quotes exist or not.
  ' Assumes curly/smart double quotes, and does not check for straight
  ' double quotes.

  ' Move backward to a previous left double quote
  Selection.MoveUntil Cset:=Chr(210), Count:=wdBackward  ' On Mac
  'Selection.MoveUntil Cset:=Chr(147), Count:=wdBackward  ' On Windows

  ' Include the double quote and any spaces (optional) before it
  Selection.MoveStart Count:=-1
  'Selection.MoveStartWhile Cset:=" ", Count:=wdBackward

  ' Extend the end of the selection forward to the next right double quote
  Selection.MoveEndUntil Cset:=Chr(211)  ' On Mac
  'Selection.MoveEndUntil Cset:=Chr(148)  ' On Windows

  ' Include the double quotes and any spaces on the end
  Selection.MoveEnd
  Selection.MoveEndWhile Cset:=" "
End Sub

Customizing your version

Remove the single quote comment in your version of the macro on the line

  'Selection.MoveStartWhile Cset:=" ", Count:=wdBackward

if you like to include spaces at the beginning also.

Also select the correct line, if necessary, for Mac or Windows depending on your operating system using the lines

  Selection.MoveUntil Cset:=Chr(210), Count:=wdBackward  ' On Mac
  'Selection.MoveUntil Cset:=Chr(147), Count:=wdBackward  ' On Windows

Keyboard shortcuts

In Windows, I assign this to Alt+Shift+Single quote.

Unfortunately, Macs or Word for Mac (not sure exactly) have problems in some cases processing keyboard input when modifier keys are combined with some punctuation. I want 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. My guess is it’s a legacy issue from days gone by because there really is no practical reason to not recognize them.

I had to settle for Option+Control+Single quote in Word for Mac which is different than most of my other selection keyboard shortcuts since it doesn’t use the Shift key.

Select double quotes forward macro

After substituting the double quote character changes into the forward parentheses search macro, the result is

Sub SelectDialogForward()
  ' Select all text between the next pair of double quotes including
  ' the double quotes
  ' Insertion point does not have to start between the double quotes.
  ' No checks are performed for whether the double quotes exist or not.
  ' Assumes curly/smart double quotes, and does not check for straight
  ' double quotes.

  ' Move forward to the next right double quote
  Selection.MoveUntil Cset:=Chr(211)  ' On Mac
  'Selection.MoveUntil Cset:=Chr(148)  ' On Windows

  ' Include the double quote and any spaces after it
  Selection.MoveEnd
  Selection.MoveEndWhile Cset:=" "

  ' Extend the start of the selection to the previous left double quote
  Selection.MoveStartUntil Cset:=Chr(210), Count:=wdBackward  ' On Mac
  'Selection.MoveStartUntil Cset:=Chr(147), Count:=wdBackward  ' On Windows

  ' Include the double quote and any spaces (optional) at the start
  Selection.MoveStart Count:=-1
  'Selection.MoveStartWhile Cset:=" ", Count:=wdBackward
End Sub

Gotchas

Mixed smart double quotes

Sometimes if you’re working with odd characters or spacing in combination with double quotes, so Word will not properly apply the smart quotes. That is, it may leave a right quote on the left or vice versa.

This will make the macro work incorrectly, but unfortunately, it’s probably not worth the effort to rework the macro to allow misplaced or incorrectly applied smart quotes.

Straight double quotes

The above double quote versions of the macro required smart quotes to work and ignored straight quotes entirely.

If you wish to extend your version to allow straight double quotes, then there is no direction information associated with the character, so it becomes unnecessarily complicated trying to work through the cases to properly select dialog text correctly.

I almost always use smart quotes in Word, so I chose not to attempt this variation.

If you’re interested in this implementation, let me know. If I get enough requests, I’ll consider adding it to the member content since it’s going to be more complicated than it seems at first glance to handle all the cases properly.

Affiliate Links

If you're interested in using Word or another tool related to the article, check out these affiliate links. I may make a small commission if you purchase when using them, but there is no increase in cost for you, and it helps to support this site and associated content.

I've been using Microsoft for Business for commercial use (that's us writers) on one of the lower pricing tiers for years. I get to use my macros, have online storage, and don't have to worry about software updates.