Как я могу прочитать оператор сравнения из ячейки и использовать его в операторе If ... Then ... Else? - PullRequest
1 голос
/ 24 февраля 2011

Я искал по всему 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

avOperator (1,1) читается из A1, который содержит =

avOperator (1,2) читается из B1, который содержит <= </p>

так в VBA,

avOperator (1,1) возвращает значение "="

avOperator (1,2) возвращает значение "<=" </p>

, поэтому приведенный выше код эквивалентен:

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 голосов
/ 24 февраля 2011

Вы можете написать свою собственную функцию для этого

Что-то вроде

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
0 голосов
/ 24 февраля 2011

Я только что понял, что использование функции в цикле разрушает производительность, поэтому я просто сделаю выбор для каждого оператора перед запуском цикла.спасибо, ребята, я ценю ваше время и усилия, и сегодня я узнал кое-что новоеодин.

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
0 голосов
/ 24 февраля 2011

Если вы включили ссылку на библиотеку объектов 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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...