Как использовать Unique между несколькими столбцами, не считая определенных разделителей? - PullRequest
0 голосов
/ 21 марта 2020

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

e

Есть ли способ изменить уникальную функцию (или любую другую) в Чтобы автоматически создать один из приведенных ниже списков (выделение по-прежнему выполняется вручную)? «N / A» могут быть заменены пустыми пробелами (как некоторые из ящиков, в которые я их не помещал).

enter image description here

Ответы [ 2 ]

1 голос
/ 21 марта 2020

РЕДАКТИРОВАТЬ: После некоторого обсуждения в чате, обнаружив, что @AlecAlameddine получает сообщения об ошибках с формулами, которые работают в других местах, представляется вероятным, что размер данных, наряду с необходимыми space замен, приводит к формулам, которые длиннее 32,767, что является ограничением, если я правильно помню, не только TEXTJOIN, но также SUBSTITUTE

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

Функция UDF не ограничена теми же ограничениями по размеру, что и формулы рабочего листа.

Это вернет вертикальный массив, который будет Spill Down как любой динамический c массив.

  • Чтобы войти в эту пользовательскую функцию (UDF), alt-F11 откроет Visual Basi c Редактор.
  • Убедитесь, что ваш проект выделен в окне Project Explorer.
  • Затем в верхнем меню выберите Вставить / Модуль и вставьте приведенный ниже код в открывшееся окно.
Option Explicit
Function Singers(rg As Range) As Variant()
    Dim COL As Collection
    Dim vSrc As Variant, vRes As Variant
    Dim v, w, x, I As Long

Set COL = New Collection

'Create array for the values
vSrc = rg

'Filter uniques into a collection object

On Error Resume Next 'allows collection to skip any duplicates without errors
For Each v In vSrc

    'split the "+"'s
    w = Split(v, "+")

    'Trim & Remove the "N/A"'s and add to dictionary
    For Each x In w
        If Trim(x) <> "N/A" Then
            COL.Add Trim(x), Trim(x)
        End If
    Next x
Next v

On Error GoTo 0

'create results array
ReDim vRes(1 To COL.Count, 1 To 1)
For I = 1 To COL.Count
    vRes(I, 1) = COL(I)
Next I

'Transfer array to output of the function
Singers = vRes

End Function
  • Чтобы использовать эту пользовательскую функцию (UDF), введите формулу, например =singers(Songs), в какую-нибудь ячейку

Предыдущие формулы, которые не будет работать с большими данными, но будет работать с маленькими данными

Вы можете сделать это с помощью функций TEXTJOIN и FILTERXML. VBA не требуется:

TEXTJOIN создаст одну строку из многоколоночного массива. FILTERXML вернет каждый уникальный узел, а также отфильтрует N/A

=UNIQUE(FILTERXML("<t><s>"&TEXTJOIN("</s><s>",TRUE,  SUBSTITUTE(myRange,"+","</s><s>"))&"</s></t>","//s[not(.='N/A')]"))

. От вашего вопроса я не уверен, если вы просто хотите отфильтровать N/A, или фактически заменить их пробелами.

Примечание: Хотя мы можем создать аргумент XPATH для возврата уникального списка узлов из-за пробелов в начале / конце, когда мы замените +, они не будут считаться уникальными FILTERXML. Поскольку возвращаемое значение из FILTERXML обрезается, мы можем применить функцию UNIQUE в этой точке

enter image description here

Если вы иметь MA C и не иметь функции FILTERXML, вы можете использовать это:

=UNIQUE(TRIM(MID(SUBSTITUTE(SUBSTITUTE(TEXTJOIN(REPT(" ",99),TRUE,myRange),"+",REPT(" ",99)),"N/A",""),SEQ_99,99)))

, где SEQ_99 является именованной формулой и относится к:

=IF(ROW(INDEX($A:$A,1,1):INDEX($A:$A,99,1))=1,1,(ROW(INDEX($A:$A,1,1):INDEX($A:$A,99,1))-1)*99)

Эта формула заменяет N/A пробелом.

Если вы предпочитаете не показывать пробел, сначала удалите N / A:

=UNIQUE(TRIM(MID(SUBSTITUTE(SUBSTITUTE(TEXTJOIN(REPT(" ",99),TRUE,SUBSTITUTE(myRange,"N/A","")),"+",REPT(" ",99)),"N/A",""),SEQ_99,99)))

Примечание: Как написано, предметы возвращаются row by row. Если вы предпочитаете, чтобы они вернули column by column, просто перенесите диапазон: замените myRange на TRANSPOSE (myRange) `

0 голосов
/ 21 марта 2020

Как вы знаете, если вы используете UNIQUE() в блоке ячеек, он возвращает другой блок, а не один столбец.

Эта крошечная пользовательская функция:

Public Function Block2Column(rng As Range) As Variant
    Dim arr, OneCol(), cnt As Long, a

    arr = rng.Value
    cnt = rng.Count
    ReDim OneCol(1 To cnt, 1 To 1)
    i = 1

    For Each a In arr
        OneCol(i, 1) = a
        i = i + 1
    Next a
    Block2Column = OneCol
End Function

вернет выделение из одного столбца из блока ячеек. Вот пример его использования:

enter image description here

РЕДАКТИРОВАТЬ # 1:

Для дальнейшей обработки списка , используйте FILTER(). Таким образом, вы можете удалить записи + , записи N / A и любые пробелы. Как:

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