РЕДАКТИРОВАТЬ: После некоторого обсуждения в чате, обнаружив, что @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
в этой точке
Если вы иметь 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) `