Many typing errors are momentary flubs where you just want a quick fix rather than postponing the correction until some drawn out editing process.
Thanks for your interest
This content is part of a paid plan.
Correct Previous Typing Error
Like the red squiggles under spelling errors, I also don’t like those little blue lines for grammatical errors as you type. They’re a little better, but they still break my concentration.
Standard forward correction keyboard shortcut
Word has a standard keyboard shortcut to correct the next spelling or grammar error, Option+F7 on Mac or Alt+F7 on Windows. That’s how Microsoft envisioned the editing feature being used, moving forward through the document, but I often want to fix the previous error with a quick keyboard shortcut.
With that in mind, we create a macro to jump back to the previous spelling or grammatical error and make the context-based correction.
Connection to previous macro
This macro dovetails well with a previous variation where we automatically corrected spelling errors without any user input. This version utilizes Word’s standard inline dialog to give us more control over the specific correction while doing double duty by handling grammatical errors.
Overall, it isn’t quite as fast as the previous macro, and it requires a little bit of hackery to get the job done, but it does 98% of what we need (see gotchas below if you want to know about the missing 2%). There is some overlap with the previous variation, but this article stands on its own.
What’s the plan?
As we proceed, I’ll refer to grammatical errors to be concrete, but the resulting macro applies to both types of errors with no changes.
Working scenario
My working scenario is:
I'm typing a novel, but I make a mistake. I’m in the flow and am already several words ahead in the document (there is often a small delay with Word processing editing errors). Those blue lines pop under a word, and … My. Attention. Must. Fix. Error.
What should the macro do?
Manually we would need to navigate back to the error and fix it, but we're trying to expedite that process. The basic steps to fix the error in a macro are:
- GoTo the previous typing error within a reasonable document range (last part is optional).
- Run the existing Word command to fix spelling errors, but it also catches and allows us to correct grammatical errors.
Manual follow-up
I usually prefer my macros to fix the error and be done (see previous version for spelling errors), but this is an example of where that's not possible (or at least not easy to do). The above steps end the macro contribution, but I then need to finish the task.
- Manually select the correction using the context dialog.
- Jump back to my previous working location in the document using a standard Word keyboard shortcut Shift+F5.
The correction does require the manual choice, but it’s usually fast since the first suggestion is often correct (just hit enter). Plus, correcting grammatical errors usually requires more human input anyhow, and sometimes our automated spelling correction macro doesn’t get the word right. This macro gives us a way to fix that.
But we have a problem ...
Grammar errors in Word are associated with the whole sentence, but … VBA doesn’t give us access to any commands to show the context correction dialog for either grammar or spelling errors.
Thus we need to work through an existing Word command NextMisspelling. On the positive side, it also works for grammar errors with a small caveat. Given its name, it seems to prioritize spelling errors in the same sentence.
Limited search range
Using a limited search range is not as much of an issue with this macro compared to the previous article. We’re answering a context dialog for any error corrections, so it’s difficult to make unintended changes to the text, but I still like to constrain the search within the current page.
My imagined use case is making quick changes as I write rather than working through a more detailed editing session. Constraining the changes to within the current page allows me to immediately validate them without jumping around the document.
The limited search range is a preference, of course. You could instead limit by the current paragraph, screen, or just not use one (see second version at the end).
Create macro skeleton
Open the VBA editor (Option+ or Alt+F11) and create an empty macro.
We append “OnPage” to this macro name since we’ll the version at the end doesn’t restrict the search range.
Macros we assign to a keyboard shortcut can’t have any parameters or return values. They also don’t appear in the Word macro list to run independently through the View → Macros dialog.
Define working range using Page bookmark
We need a working range variable to perform the GoTo command and then a second one to ensure the found text range is inside the intended search range.
To define the search range rSearch, we start with the current page. For our purposes here, a bookmark in Word is like a range but with some extra stuff. A previous article talks about using bookmarks to access some Word-defined document ranges.
The fastest way to get the current page range is to use one of Word’s predefined bookmarks named \Page. We use the Bookmarks collection of the Selection object including double quotes “\Page” to specify the bookmark name.
We referred to the Range property since a Bookmark includes some extra stuff, but we just want the spanned document content. We assigned the corresponding bookmark page range to the rSearch range variable using a Set command because a Range is an “object” in Word not just a plain value.
Limit working range to previous content
The current search range is the entire page, so we need to further constrain the range based on the user's current location in the document. We assign the end position of the Selection to the End position of the working range.
No Set is required here because the End positions are just character position values in the document.
Sentence extension due to grammar error
Since we’re dealing with possible grammar errors, we further tweak the search range to include the whole current sentence. Word grammar error ranges in VBA are based on the whole sentence, and there is a possibility of missing an error if multiple exist in the current sentence. Toward this end, we extend the search range to the end of the sentence to catch all errors in the sentence.
We’ve used the EndOf command before, but it moves the range to the end of the indicated Unit which is wdSentence here, of course. EndOf would automatically collapse the spanned text of the range during the move. However, we don’t want to disturb the rest of the search range, so we use the Extend option with wdExtend.
Set working error range
Now we need a second working range to find the error if it exists. We initially define the error range based on the current location in the document.
Now we need to adjust for the end of the current sentence for the same reason mentioned above with rSearch.
We do not need to extend the range like we did above with the rSearch range since the upcoming GoTo command doesn’t care (mostly).
GoTo previous error
Since we’re targeting either grammatical or spelling errors, we take advantage of a search option for a GoTo command to do exactly that.
There are several flavors of GoTo commands, so it’s more convenient to use GoToPrevious. The What option indicates the type of document element we want to find using a list of standard Word constants. The wdGoToProofreadingError constant searches for either type of error. The option must be included inside parentheses in the command since we are storing the returned range.
We updated the rError range with the returned range found by the GoToPrevious command since the rError variable was always intended to mark the error position (if any prior ones exist).
We could technically specialize at this point to one or the other error types, but it would be problematic later since the main command below is wishy-washy on which error type it corrects despite its name.
Validating error location
It's good practice to validate that the range returned by the GoToPrevious command results in a valid document range (invalid for an object is often indicated by a Nothing assignment). However, I've tested this command in various cases and situations, but I haven't had any problems. Therefore, I skipped my normal validation check for the GoTo command to keep the macro a little simpler.
Check search range
In this version, we check the found error against the intended search range using a standard range method.
The InRange method checks whether rError is inside of the rSearch range and returns True if so and False if not. Combining this into a conditional statement, we have:
Running context dialog
Now we get to the bit of hackery previously advertised.
We have no VBA method to invoke the grammatical or spelling error context dialog. Thus, we need to invoke a standard Word command NextMisspelling. Despite the name, it will also open the context dialog for grammar errors. Although, it does seem to prefer spelling errors if both are in the same sentence (not quite sure of the conditions).
Correct at error location
If we just run the Word command, it will search forward in the document from the user’s current document position, but we want it to catch the typing error we’ve found earlier at the rError range.
As far as I know, we can’t change the behavior of NextMisspelling, but we can select the error range to force the search to start from that text.
We usually do not select text like this in the middle of a macro because it literally selects the text in the document for the user. Here is it a necessity to properly use the NextMisspelling command, and the following command would select the error text anyhow.
Of course, this command needs to be in front of the NextMisspelling command.
Run Word command
We can run any macro or standard Word command using the Application Run method.
Despite the option name MacroName, we can provide a standard Word command, specifically NextMisspelling for this macro. The name must be in double quotes.
We can only invoke the Word command. To my knowledge, we don’t have any other control over it.
Fixing the error
Correcting the error is a manual user decision for this macro, but you can jump back to your working location afterward using Shift+F5.
Gotchas
Where could all this go wrong?
What if no previous errors or suggestions exist?
If the above GoToPrevious command doesn’t find an error, nothing happens because the error range location will not be inside the search range rSearch.
I don’t know the exact details of the NextMisspelling command, but if there are no suggestions, the context dialog just tells you that. You can then choose to ignore the error or add it to the active custom dictionary if it’s a custom word just not yet in the custom dictionary.
It looks like we’re okay with both cases.
Error order for grammar errors
The GoTo command identifies the previous error as desired, and everything works fine most of the time …
“Uh oh …”
Yeah, there’s a “but” coming.
Unfortunately, if it finds a grammar error first (moving backward in the document), it will prioritize correcting the first error in the sentence of whichever type.
Arghhh. That doesn’t make sense.
While technically okay, since it will still detect the original grammar error in the sentence after we fix the first error, it violates the name and intent of the macro, CorrectPreviousErrorOnPage.
We only need run the macro again, and it will catch the second grammar error (now located after the insertion point but still inside the current sentence), but … it’s just not … it shouldn’t be that way. It’s kind of false advertising.
What’s the problem?
In VBA, a grammar error is marked as a blue double underline for one or more words in a sentence similar to spelling errors (except for the red squiggles), but a grammar error nevertheless encompasses the whole sentence when searching for it. With any VBA approach, a grammar error is returned as a sentence range.
Also, the command we’re leveraging to correct errors with the context dialog is called NextMisspelling. Given its name, it apparently prioritizes spelling errors (although I am not sure). There is no corresponding standard Word command like “NextGrammarError” that specializes only in grammar errors. Kind of a misnomer.
The NextMisspelling command does double duty but with some caveats that are difficult to work around (maybe not even possible). VBA does not give us access to comparable methods for manipulating grammar errors in the same way as spelling errors, and there are even some annoying limitations when working with spelling errors.
Are there fixes?
We could remove the search range extension where we included the whole starting sentence, but then we might skip a grammar error for the same reason as above.
If we try to solve the issue by focusing only on one error type, we’re stymied again because the NextMisspelling command (which we must use to get the convenient context dialog behavior) will catch both error types, and we have no control over that command.
Ughhh.
Verdict … stuck with it?
I work hard to avoid issues like this even in my personal macros, but given the more limited VBA access to commands in this context, it appears we are stuck with this behavior.
At this point, I must pinch my nose against the smell and move on.
Final Macro
Putting everything together, the macro is:
I assigned this macro to Control+Option+F7 in Word for Mac or Alt+Shift+F7 on Windows both of which override standard function key shortcuts because I rarely use most of the default Word function key shortcuts.
I usually try to keep some symmetry between the Word for Mac and Windows keyboard shortcuts, but Windows is missing a fourth modifier key possibility (the Windows command key is limited to operating system shortcuts) which hinders some keyboard shortcut combinations in Word (please change this Microsoft!).
Improvements?
I preach about letting the macro do as much work for us as possible (within reason, I suppose), so it would be nice if the macro would automatically jump back to our typing position in the document, so we could just keep writing. We accomplished this in the previous spelling error version by using the first correction suggestion.
Unfortunately, most relevant VBA steps after we invoke the editing error dialog will collapse the dialog. We wouldn’t be able to pick a correction, so as far as I know (without some serious VBA shenanigans), we must allow the macro to end (by not doing anything else) and follow the selected dialog correction with a manual keyboard shortcut Shift+F5 to jump back to our previous working location.
Arghhh. It’s an annoying extra step but not the end of the world.
Some languages like JavaScript have capabilities like awaiting a result, but to my knowledge, VBA is an older language that does not share these more advanced features.
Simplified with no search range
This version removes the constrained search range, but we still need to validate whether we found an error because the standard NextMisspelling command will automatically search forward in the document. With only a little extra commentary below, the result is:
In this version, the validation check before calling the NextMisspelling command is done with the IsEqual method. This method checks whether rError corresponds to exactly the same spanned document content as the starting range rStart.