如何从单元格中读取比较运算符并在If ... Then ... Else语句中使用它?

时间:2011-02-23 23:34:24

标签: excel vba excel-vba

我在MSDN上搜索过,找不到任何有关此内容的信息。我有一个控制我的应用程序的“设置”表。此工作表具有一系列单元格,用于存储比较运算符,例如< =和>用于手术。

我有一份水果清单和每种水果销售价格的清单。我想看看有多少苹果以低于或等于10美元的价格出售。

我的程序的先前版本使用了WorksheetFunction.CountIfs方法,它基本上将工作表中的运算符读入数组并使用它们:

Sub BuiltInCountIfsUsingArray()

    Dim rngOperator As Range
    Dim avOperator As Variant

    Set rngOperator = [A1:B1]

    avOperator = rngOperator

    With WorksheetFunction
        lResult = .CountIfs(rngFruits, _
            avOperator(1, 1) & "apple", _
            rngPrice, _
            avOperator(1, 2) & 10)
    End With

End Sub

从A1读取avOperator(1,1),其中包含=

从B1读取avOperator(1,2),其中包含< =

所以在VBA中,

avOperator(1,1)返回值“=”

avOperator(1,2)返回值“< =”

所以上面的代码相当于:

Sub BuiltInCountIfs()

    With WorksheetFunction
        lResult = .CountIfs(rngFruits, _
            "=" & "apple", _
            rngPrice, _
            "<=" & 10)
    End With

End Sub

并且CountIfs函数可以正常工作。

我的问题是:如何使用相同类型的存储比较运算符的方法,然后在If ... Then ... Else语句中使用它们?

基本上,我想从此开始:

Sub MyCountIfs()

    Dim lRow As Long
    Dim lCounter As Long
    Dim lResult As Long

    For lRow = 1 To 10
        If rngFruits(lRow, 1) = "apple" _
            And rngPrices(lRow, 1) <= 10 Then

            lCounter = lCounter + 1

        End If
    Next lRow

    lResult = lCounter

End Sub

这样的事情:

Sub MyCountIfsUsingArray()

    Dim lRow As Long
    Dim lCounter As Long
    Dim lResult As Long

    Dim rngOperator As Range
    Dim avOperator As Variant

    Set rngOperator = [A1:B1]

    avOperator = rngOperator

    For lRow = 1 To 10
        If rngFruits(lRow, 1) & avOperator(1, 1) & "apple" _
            And rngPrices(lRow, 1) & avOperator(1, 2) & 10 Then

            lCounter = lCounter + 1

        End If
    Next lRow

    lResult = lCounter

End Sub

如果使用数组不可能,直接读取rngOperator也会很好。这样的事情可能是:

Sub MyCountIfsUsingRange()

    Dim lRow As Long
    Dim lCounter As Long
    Dim lResult As Long

    Dim rngOperator As Range
    Dim avOperator As Variant

    Set rngOperator = [A1:B1]

    For lRow = 1 To 10
        If rngFruits(lRow, 1) & rngOperator(1, 1) & "apple" _
            And rngPrices(lRow, 1) & rngOperator(1, 2) & 10 Then

            lCounter = lCounter + 1

        End If
    Next lRow

    lResult = lCounter

End Sub

提前致谢!

3 个答案:

答案 0 :(得分:0)

如果您包含对Microsoft Access x.x对象库的引用,则可以说:

    If Eval("'" & rngFruits(lRow, 1) & "'" & avOperator(1, 1) & "'apple' AND " _
         & rngPrices(lRow, 1) & avOperator(1, 2) & 10) Then

我不确定为什么excel没有Eval,但我正在测试早期版本,所以你可能希望查看。请注意,Evaluate根本不是一回事。我完全不确定这是个好主意,但它就在那里,FWIW。

答案 1 :(得分:0)

您可以编写自己的函数来执行此操作

这样的东西
Function CompareTest(v1 As Variant, Operator As String, v2 As Variant) As Boolean
    Select Case Operator
        Case "=": CompareTest = v1 = v2
        Case "<>": CompareTest = v1 <> v2
        Case ">": CompareTest = v1 > v2
        Case ">=": CompareTest = v1 >= v2
        Case "<": CompareTest = v1 < v2
        Case "<=": CompareTest = v1 <= v2
        Case <insert any other operator you may need> 
        Case Else: <handle the invalid operator case as you see fit>
    End Select
End Function

然后您的代码变为

For lRow = 1 To 10
    If CompareTest(rngFruits(lRow, 1), rngOperator(1, 1), "apple") And _
       CompareTest(rngPrices(lRow, 1), rngOperator(1, 2), 10) Then

        lCounter = lCounter + 1

    End If
Next lRow

答案 2 :(得分:0)

我刚刚意识到在循环中使用函数会破坏性能,因此我将在循环运行之前为每个运算符执行一个select case。谢谢你们,我感谢你们的努力,今天我学会了新的东西:)

我很蠢,我忘了提到第一个操作符总是“=”,所以用户只会指定第二个操作符。

Sub MyCountIfsUsingCases()

    Dim lRow As Long
    Dim lCounter As Long
    Dim lResult As Long

    Dim rngOperator As Range
    Dim avOperator As Variant

    Set rngOperator = [A1:B1]

    avOperator = rngOperator

    Select Case avOperator(1, 2)
        Case "<="
            For lRow = 1 To 10
                If rngFruits(lRow, 1) = "apple" _
                    And rngPrices(lRow, 1) <= 10 Then

                    lCounter = lCounter + 1

                End If
            Next lRow

        Case ">="
            For lRow = 1 To 10
                If rngFruits(lRow, 1) = "apple" _
                    And rngPrices(lRow, 1) >= 10 Then

                    lCounter = lCounter + 1

                End If
            Next lRow

        'Case "<", etc...

    End Select

    lResult = lCounter

End Sub