简体   繁体   English

如何在VBA Excel UDF参数中使用比较运算符?

[英]How to use comparison operators in VBA Excel UDF arguments?

How would i write UDF so they accept comparison operators in arguments? 我如何编写UDF以便它们接受参数中的比较运算符?

When using standard functions you write like this =countif(range;x) and you would get the number of cells in the range that equals x. 当你使用标准函数时,你会像这样写= countif(range; x) ,你会得到等于x的范围内的单元格数。

Replicating this function in VBA would look something like this: 在VBA中复制此函数看起来像这样:

Function countifUDF(rng As Range, x As Integer)
    count = 0
    For Each cell in rng.Cells
        If cell.Value = x Then
            count = count + 1
        Next cell
    countifUDF = sum
End Function

When using the standard function you can pass a comparison operator to the function like this =countif(range;"<"&x) and you would get the number of cells in the range less than x. 使用标准函数时,您可以将比较运算符传递给函数,如this = countif(range;“<”&x) ,您将得到小于x的单元格数。

How could i do this in an UDF? 我怎么能在UDF中这样做? My UDF as =countifUDF(range;"<"&x) yields #VALUE 我的UDF as = countifUDF(范围;“<”和x)产生#VALUE


SOLUTION

Function countifUDF(rng As Range, x As String)
Dim arr() As String
Dim count As Integer
Dim i As Integer

' breaking down x character by character and puts in array
ReDim arr(Len(x) - 1)
For i = 1 To Len(x)
    arr(i - 1) = Mid$(x, i, 1)
Next

' if the last character in x is not numeric i assume the user want to count matching strings
' Like allows the user to use wildcards, LCase makes the comparision case insensitive
If IsNumeric(arr(UBound(arr))) = False Then
    x = LCase(x)

    For Each cell In rng.Cells
        If LCase(cell.Value) Like x Then
            count = count + 1
        End If
    Next cell

' if the first char in x is numeric its pretty straight forward
ElseIf IsNumeric(arr(0)) = True Then
    For Each cell In rng.Cells
        If cell.Value = x Then
            count = count + 1
        End If
    Next cell

' if the first character in x is < and the second is numeric less-than operator is used
ElseIf arr(0) = "<" And IsNumeric(arr(1)) = True Then
    ' removing < from x
    x = Replace(x, "<", "")
    For Each cell In rng.Cells
        If cell.Value < x Then
            count = count + 1
        End If
    Next cell

ElseIf arr(0) = ">" And IsNumeric(arr(1)) = True Then
    x = Replace(x, ">", "")
    For Each cell In rng.Cells
        If cell.Value > x Then
            count = count + 1
        End If
    Next cell

' if the first char is < and the second is > the is not operator is used
ElseIf arr(0) = "<" And arr(1) = ">" Then
    x = Replace(x, "<", "")
    x = Replace(x, ">", "")
    For Each cell In rng.Cells
        If cell.Value <> x Then
            count = count + 1
        End If
    Next cell

ElseIf arr(0) = ">" And arr(1) = "=" Then
    x = Replace(x, ">", "")
    x = Replace(x, "=", "")
    For Each cell In rng.Cells
        If cell.Value >= x Then
            count = count + 1
        End If
    Next cell

ElseIf arr(0) = "<" And arr(1) = "=" Then
    x = Replace(x, "<", "")
    x = Replace(x, "=", "")
    For Each cell In rng.Cells
        If cell.Value <= x Then
            count = count + 1
        End If
    Next cell

End If

countifUDF = count

End Function

Given the answers i got it seems like theres no convenient way in VBA of handling comparison operators in UDF, please correct me if i'm wrong. 鉴于我得到的答案似乎在VBA中处理UDF中的比较运算符并不方便,如果我错了请纠正我。 My solution supports both numbers and strings with wildcards. 我的解决方案通过通配符支持数字和字符串。 At first i tried to use the Split-method with & as delimiter. 起初我尝试使用带有&作为分隔符的Split方法。 Appearantly VBA identifies '">"&x' as '>x' why i had to split x character by character and evaluate what kind of comparison operator the user typed in. 外观上VBA将'“>”&x'标识为'> x'为什么我必须按字符分割x并评估用户键入的比较运算符类型。

Have the UDF() consider the second argument as a String : UDF()将第二个参数视为String

Function countifUDF(rng As Range, x As Variant) As Long
    Dim cell As Range, Count As Long, CH As String, VL As Long

    VL = Replace(Replace(x, ">", ""), "<", "")
    CH = Left(CStr(x), 1)
    Count = 0

    If CH = ">" Then
        For Each cell In rng.Cells
            If cell.Value > VL Then
                Count = Count + 1
            End If
        Next cell
    ElseIf CH = "<" Then
        For Each cell In rng.Cells
            If cell.Value < VL Then
                Count = Count + 1
            End If
        Next cell
    Else
        For Each cell In rng.Cells
            If cell.Value = x Then
                Count = Count + 1
            End If
        Next cell
    End If
    countifUDF = Count
End Function

In this example, CH is the first character of the second argument and VL is the numeric part of the second argument. 在此示例中, CH是第二个参数的第一个字符, VL是第二个参数的数字部分。

Try this: 尝试这个:

Function countifUDF(rng As Range, x As Integer)
    Dim cell As Range
    Dim Count As Integer

    Count = 0
    For Each cell In rng.Cells
        If cell.Value < x Then Count = Count + 1
    Next cell

    countifUDF = Count

End Function

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM