Instead of typing up a bunch of “Or” statements, how can I implement a function in this code?

前端 未结 3 537
攒了一身酷
攒了一身酷 2021-01-20 17:55
Sub test()

Dim DataRange As Range
Dim LastRow As Integer
Dim i As Integer
Dim SplitVal() As String
Dim OutputOffset As Long
OutputOffset = 0

LastRow = Cells(Rows.C         


        
3条回答
  •  北荒
    北荒 (楼主)
    2021-01-20 18:14

    That's a concern of its own; it belongs in its own scope. I use a function like this for short-circuiting otherwise redundant conditions - ParamArray is the secret sauce here:

    Public Function MatchesAny(ByVal needle As String, ParamArray haystack() As Variant) As Boolean
    
        Dim i As Integer
        Dim found As Boolean
    
        For i = LBound(haystack) To UBound(haystack)
            found = (needle = CStr(haystack(i)))            
            If found Then Exit For
        Next
    
        MatchesAny = found
    
    End Function
    

    That would be used like this:

    If MatchesAny(CStr(ActiveSheet.Cells(i, 10).Value), _
        "Test1", "Test2", "Test3", "Test4", "Test5", _
        "Test6", "Test7", "Test8", "Test9", "Test10", _
        "Test11", "Test12", "Test13", ..., "Test50") _
    Then
        'match was found
    End If
    

    You can quite easily tweak the haystack to support passing a 1D array of values like @Jeeped's answer; the principle is the same: bail out as soon as you know your result; your current code will execute every single InStr statement, even if the first Boolean expression to be evaluated is True.

    That function returns True if any item matches the specified string. Sometimes you might need a function that returns True if any item contains the specified string. That's another function:

    Public Function ContainsAny(ByVal needle As String, ByVal caseSensitive As Boolean, ParamArray haystack() As Variant) As Boolean
    
        Dim i As Integer
        Dim found As Boolean
    
        For i = LBound(haystack) To UBound(haystack)
            found = Contains(needle, CStr(haystack(i)), caseSensitive)            
            If found Then Exit For
        Next
    
        ContainsAny = found
    
    End Function
    

    This one calls a simple wrapper function around InStr, which helps improve the readability of InStr() <> 0 calls:

    Public Function Contains(ByVal needle As String, ByVal haystack As String, Optional ByVal caseSensitive As Boolean = False) As Boolean
    
        Dim compareMethod As VbCompareMethod
    
        If caseSensitive Then
            compareMethod = vbBinaryCompare
        Else
            compareMethod = vbTextCompare
        End If
    
        Contains = (InStr(1, haystack, needle, compareMethod) <> 0)
    
    End Function
    

    Usage of that one is similar, except we have a caseSensitive parameter that needs to be specified (you might want to tweak MatchesAny to have a similar signature) before the list of arguments. Again, same principle: bail out as soon as you know what to return.

提交回复
热议问题