Новичок в VBA, и я пытаюсь создать функцию - PullRequest
0 голосов
/ 10 января 2019

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

Я пробовал VBA и использую приведенную выше формулу как есть. Это неэффективно для больших наборов данных, с которыми я работаю.

=IF((AND(B2>=65,A2>=7)),"Greenbox",IF((AND(B2>10,A2=0,B2= "")),"Balance",IF((AND(B2>=65,A2<3)),"Yellowbox",IF((AND(B2<65,A2>=7)),"Purplebox",IF((AND(B2<65,A2<=3,A2>=1)),"Orangebox",IF(AND(B2>=65,A2<7,A2>=3),"Bluebox",IF(AND(A2<7,A2>=3,B2<65),"Redbox")))))))

Функция VBA, имитирующая формулу.

Ответы [ 3 ]

0 голосов
/ 10 января 2019

Вот и все. Total - это значение, возвращаемое в ячейке с вызванной функцией. Это будет ячейка a2 и B будет ячейка b2 в примере = CaseTest (А2, В2)

Согласно примечанию Скотта, <10 используется, а не ноль. Не стесняйтесь редактировать. </p>

Существует также значение по умолчанию, если не выполняется ни одно из условий. Удачного кодирования.

Function caseTest(A, B)

Dim scoreA As Integer, scoreB As Integer, result As String
    scoreA = A.Value
scoreB = B.Value

If ((scoreA >= 7) And (scoreB >= 65)) Then
    Total = "Greenbox"
ElseIf ((scoreA = 0) And (scoreB <10)) Then
    Total = "Balance"
ElseIf ((scoreA < 3) And (scoreB >= 65)) Then
    Total = "Yellowbox"
ElseIf ((scoreA >= 7) And (scoreB < 65)) Then
    Total = "Purplebox"
ElseIf ((scoreA <= 3) And (scoreA >= 1) And (scoreB < 65)) Then
    Total = "Orangebox"
ElseIf ((scoreA >= 3) And (scoreA < 7) And (scoreB >= 65))) Then
    Total = "Bluebox"
ElseIf ((scoreA >= 3) And (scoreA < 7) And (scoreB < 65))) Then
    Total = "Redbox"
Else
    Total = "default"
End If
    caseTest = Total
End Function
0 голосов
/ 10 января 2019

если вам нужна помощь по созданию пользовательских функций, ссылка ниже - полезное руководство https://support.office.com/en-us/article/create-custom-functions-in-excel-2f06c10b-3622-40d6-a1b2-b6748ae8231f.

Чтобы ответить на ваш вопрос, я создал пользовательскую функцию, основанную на том, что я расшифровал из вашей формулы.

Function Cust_SetBox(A as Range, B as Range) As String
'function will receive two parameters A and B as ranges and return back a string
   Application.Volatile 'this ensures that formula will update when cell values are modified

   'Original formula
   '=IF((AND(B2>=65,A2>=7)),"Greenbox",IF((AND(B2>10,A2=0,B2= "")),"Balance",IF((AND(B2>=65,A2<3)),"Yellowbox",IF((AND(B2<65,A2>=7)),"Purplebox",IF((AND(B2<65,A2<=3,A2>=1)),"Orangebox",
   'IF(AND(B2>=65,A2<7,A2>=3),"Bluebox",IF(AND(A2<7,A2>=3,B2<65),"Redbox")))))))

   'adding .value="" condition as emtpy cells will show up as true while checking for X.Value<n
   If B.Value = "" And A.Value = "" Then
       Cust_SetBox = "Unknown"
   ElseIf (B.Value = "" Or B.Value > 10) And A.Value = 0 Then 'you might want to check this condition as it is not clear from your formula
       Cust_SetBox = "Balance"
   ElseIf B.Value >= 65 And B.Value <> "" Then
       If A.Value >= 7 Then
           Cust_SetBox = "Greenbox"
       ElseIf A.Value < 3 Then
           Cust_SetBox = "Yellowbox"
       ElseIf A.Value < 7 And A.Value >= 3 Then
           Cust_SetBox = "Bluebox"
       End If
   ElseIf B.Value < 65 And B.Value <> "" Then
       If A.Value >= 7 Then
           Cust_SetBox = "Purplebox"
       ElseIf A.Value <= 3 And A.Value >= 1 Then
           Cust_SetBox = "Orangebox"
       ElseIf A.Value < 7 And A.Value >= 3 Then
           Cust_SetBox = "Redbox"
       End If
   Else
       Cust_SetBox = "Unknown"
   End If



End Function
Чтобы быстро добавить эту функцию в вашу книгу. используйте Alt + F11, вставьте новый модуль и добавьте приведенный выше код к модулю. Вы должны быть в состоянии использовать эту новую функцию в качестве формулы. Перейдите в любую ячейку и введите ниже = Cust_SetBox (A1, B1) Ячейка покажет значение на основе логики выше. Подробное объяснение в ссылке выше.

Примечание

Убедитесь, что Расчет установлен для автоматического расчета (в меню Формулы -> Параметры расчета), иначе нажмите F9 для расчета

Рабочая книга должна быть сохранена в виде файла с поддержкой макросов, иначе функция будет недоступна позже.

0 голосов
/ 10 января 2019

Если вы не хотите вводить данные в UDF, вы можете получить номер строки и рабочий лист, используя Application.Caller. В противном случае вы можете добавить два аргумента для диапазона A2 & B2 и сравнить там значение.

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

Application.Caller Method

Function myFunc() As String

    Dim r As Long, ws As Worksheet
    Set ws = Application.Caller.Worksheet
    r = Application.Caller.Row

    If ws.Cells(r, "B").Value >= 65 And ws.Cells(r, "A").Value >= 7 Then
        myFunc = "Greenbox"
    ElseIf ws.Cells(r, "B").Value > 10 And ws.Cells(r, "A").Value = 0 Then
        myFunc = "Balance"
    '.... Continue
    End If

End Function

Как будет выглядеть формула листа: =myFunc(). (аргументы не нужны)


Функция с методом аргументов

Function myFunc(rngA As Range, rngB As Range) As String

    If rngB.Value >= 65 And rngA.Value >= 7 Then
        myFunc = "Greenbox"
    ElseIf rngB.Value > 10 And rngA.Value = 0 Then
        myFunc = "Balance"
    '.... Continue
    End If

End Function

Как будет выглядеть формула листа: =myFunc($A2, $B2).

Как уже упоминалось в комментариях Скотта Крейнера, AND(B2>10,A2=0,B2= "") не является логически правильным. B2>10 и B2="" никогда не будут True при использовании вместе с AND, поэтому вам, возможно, придется выяснить свои намерения с этим.

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