Попросите UDF выполнить count и "подсчитать" строку - PullRequest
0 голосов
/ 20 июня 2020

Я пытаюсь выполнить sh эту задачу с помощью пользовательской функции. В настоящее время я могу выполнить sh "оценку" с помощью вспомогательной строки и ячеек. Набор данных, который я пытаюсь реализовать, намного больше, чем изображение, которое у меня ниже, и между строками, которые я пытаюсь подсчитать, нет промежуточной вспомогательной строки.

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

  • Запах = 7
  • Пигмент = 6
  • AO = 5
  • M C = 4
  • PPA = 3
  • Antistat = 2
  • Если строка отсутствует в одной из приведенных выше таблиц, вернуть 1

Я выполняю это со вспомогательными ячейками, ячейка A3 выполняет следующую функцию: =IF(COUNTIF(Scent,A2)>0,7,IF(COUNTIF(Pigment,A2)>0,6,IF(COUNTIF(AO,A2)>0,5,IF(COUNTIF(MT,A2)>0,4,IF(COUNTIF(PPA,A2)>0,3,IF(COUNTIF(Antistat,A2)>0,2,1))))))

После того, как индивидуальная «оценка» выполнена. Затем я хочу вернуть наибольшее и второе наибольшее значение указанным способом c. наибольшее число . второе наибольшее число Ячейка G3 имеет этот результат как «7,5», потому что строка имеет совпадение по запаху и совпадение по AO. Он имеет следующую функцию: =VALUE(LARGE(A3:F3,1)&"."&LARGE(A3:F3,2))

Я никогда не создавал пользовательскую функцию, я не уверен, как это сделать sh. Выходные данные, которые у меня сейчас есть, находятся в диапазоне «A1: G5». Выходные данные, которые я пытаюсь достичь, находятся в диапазоне «A9: G11»

Реальный набор данных, для которого я пытаюсь использовать это, может иметь до 18 значений столбца в строке, но для простоты я пытаюсь заставить это работать только для 6 значений столбца. Я показал только 3 строки, но в реальном наборе данных может быть до 120 строк. Помимо 6 предопределенных таблиц, это число может go вверх или вниз. Меня это не беспокоит, потому что я не думаю, что это число изменится.

Итак, я предполагаю, что мой вопрос в том, как мне получить UDF для выполнения этого метода подсчета счетчиков для диапазона, который Даю это? Диапазон будет состоять из отдельных строк, которые я пытаюсь получить. Ниже приведен фрагмент моего рабочего листа. Спасибо всем за любую помощь или руководство! My current worksheet

папка github

1 Ответ

1 голос
/ 20 июня 2020

Попробуйте, пожалуйста, следующую функцию. Он использует именованные диапазоны, но код может быть легко адаптирован для использования таблиц (как я понял, ваш случай):

Function fScoresN(rng As Range) As String
  Dim arrT As Variant, arrFin() As Long, i As Long, arrInt As Variant, c As Range
  Dim boolFound As Boolean
  
  arrT = Split("Scent|7,Pigment|6,AO|5,MC|4,PPA|3,Antistat|2", ",")
  
  ReDim arrFin(1 To UBound(arrT) + 1)
  
  For i = 0 To UBound(arrT)
    arrInt = Split(arrT(i), "|")
    Debug.Print arrInt(0)
    For Each c In rng.Cells
        If WorksheetFunction.CountIf(Names(arrInt(0)).RefersToRange, c.Value) > 0 Then
            arrFin(i + 1) = arrInt(1): boolFound = True: Exit For
        End If
    Next
    If Not boolFound Then arrFin(i + 1) = 1
    boolFound = False
  Next i
  fScoresN = WorksheetFunction.Large(arrFin, 1) & "." & WorksheetFunction.Large(arrFin, 2)
End Function

Вы должны написать формулу =fscoresN(A3:F3) и нажать ввод

Пожалуйста, используйте следующие функции в случае использования имени таблиц:

Function fScoresT(rng As Range) As String
  Dim arrT As Variant, arrFin() As Long, i As Long, arrInt As Variant, c As Range
  Dim boolFound As Boolean
  
  arrT = Split("Scent|7,Pigment|6,AO|5,MC|4,PPA|3,Antistat|2", ",")
  If Not TablesExist(arrT) Then Exit Function 'check the tables name consistency
  ReDim arrFin(1 To UBound(arrT) + 1) 'redim the array to finally be evaluated
  
  For i = 0 To UBound(arrT)
    arrInt = Split(arrT(i), "|") 'split the array on "|" to obtain the name and its score
    Debug.Print arrInt(0) 'only to visually see what's happening. It must be commented after testings
    For Each c In rng.Cells
        If WorksheetFunction.CountIf(ActiveSheet.ListObjects(arrInt(0)).DataBodyRange, c.Value) > 0 Then
            arrFin(i + 1) = arrInt(1): boolFound = True: Exit For
        End If
    Next
    If Not boolFound Then arrFin(i + 1) = 1 'in case of no match 
    boolFound = False
  Next i
  fScoresT = WorksheetFunction.Large(arrFin, 1) & "." & WorksheetFunction.Large(arrFin, 2) 'concatenation between the two Large score returns
End Function

и функции для проверки имени таблиц:

Function TablesExist(arr As Variant) As Boolean
    Dim El As Variant, arrInt As Variant, T As ListObject, boolFound As Boolean
    For Each El In arr
        arrInt = Split(El, "|")
        For Each T In ActiveSheet.ListObjects
            If T.Name = arrInt(0) Then boolFound = True: Exit For
        Next
        If Not boolFound Then
            MsgBox "Table """ & arrInt(0) & """ does not exist, or it is wrongly spelled in arrT"
            TablesExist = False: Exit Function
        End If
        boolFound = False
    Next
    TablesExist = True
End Function

Вы должны написать формулу =fscoresT(A3:F3) и нажать введите

...