Хранить переменные условия VBA в ячейке - PullRequest
0 голосов
/ 10 октября 2019

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

Для тривиального примера того, что я пытаюсь сделать, приведу простой код:

Dim result As Boolean
Dim var1 as integer
Dim rule As string
rule = "(var1 = 3)"
var1 = getthisfromsomewhere()

'How to evaluate the rule?
result = ????(rule)

По сути, я хочу оценить строку, которая, если бы она была в операторе if, вернула бы значение true или false.

Я видел функцию Evaluate (), но, похоже, она работает с ячейками, а не сПеременные VBA. Итак, можно ли это сделать?

[Объяснение цели: я, к сожалению, обязан использовать VBA для этого проекта, хотя он не идеален. Мы хотим, чтобы правила были редактируемыми, не вдаваясь в сам код VBA. В основном у нас будет лист с именем ПРАВИЛА, в столбце А которого будет код для оценки, если он истинен. А в столбце B поместите строку в журнал, если результат при оценке столбца A равен true. Код VBA имеет десятки, может быть, пару сотен переменных. Список правил будет от десятков до нескольких сотен правил. Правила время от времени меняются, поэтому мы должны обновить список правил. Правило может быть произвольным логическим выражением, составленным из этих переменных. ((var1 = 1) и (var2 = 2) и (var3 = 3)) является допустимым правилом, предполагая, что var1, var2 и var3 определены в коде VBA.]

1 Ответ

0 голосов
/ 11 октября 2019

Хорошо, поэтому, углубляясь в это, я думаю, что у меня есть решение, я просто сделал базовый пример, иначе это заняло бы у меня весь день.

Для этого есть три "части": лист для хранения правил, форма для создания правил и класс для оценки правил.

Вот форма:

enter image description here

Я ленивый и не дал ему настоящее имя, или не добавил метки, но суть в том, что они выбирают переменную и оператор, а затем вводят значение,После этого они регистрируют правило, оно отправляется на лист для хранения там. (Я никак не мог их изменить, но это должно быть довольно просто.)

Когда у них есть правила, они оценивают их все.

Код для формы:

Option Explicit

Private Sub Cmd_LogRules_Click()
    'Log the rules
    Dim lr As Long

    With ThisWorkbook.Sheets(1)
        lr = .Cells(.Rows.Count, 1).End(xlUp).Row
        .Cells(lr + 1, 1).value = ComboBox1.value & " " & ComboBox2.value & " " & TextBox1.value
    End With
End Sub

Private Sub Cmd_Evaluate_Click()
    'Execute rules
    Dim ruledict As Object
    Dim vardict As Object
    Dim lr As Long
    Dim i As Long
    Dim ruleclass As Class1
    Dim rulesplit As Variant
    Set vardict = load_vardict()
    Set ruledict = CreateObject("Scripting.Dictionary")
    'Not sure if you need the ruledict but I'm not sure how elaborate this needs to be and will be helpful probably
    With ThisWorkbook.Sheets(1)
        lr = .Cells(.Rows.Count, 1).End(xlUp).Row
        For i = 1 To lr
            Set ruleclass = New Class1
            rulesplit = Split(.Cells(i, 1).value, " ")
            ruleclass.load rulesplit(1), rulesplit(2)
            ruledict.Add rulesplit(0), ruleclass
            .Cells(i, 2).value = ruleclass.evaluate_rule(vardict(rulesplit(0)))
        Next
    End With
End Sub
Private Function load_vardict() As Object
    'Not sure where you are getting the real variable values but they are being stored in this dictionary
    Dim tempdict As Object

    Set tempdict = CreateObject("Scripting.Dictionary")

    tempdict.Add "var1", 2
    tempdict.Add "var2", 4
    tempdict.Add "var3", 6

    Set load_vardict = tempdict

End Function
Private Sub UserForm_Initialize()
    'Add any additional variables/operators you need
    With ComboBox1
        .AddItem "Var1"
        .AddItem "Var2"
        .AddItem "Var3"
    End With

    With ComboBox2
        .AddItem "="
        .AddItem "<>"
    End With

End Sub

Вот журнал:

enter image description here

А воткод класса:

Option Explicit

Private pOperator As String
Private pValue As Variant

Public Sub load(ByVal op As String, ByVal val As Variant)
    'Parameters are byval because it was yelling at me, there's probably a way to make them byref and have it accept them.
    'You might not need a class but if it gets more complicated it will be helpful
    pOperator = op
    pValue = val

End Sub

Public Function evaluate_rule(value As Long) As Boolean
    'Select case for operators, there might be a more clever way of doing this...
    Select Case pOperator
        Case "="
            If value = pValue Then
                evaluate_rule = True
            Else
                evaluate_rule = False
            End If
        Case "<>"
            If value <> pValue Then
                evaluate_rule = True
            Else
                evaluate_rule = False
            End If
        End Select
End Function

В этом коде есть некоторые ненужные вещи, например, словарь правил, но я думаю, что они будут вам полезны, поэтому я добавил их.

РЕДАКТИРОВАТЬ: я думаю, суть в том, чтобы использовать словарь, где ключ является «переменная», а элемент является правилом. Хотя я все еще думаю, что форма - это хорошая идея, чтобы содержать все в чистоте.

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