Reputation: 191
Could someone help me understand how to adjust the order that a "For Each" loop will cycle through a UserForm's controls? (I know it's not cycling via "TabIndex" order, and I understand it doesn't care about the "TabIndex" when looping programatically in "For Each".)
I added controls to my current UserForm (screenshot below) by copying a single controls for a couple and then a group of controls (Ctrl+click, copy/paste) from a previous form, and adding controls after that. The group of controls ("Site Name" to "City,St,Zip") cycles in reverse-order (bottom to top). Ideally, I want to cycle from the top to bottom continuously.
I tried to re-order by right-clicking and "Send Backward/Forward" but that does nothing for my "For Each" loop.
For Each txtBox In ADSheaderForm.Controls
If TypeName(txtBox) = "TextBox" Then
If txtBox.Name = "stNmTxtBx" Then
ReDim Preserve txtArr(txtNum)
txtArr(txtNum) = txtBox.Text
txtNum = txtNum + 1
Else
If txtBox.Text = "" Or txtBox.Text = "Optional" Then
ReDim Preserve txtArr(txtNum)
txtArr(txtNum) = "Not Entered"
txtNum = txtNum + 1
Else
ReDim Preserve txtArr(txtNum)
txtArr(txtNum) = txtBox.Text
txtNum = txtNum + 1
End If
End If
End If
Next
Upvotes: 3
Views: 2214
Reputation: 46
You can reorder them all at once, as MacroMarc touched on, using the copy/paste function but the controls must be selected REVERSE order from what you want them to cycle.
For your example, in the userform you would select the textbox next to "Scope of Work", hold CTRL and click on each subsequent control, again in reverse order. Cut, paste and voilà, they will cycle in the correct order.
Upvotes: 1
Reputation: 11
I had a similar problem working with an Access form and was looking for solutions, so I stumbled upon this post. Because of my very limited knowledge of VBA syntax, I had to turn MarcoMarc's idea (thanks for that, btw) into something I would know how to write.
Here's what I came up with... It worked for me:
Dim i as Integer
Dim ctl as Control
For i = 1 To ADSheaderForm.Controls.Count
For Each ctl In ADSheaderForm.Controls
If ctl.TabIndex = i then
'do something
Exit For
End If
Next ctl
Next i
Upvotes: 1
Reputation: 3324
The controls seem to be added into the form by copy/paste order(a group often has last as first), and you cannot change that order of controls.
You could look at the following code and see how you might use the tabIndex to reorder the controls for your purpose.
Dim ctrl As Control
Dim str As String
Dim v() As Control
Dim i As Long
Dim arrItem As Variant
i = ADSheaderForm.Controls.count
ReDim v(1 To i)
For Each ctrl In ADSheaderForm.Controls
Set v(ctrl.TabIndex + 1) = ctrl
Next ctrl
For Each arrItem In v
str = str & arrItem.Name & vbNewLine
'Actually do your code as above within this loop e.g. if typeName = blabla
Next arrItem
MsgBox str
If you set the tabIndexes to run as you do, then this will push them into an array by tabIndex position. Then you cycle through the array.
Upvotes: 1