检查值是否是列表的成员

Evi*_*ine 11 excel vba excel-vba

  • 我必须根据项目列表检查一条用户输入; 如果输入位于项目列表中,则将流程指向一个方向.如果没有,将流量引导到另一个流量.
  • 此列表在工作表本身中可见; 它必须在代码下进行混淆.

我想到了两种策略:

  1. 声明为enum并检查输入是否属于此enum,虽然我不确定这个的语法 - 我是否需要在enum每次使用它时初始化它?
  2. 声明为数组并检查输入是否是此数组的一部分.

我想知道VBA哪个在效率和可读性方面更好?

小智 7

与.NET语言不同,VBA不会将Enum公开为文本.它严格地是一个数字,并且没有.ToString()方法可以公开枚举的名称.可以创建自己的ToString()方法并返回枚举的String表示.枚举Enum类型也是可能的.尽管所有这些都是可以实现的,但我不建议这样做,因为对于这样的单个任务来说,过于复杂.

如何创建项的Dictionary集合,只需使用Exist方法和某种错误处理(或简单的if/else语句)来检查列表中是否存在输入框中的任何用户输入.

例如:

Sub Main()

    Dim myList As Object
    Set myList = CreateObject("Scripting.Dictionary")

    myList.Add "item1", 1
    myList.Add "item2", 2
    myList.Add "item3", 3

    Dim userInput As String
    userInput = InputBox("Type something:")

    If myList.Exists(userInput) Then
        MsgBox userInput & " exists in the list"
    Else
        MsgBox userInput & " does not exist in the list"
    End If

End Sub
Run Code Online (Sandbox Code Playgroud)

注意:如果您添加对Microsoft Scripting Runtime库的引用,那么您将能够将智能与myList对象一起使用,因为它本来是早期绑定的替换

 Dim myList As Object
 Set myList = CreateObject("Scripting.Dictionary")
Run Code Online (Sandbox Code Playgroud)

Dim myList as Dictionary
Set myList = new Dictionary
Run Code Online (Sandbox Code Playgroud)

这取决于你想要采用哪种方式以及更方便的方式.请注意,如果您使用Late Binding,则不需要添加引用,如果您希望使用智能早期绑定,则需要引用.


只是为了让读者能够使用Enum可视化版本,让我演示这种机制可能如何工作

Enum EList
    item1
    item2
    item3
    [_Min] = item1
    [_Max] = item3
End Enum

Function ToString(eItem As EList) As String
    Select Case eItem
        Case EList.item1
            ToString = "item1"
        Case EList.item2
            ToString = "item2"
        Case EList.item3
            ToString = "item3"
    End Select
End Function

Function Exists(userInput As String) As Boolean
    Dim i As EList
    For i = EList.[_Min] To EList.[_Max]
        If userInput = ToString(i) Then
            Exists = True
            Exit Function
        End If
    Next
    Exists = False
End Function

Sub Main()

    Dim userInput As String
    userInput = InputBox("type something:")

    MsgBox Exists(userInput)

End Sub
Run Code Online (Sandbox Code Playgroud)

首先,将List列为Enum.我只为示例添加了3个项目,以尽可能简单.[_Min][_Max]指出枚举的最小值和最大值(可以再次调整它,但是现在让我们保持简单).你声明它们都能够迭代你的EList.

ToString()method返回Enum的String表示形式.任何VBA开发人员都会在某种程度上意识到VBA太糟糕了,因为它是一个内置功能.无论如何,你现在有了自己的实现.

Exists获取任何userInput商店,同时迭代Enum EList匹配您的Enum的String表示.这是一种矫枉过正,因为你需要调用许多方法并循环遍历枚举,以便能够一次性实现简单DictionaryExists方法.这主要是为什么我不建议您使用Enums来解决您的具体问题.

然后最后你有了Mainsub,它只是收集用户的输入并调用Exists方法.它示出了具有任一消息框truefalse其指示如果String存在作为Enum类型.

  • mehow,我错过了什么,或者你的'不存在:`是奇怪的?如果字典中不存在用户输入,`myList.Exists(userInput)`只返回`false`并且没有触发错误 (2认同)
  • @SchwitJanwityanujit http://www.experts-exchange.com/Software/Office_Productivity/Office_Suites/MS_Office/A_3391-Using-the-Dictionary-Class-in-VBA.html (2认同)

bre*_*tdj 7

您可以在下面运行一个简单的数组测试,将单词添加到单个列表中:

Sub Main1()
arrList = Array("cat", "dog", "dogfish", "mouse")
Debug.Print "dog", Test("dog")   'True
Debug.Print "horse", Test("horse") 'False
End Sub

Function Test(strIn As String) As Boolean
Test = Not (IsError(Application.Match(strIn, arrList, 0)))
End Function
Run Code Online (Sandbox Code Playgroud)

或者,如果您想进行更详细的搜索并返回子字符串匹配列表以供进一步工作,请使用Filter.vFilter如果查找,此代码将返回以下内容dog

狗,鲨鱼

在这种特殊情况下,代码然后检查完​​全匹配dog.

Sub Main2()
arrList = Array("cat", "dog", "dogfish", "mouse")
Debug.Print "dog", Test1("dog")
Debug.Print "horse", Test1("horse")
End Sub

Function Test1(strIn As String) As Boolean
Dim vFilter
Dim lngCnt As Long
vFilter = Filter(arrList, strIn, True)
For lngCnt = 0 To UBound(vFilter)
    If vFilter(lngCnt) = strIn Then
        Test1 = True
        Exit For
    End If
Next
End Function
Run Code Online (Sandbox Code Playgroud)

  • 很好的答案,但为时已晚 - 我已经手动将大约100个项目添加到字典中:(.当然,除了所有的手动工作之外,解决方案并没有出现任何问题. (2认同)

小智 6

Select Case只需将与列表一起使用:

Select Case entry
   Case item1,item2, ite3,item4 ' add up to limit for Case, add more Case if limit exceeded
      do stuff for being in the list
   Case Else
      do stuff for not being in list
End Select
Run Code Online (Sandbox Code Playgroud)

  • 这并没有提供问题的答案。要批评或要求作者澄清,请在他们的帖子下方发表评论 - 您可以随时对自己的帖子发表评论,一旦您拥有足够的[声誉](http://stackoverflow.com/help/whats-reputation),您就会能够[对任何帖子发表评论](http://stackoverflow.com/help/privileges/comment)。 (2认同)