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

Get next character after range

Word • Macros • Functions
Peter Ronhovde
8
min read

Text manipulation macros often need the next character after a range. It’s a trivial task that requires several steps, and it happens often enough that it would be convenient to have a dedicated function to accomplish the task.

Thanks for your interest

This content is part of a paid plan.

Get Next Character After Range

We are building several functions to streamline our previous move sentence macro, but this one finds uses in multiple other macros.

The Problem

Unfortunately, what is considered the “next” character for a range depends on whether the range is empty or not. In my opinion, the next character is the character immediately after the range ends.

If the range spans any text in the document, then the next character is the one immediately after the End position of the range. This makes sense.

With an empty range, the next character would intuitively be the character immediately after the range (the End position), but VBA considers the “first” character as part of an empty range even if it spans no text in the document (its Start and End positions are equal). This is not intuitive in my opinion since conditional logic often relies on the next character as mentioned above. This function remedies this inconvenient situation.

Create function skeleton

The function skeleton is basically the same as previous ones we’ve created.

Function GetRangeNextCharacter(r As Range) As String
' Include function steps ...

' Return next character
GetRangeNextCharacter = ""
End Function

What parameter to use?

We accept the range in question after which we want the next character. We call is simply r for a range since it’s easy to type.

Return type

In this function, we will return a single character after the range. While there is a specific character data type in VBA, it’s convenient to just return the next character as a regular String just one character in length.

If the range doesn’t exist, then return an empty string “”. This is useful because it informs the user that the range was not valid without causing any other problems.

What’s the plan?

We basically just need to test whether the range is empty and return the “correct” next character.

Character count does not work

It would (theoretically) make sense to check how many characters are in the range. Zero characters would be empty, and one character ...

Unfortunately, we can’t check whether a range is empty by using how many characters are spanned. This would use the Count property, but it doesn't work as expected since even an empty range is considered to have one character, but this is also the case with a range spanning literally one character.

Arghhh!

Use Start and End positions

Instead, we can check whether the range is empty using the Start and End positions.

r.Start = r.End

Recall the Start and End positions are literal character positions in the document counting from 0 as the beginning of the document. If the two position values are the same, the range is empty since it spans no text.

Now combine this with an If statement to assign the appropriate character as the function return value.

' Get next character immediately after working range
If r.Start = r.End Then
' Range is empty, so use first character
' ...
Else
' Range is not empty, so use regular next character
' ...
End If

Get the first character

The first character is found using the working range’s Characters collection.

r.Characters.First

Specifically, we want the First character, but this is actually a range in the document, so we need the Text property of that range.

r.Characters.First.Text

The text property yields a String value containing all text in the range without any formatting.

Get the next character

If the range spans any text in the document, we instead use the Next method of a range.

r.Next(Unit:=wdCharacter)

The Next command returns a range corresponding to the Unit given. Of course, we specified wdCharacter. We also put the Unit option inside parentheses since we’re accessing that range’s Text property to get the next character.

r.Next(Unit:=wdCharacter).Text

Intuitive next character

Putting the conditional steps together, we get the intuitive next character.

' Get next character immediately after working range
If r.Start = r.End Then
' Range is empty, so use first character
GetRangeNextCharacter = r.Characters.First.Text
Else
' Range is not empty, so use regular next character
GetRangeNextCharacter = r.Next(Unit:=wdCharacter).Text
End If

We just stored the text value in the function name as the respective return value.

Gotchas

This function is quite general, so we should probably think about other problems.

What if the range doesn’t exist?

What if the user gives us a range variable that isn’t actually assigned to any range of the document?

To be safe, we should add a few steps to check whether the range exists and just exit the function if not.

If r Is Nothing Then
' No range detected. Aborting function.
' ...
End If

What is Nothing?

We don’t want to wax too philosophical or even technical here, but “Nothing” in VBA is assigned to an object that doesn’t exist in the regular sense. We use “Is Nothing” in the condition since it is not a value in the normal sense.

The function still expects a return value, so we need to assign something that makes sense before we quit the function.

GetRangeNextCharacter = ""

Since we found no next character, a literal empty string (no characters in the double quotes) makes the most sense, and it communicates to whoever is using the function that something went wrong.

Quit the function

Now we abort the function.

Exit Function

The Exit Function command quits the function immediately. No steps after the command are run which is why we needed to assign the return value before giving this command.

Invalid range check

Putting it together, our invalid working range check is:

' Make sure range r exists
If r Is Nothing Then
' No range detected. Aborting function.
GetRangeNextCharacter = ""
Exit Function
End If

Invalid range check placement

Placement is important though. We need to check whether the given range is Nothing before we try to use it later in the function. Otherwise we’ll get an error because we would be attempting to reference an invalid range.

This extra Nothing check is an example of being able to add extra safeguards in a dedicated function without cluttering our main macros with lots of extra steps.

Final Function

This function is small but useful. It saves multiple steps for some condition checks in other macros.

Function GetRangeNextCharacter(r As Range) As String
' Get character after range r in the intuitive sense

' Make sure range r exists
If r Is Nothing Then
' No range detected. Aborting function.
GetRangeNextCharacter = ""
Exit Function
End If

' Get next character immediately after working range
If r.Start = r.End Then
' If there is no span of text in the range, then the "next" character consists
' (by word defaults) of the character immediately to the right of the cursor.
GetRangeNextCharacter = r.Characters.First.Text
Else
' Normal case of getting the character immediately to the right of the range
GetRangeNextCharacter = r.Next(Unit:=wdCharacter).Text
End If
End Function

We aren’t required to assign the function’s return value at the end of the function, but we do need to assign a value somewhere in the macro.

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.