在 For-Next 循环 vba 期间按顺序显示控件

Posted

技术标签:

【中文标题】在 For-Next 循环 vba 期间按顺序显示控件【英文标题】:Display controls with order during For-Next loop vba 【发布时间】:2019-02-23 14:29:27 【问题描述】:

我有一个带有很多控件的 VBA 应用程序。 我想在 For-Next 循环期间按照阅读顺序访问控件。

' Parcours des contrôles de l'userform
For Each cCont In Me.Controls

   ' TypeName(cCont)
    MsgBox (cCont.Name)

Next cCont

实际上,我认为我正在访问创建日期...

你知道我是否可以配置阅读顺序吗?

谢谢

【问题讨论】:

您有什么特别的理由希望它们出现在an order of reading 中吗?另外,不确定an order of reading 是什么意思? 我认为这是关于序列的。 AFAIK For each loop 只是在添加控件时通过控件,您无法更改它。 感谢您的回复,确实是关于序列 如果您确实需要按特定顺序处理它们,您可以在For Each 循环中创建一个字典,对字典进行排序,然后按字典排序顺序进行处理。 【参考方案1】:

一种方法是按 TabIndex 属性对它们进行排序。将选项卡索引设置为所需的顺序,然后使用:

Private Sub test()

    Dim cCont As Control
    Dim i As Integer
    Dim maxIndex As Integer
    Dim controls As Object
    Dim key As Variant

    Set controls = CreateObject("Scripting.Dictionary")

    'Add controls to dictionary, key by tabindex property
    For Each cCont In Me.controls
        maxIndex = IIf(maxIndex < cCont.TabIndex, cCont.TabIndex, maxIndex)
        controls.Add cCont.TabIndex, cCont
    Next cCont

    'Get controls in order
    For i = 0 To maxIndex
        If controls.exists(i) Then
            MsgBox controls(i).Name
        End If
    Next i

End Sub

【讨论】:

【参考方案2】:

发布的代码是一个很好的解决方案,我通过这个微小的更改使其对我有用。我通过了用户表单,因为我在模块中使用了代码。我排除了 LabelCommandButtonImage 以使 Valon Miller 的代码为我工作,否则所描述的运行时错误将runtime error '-2147352573 (800 200037': Member not found 显示.

Private Sub test(frm As UserForm)
    Dim cCont As Control
    Dim i As Integer
    Dim maxIndex As Integer
    Dim controls As Object
    Dim key As Variant

    Set controls = CreateObject("Scripting.Dictionary")

    'Add controls to dictionary, key by tabindex property
    For Each cCont In frm.controls
      If TypeName(cCont) <> "Label" And _
         TypeName(cCont) <> "Image" And _
         TypeName(cCont) <> "CommandButton" Then
            maxIndex = IIf(maxIndex < cCont.TabIndex, cCont.TabIndex, maxIndex)
            controls.Add cCont.TabIndex, cCont
      End If
    Next cCont

    'Get controls in order
    For i = 0 To maxIndex
        If controls.exists(i) Then
          Debug.Print controls(i).Name & vbTab & i
            MsgBox controls(i).Name
        End If
    Next i

End Sub

--------------------------------------------

最初我需要一个解决方案来使 sql 语句的顺序与我的表单控件的顺序同步。我想这样做:

fld1 = recordset1.value
fld2 = recordset2.value
fld3 = recordset3.value

正在寻找一种解决方案来让我的控件和我的 SQL 语句按 field1 ->recordset.value1 的顺序排列。

因此,我没有使用 taborder 对控件进行排序,而是创建了控件数组。即

sub useControlArray()
    dim a as variant, rs as new recordset, strSQL as string
    strSQL = "select fld1, fld2, fld3 from table"
    rs.open strSQL, connection
    a = array("fld1", "fld2", "fld3")
    'This array would help like this:
    for i = lbound(a) to ubound(a)
        frm.controls(a(i)) = rs(i)
        debug.print frm.controls(a(i)) ' Form is a user form
    next i
end sub

这会将控件限制为使用与我的 SQL 语句中相同的顺序填充它们所需的控件数量,并且我不需要注意控件是否存在。

我希望这会有所帮助。

【讨论】:

以上是关于在 For-Next 循环 vba 期间按顺序显示控件的主要内容,如果未能解决你的问题,请参考以下文章

vba 按顺序打开文件夹下含特定字符的工作簿

VBA Access - 按字母顺序排序列表框

从与特定日期匹配的列表中提取值 - Excel VBA循环

EXCEL VBA 窗体显示期间不执行下面代码,也不影响操作工作表?

Excel用vba按先后顺序打开一个文件夹中的N个excel工作簿,运行一段宏程序后

使用 VBA 循环遍历 XML