2013-09-25 3 views
0

Я хочу дать пользователю возможность добавлять некоторые правила IF в мой код через форму пользователя, а затем запускает программу. правила являются чем-то вроде этого:Добавить правила IF, используя форму пользователя в excel vba

If Xarray(i,j-1)= "X" and Xarray(i,j+1)= "Y" Then Xarray(i,j)= "Z" 

Где «X», «Y» и «Z» являются текстовые поля, которые заполняются с пользователем, используя пользовательскую форму, и есть «Добавить правило» кнопку, когда пользователь нажимает на это, правило будет добавлено в код программно. Позже я могу расширить правила до более сложных правил. Мой вопрос в том, как я могу создать такую ​​процедуру для Excel VBA?

Спасибо.

Вот пример:

у нас есть форма пользователя, который имеет три Text-Boxes и один кнопку "Добавить" Rule. Я создал этот образец кода:

Private Sub UserForm_Initialize() 

    Dim LeftCell As String, RightCell As String, CenterCell As String 
    Dim iRule As String 

    UserForm1.Show 
    LeftCell = txtLeft.Text 
    CenterCell = txtCenter.Text 
    RightCell = txtRight.Text 

    iRule = "If " & "Xarr(I, J - 1) = " & LeftCell & " And" & " Xarr(I, J + 1) = " & RightCell & " Then" & Chr(10) & _ 
      " Xarr(I, J) = " & CenterCell & Chr(10) & _ 
      "End If" 

    MsgBox iRule 
End Sub 

Проблема заключается в том, что как я могу использовать iRule (который является строкой) как «Оператор IF» в моем основном коде.

+2

Что ваш вопрос? –

+1

Трудно сказать, в чем проблема. Почему бы вам не попытаться реализовать это правило и не пересмотреть свой вопрос, если у вас есть проблемы или ошибки? –

ответ

1

Предлагаю использовать двумерный массив «правил». Когда пользователь добавляет правило, информация, такая как тип правила (равенство, неравенство) и параметры, подлежащие тестированию, будет введена в массив. Наконец, когда выполняется проверка, вы можете использовать параметры внутри оператора if..then внутри цикла для проверки всех элементов массива. Если все правила объединены с ИО, то вы можете установить логическую переменную в false и выйти из цикла. Если вам нужна дополнительная информация или пример кода, отправьте пробный код, над которым я могу работать.

Редактировать с кодом:

Я сделал класс, который вы можете использовать для этой цели:

Option Explicit 

'Class Parameters 
Dim pRules() As Variant 'note the variant data type 
Dim pCountRules As Long 

Private Sub class_initialize() 
    pCountRules = 0 
End Sub 

Public Sub AddRule(Parameter As Variant, Condition As Variant) 
'note the variant data types 
    If TypeName(Parameter) <> TypeName(Condition) Then 
     'one possible exception I can think of, handle this here 
     Exit Sub 
    End If 
    If pCountRules = 0 Then 
     pCountRules = 1 
     ReDim pRules(1 To 2, 1 To 1) 
     pRules(1, 1) = Parameter 
     pRules(2, 1) = Condition 
    Else 
     pCountRules = pCountRules + 1 
     ReDim Preserve pRules(1 To 2, 1 To pCountRules) 
     pRules(1, pCountRules) = Parameter 
     pRules(2, pCountRules) = Condition 
    End If 
End Sub 

Public Sub ResetRules() 
    Erase pRules 
    pCountRules = 0 
End Sub 

Public Function CheckRules() As Boolean 
Dim i As Integer 
    If pCountRules = 0 Then 
     CheckRules = True 'or false, depends on your logic 
    Else 
     CheckRules = True 
     For i = 1 To pCountRules 
      If pRules(1, i) <> pRules(2, i) Then 
       CheckRules = False 
       Exit For 
      End If 
     Next i 
    End If 
End Function 

Private Sub Class_Terminate() 
    Erase pRules 
End Sub 

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

Option Explicit 

Sub test() 
Dim Rules As clsRules 
Dim testarr(1 To 1, 1 To 3) As String 
Dim testparam(1 To 3) As String 
    testarr(1, 1) = "a" 
    testarr(1, 2) = "b" 
    testarr(1, 3) = "c" 
    testparam(1) = "a" 
    testparam(2) = "b" 
    testparam(3) = "c" 
    'values match 
    Set Rules = New clsRules 
    Rules.AddRule testarr(1, 1), testparam(1) 
    Rules.AddRule testarr(1, 2), testparam(2) 
    Rules.AddRule testarr(1, 3), testparam(3) 
    'will print true 
    Debug.Print Rules.CheckRules 

    'change parameter so values do not match 
    testparam(3) = "a" 
    Rules.ResetRules 
    Rules.AddRule testarr(1, 1), testparam(1) 
    Rules.AddRule testarr(1, 2), testparam(2) 
    Rules.AddRule testarr(1, 3), testparam(3) 
    'will print false 
    Debug.Print Rules.CheckRules 

    'clean up 
    Erase testarr 
    Erase testparam 
    Set Rules = Nothing 
End Sub 

Надеюсь, это будет полезно для вас.

+0

Я отредактировал вопрос на примере. – Bruce

+0

Я добавил код. – Teeracroptus

+0

большое спасибо. Это очень близко к тому, что мне нужно, тогда у меня есть вопрос. Если я хочу повторить процесс каждый раз, когда пользователь нажимает кнопку AddRule и сохраняет число pCountrules для использования в следующий раз, то каково это решение? постскриптум Я даю имя каждый раз, когда пользователь добавляет правило, нажав на кнопку. – Bruce

0

Один из способов я могу думать о том, чтобы создать подпрограмму в новом модуле с вашей строки (код, который вы хотите выполнить) и запустить эту подпрограмму

Смежные вопросы