代码之家  ›  专栏  ›  技术社区  ›  Julie S.

Excel VBA for循环的代码帮助,用于检查多个ListBoxes是否有值?

  •  1
  • Julie S.  · 技术社区  · 6 月前

    我有一个Userform(Userform1),它有4个列表框(ListBox1到4),每个列表框中都有条目。表单用户选择列表中的条目,然后点击CommandButton(CommandButton_1)。然后,VBA宏将每个列表框中的值写入excel日志表上的单元格中。用项目填充列表框并将结果写入电子表格的代码正在工作。

    但是,我希望能够检查以确保所有列表框都有选择。在写入数据之前,必须始终填写所有内容,否则我们在以后的分析中会失去数据完整性。

    我已经想出了如何检查 个人 listbox没有选择,但我想对其进行概括,以便能够考虑任何数量的listbox。到目前为止,我已经尝试过:

    'Attempt 1
    
         For Each Control In Me.Controls
             If Controls.Name Like "Listbox*" Then
                 If Controls.Value <> "" Then
                     Else: MsgBox ("You must select a value for every list.")
                     GoTo ERROR_ENDSUB
                 End If
             End If
         Next
    

    A1给了我错误438:Obect不支持此属性或方法(If-Controls.Name行)。

    'Attempt 2
    
         Dim sh as Worksheet
         Set sh = ThisWorkbook.Sheets("Downtime")
         For i = 1 To 4
             If "sh.listbox" & i & ".value" <> "" Then
                 Else: MsgBox ("You must select a value for every list.")
                 GoTo ERROR_ENDSUB
             End If
         Next
    

    A2只是不起作用,我可以把列表留空,它仍然会在没有Msgbox的情况下写入数据。

    'Attempt 3
        
        Dim LB as ListBox
        For i = 1 To 4
            Set LB = ListBoxes("Listbox" & i)
            If LB.Value <> "" Then
                Else: MsgBox ("You must select a value for every list.")
                GoTo ERROR_ENDSUB
            End If
        Next
    

    A3给出了一个编译错误:未定义子函数或函数(突出显示Listboxes())。

    如果我对函数/方法的VBA对象模型不是100%熟悉,请原谅我。我是一名化学工程师,以擅长excel(配方方面的事情)而闻名,我的公司一直在给我越来越大的电子表格自动化任务。最终,它们变得太大了,现在我在过去一周左右的时间里一直在努力学习VBA,而之前没有编码经验。

    3 回复  |  直到 6 月前
        1
  •  1
  •   Tim Williams    6 月前

    例如:

    Private Sub UserForm_Activate()
        Dim con As Control
        For Each con In Me.Controls
            If TypeName(con) = "ListBox" Then
                Debug.Print "Found listbox: " & con.Name
            End If
        Next con
    End Sub
    
        2
  •  0
  •   Abu Ben Reaz    6 月前

    你可以试试这个简单的代码

    Private Sub CommandButton1_Click()
    Dim contr As Control
    
    For Each contr In UserForm1.Controls
        If TypeName(contr) = "ListBox" Then
            If contr <> "" Then
        
            Else
                MsgBox ("You must select a value for every list.(" & contr.Name & ")")
                Exit Sub
            End If
        End If
    Next
    End Sub
    
        3
  •  0
  •   FunThomas    6 月前

    尝试1已接近。正如黑猫在评论中提到的,你的迭代变量是 Control 所以你需要写 If Control.Value <> "" Then .

    尝试2有两个主要问题。首先,您不是在循环用户表单的控件,而是试图从工作表中访问某些内容。然而,你甚至没有这样做:你真正在做的是比较 一串 “sh.listbox1”为空字符串。

    尝试3抛出编译器错误,因为集合 ListBoxes 对于用户表单不存在(对于工作表存在)。


    我强烈建议更改您的语法和逻辑 If Else -声明。首先,不要将If分支留空,只将代码放入Else分支。相反,请恢复If条件:

    If Control.Value = "" Then
        MsgBox "You must select a value for every list."
        GoTo ERROR_ENDSUB
    End If 
    

    如果 你需要一个Else分支,不要使用这种奇怪的语法,使用引号直接在后面添加第一条语句 其他 。它很难看,使代码更难阅读。此外,正确缩进代码:

    If Control.Value <> "" Then
        MsgBox "You did a good job, good boy"
    Else
        MsgBox "You must select a value for every list."
        GoTo ERROR_ENDSUB
    End If 
    

    也就是说:当你真的想检查 姓名 在控制中,尝试1(经过上述纠正)是正确的做法。但是,如果你使用编码进行处理,你会发现最好重命名控件,如果它们的名称有意义,比如 lbCountry , lbState , selectManager 或者别的什么。在这种情况下,检查姓名很容易失败。您应该考虑循环控制并检查 类型 的控制。 蒂姆威廉姆斯 答案显示了如何做到这一点(检查 TypeName 控制)。