I hate designing userforms. I mean the part where I’m lining up controls, renaming controls, and all the other super-fiddly parts of making a form look and act right – like setting the tab order. I always wait until the very end so I don’t have to do it twice. And that Tab Order dialog? Forget about it.
When I’m finally ready to set the tab order, I find the first control and click Move Up until it’s at the top. Next, I find the second control and click Move Up until it’s just below the first control. Then I go to Whammyburger and force them to serve me breakfast. Then I go back and do the rest of the controls. It’s maddening. I decided finally to do something about it.
First I set a reference to the VBA Extensibility Library.
Then I put this code in a standard module
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
Public Sub FixTabOrder() Dim ctl As Control Dim i As Long, j As Long Dim lCnt As Long Dim vbc As VBIDE.VBComponent 'Change this to the name of your userform Set vbc = ThisWorkbook.VBProject.VBComponents("UInvoice") For i = 1 To vbc.Properties("Width") For j = 1 To vbc.Properties("Height") For Each ctl In vbc.Designer.Controls If ctl.Top = i And ctl.Left = j Then ctl.TabIndex = lCnt lCnt = lCnt + 1 End If Next ctl Next j Next i For Each ctl In vbc.Designer.Controls Debug.Print ctl.Name, ctl.TabIndex Next ctl End Sub |
This is pretty brute force, but it only take a few seconds to run, so who cares. The i and j variables move through the userform point-by-point, left to right, top to bottom (that’s the typographical point, not the agenda items point). For every point on the userform, it loops through every control to see if that control starts at that point. If it finds one, it sets the controls TabIndex to the next number. At the end it just prints out the control names and tabs.
Even if that’s not exactly how I want my tab order, it gets it close and I can make other modifications manually.
If you have a super-wide or super-long form, it will take longer. The right way to do this is to put all the controls in an array and sort them by their Top and Left properties. If this method is too slow, you should write that up. Then send me a copy.