How to set the tab order of a Word form

Article contributed by Dave Rado and Mark Tangard

A common obstacle encountered in designing Word forms is that Word itself, not you, decides this tabbing sequence - decides what the next formfield will be – and you may not agree with its decisions. For example, if the formfields are in a table, you might want your users to tab through all the fields in column 1, then column 2, then column 3; whereas by default, they will tab through the formfields in row 1, then row 2, then row 3.

Unfortunately, there is no way to set the tab order via the user-interface, you have to use a macro. Even more unfortunately, the macro does not differentiate between tabbing out of a formfield and clicking with the mouse. So if you do use a macro to set the tab order, your users will be unable to click with their mouse in the form field of their choice – for instance, after filling in formfield 10, you might notice an error in formfield 2; but when you click in formfield 2 to correct the error, the macro will send you to formfield 11 (if that happens to be the next item in your tab-order) – which can be very disconcerting!

For this and other reasons, a UserForm (Microsoft-speak for a custom dialog box) is usually a much more elegant solution for form filling than a document-based form. The UserForm code could fill in the document form (with or without using form fields in the document); and the tab-order of UserForm controls is very easy to set.

However, if you do want to set the tab-order of form fields, despite the drawbacks, this is how to do it:

Method 1: create an OnExit macro for each form field

Supposing, for example, you have three form fields in your document, and that their bookmark names (right-click + Properties + Bookmark)  are "Text 1", "Text2" and "Text3", you could put the following code into the ThisDocument module of your template, and assign each macro as the Exit macro for the appropriate formfield.

Note, however, that it is a good idea to give the bookmarks more meaningful names than this!

Option Explicit

Sub ExitText1()
    ActiveDocument.Bookmarks("Text3").Range.Fields(1).Result.Select
End Sub

Sub ExitText2()
    ActiveDocument.Bookmarks("Text1").Range.Fields(1).Result.Select
End Sub

Sub ExitText3()
    ActiveDocument.Bookmarks("Text2").Range.Fields(1).Result.Select
End Sub

Microsoft Knowledge Base (MSKB) article Q212378 suggests using Selection.GoTo What:=wdGoToBookmark, but as discussed in the article: The best way to select a form field using VBA, that method is buggy, and the method used above works much more satisfactorily.

Method 2: assign a single OnExit macro to all your form fields

If you have a lot of form fields you might find it easier to create a single macro to set the tab-order, assigned as the Exit macro for every formfield, as follows:

Sub TabOrder()

Dim StrCurFFld As String, StrFFldToGoTo As String

'First get the name of the current formfield
If Selection.FormFields.Count = 1 Then
    'No textbox but a check- or listbox
    StrCurFFld = Selection.FormFields(1).Name
ElseIf Selection.FormFields.Count = 0 And Selection.Bookmarks.Count > 0 Then
   
'Textbox
    StrCurFFld = Selection.Bookmarks(Selection.Bookmarks.Count).Name
End If

'Then find out which formfield to go to next ...
Select Case StrCurFFld
     Case "Text1"
        StrFFldToGoTo = "Text3"
     Case "Text2"
        StrFFldToGoTo = "Text1"
     Case "Text3"
        StrFFldToGoTo = "Text2"
 End Select
'... and go to it.
ActiveDocument.Bookmarks(StrFFldToGoTo).Range.Fields(1).Result.Select

End Sub

Again, MSKB article Q212378 suggests using Selection.GoTo, but the above method works better, for the reasons discussed previously.

Also, the KB article suggests unprotecting and reprotecting the document in order to find out the name of the current formfield, but the method used above (and discussed in the article: How to find the name of the current formfield) is more elegant and runs more quickly.