Friday, January 04, 2008

Mapping "Find Next/Previous" to F3/Shift+F3 in MS Word

Earlier today, after years of using Microsoft Word, I finally decided that I'd had enough of reopening the Find dialog every time I want to do a "Find Next" or "Find Previous" – that is, to have Word search up or down from the current caret position to find the next (or previous) instance of the string that I had most recently searched for via the Find dialog.

Visual Studio comes with this functionality by default, mapped to F3 for Find Next and Shift+F3 for Find Previous. Some other applications including Firefox and Notepad2 (Florian Balmer's excellent lightweight Notepad-like text editor) support these keyboard shortcuts as well. (Regular old notepad.exe supports F3, but not Shift+F3.) I'm very accustomed to using F3/Shift+F3, so I set out to get my copy of Word to support these.

(Update 4/28/2009: Jeff Cogswell commented with a much better solution to this problem that doesn't involve writing a custom macro, as detailed in this post -- see the comments on this post below for his solution!)

A search revealed that Microsoft Word supports a "Find Again" function, mapped by default to Shift+F4 and to Ctrl+Alt+y, but that isn't what I was looking for; I wanted to be able to easily search in either direction without having to open up the Find dialog and alter the setting of the search direction option.

So I ended up writing a couple of simple VBA functions using Word 2003's integrated Visual Basic Editor to do what I was looking for:

Sub FindNext()
   DoFind True

End Sub

Sub FindPrevious() DoFind False End Sub
Sub DoFind(findDirection As Boolean) 'Save the initial Find direction in order to restore it when we're done, 'so that we don't alter the current "Find Up" setting in the regular Find dialog. Dim initialFindDirection As Boolean initialFindDirection = Selection.Find.Forward 'Do the Find in the requested direction. Selection.Find.Forward = findDirection Selection.Find.Execute 'Restore the initial Find direction. Selection.Find.Forward = initialFindDirection End Sub

I determined that the Selection.Find.Execute statement was the key to getting Word to repeat a Find operation by using the Tools | Macro | Record New Macro functionality to record a macro of the built-in Ctrl+Alt+y "Find Again" shortcut, and then inspecting the resulting generated code in the VBA editor. Using the editor's intellisense functionality, it was simple to determine that the Selection.Find.Forward property was what controls the direction of the Find.

At first, I just wrote the FindNext and FindPrevious methods, setting Selection.Find.Forward to the appropriate value, and then calling Selection.Find.Execute. When testing those methods, though, I noticed that the setting of the Find direction carried over to be the new initial value for the Find dialog; i.e. after running the FindPrevious method, the next time the Find dialog was used, it would be set to find in the Up direction by default. I added the DoFind method to handle this issue, by temporarily setting Find.Forward to the necessary value, doing the Find, and then setting Find.Forward back to its original value.

To use these FindNext and FindPrevious functions yourself in Word 2003, paste the code above into the VBA editor (Tools | Macro | Visual Basic Editor), and save them. Then, map the F3 and Shift+F3 keys (or other keys of your choice) to FindNext and FindPrevious respectively by using the Customize Keyboard dialog (Tools | Customize, then click the Keyboard button at the bottom of the Customize dialog).

I would imagine that these functions should be similarly usable under Word 2007 as well, but since 2007's menu system and customization interface have changed, there are likely to be some changes to the steps necessary to enter the functions and map them to the F3 and Shift+F3 keys.