Есть ли способ подсчитать количество символов в слове для строки, возвращая значения, разделенные запятой? - PullRequest
3 голосов
/ 02 ноября 2019

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

Например: 1. "Черная чашка с ручкой"> Формула мне нужна> 5,3,4,6

«Статуя гигантского медведя»> Формула, в которой я нуждаюсь> 5,4,6

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

Обычно мы считаем пространства и вложенные в слои формулы serach (), чтобы объединить их в одно и другое, чтобы разбитьструктура затем символ подсчитывает отдельные слова ...

В качестве альтернативы макрос мог бы заменить пробелы запятыми и использовать текст в столбцах, но это все равно оставляет мне длительный процесс подсчета того, что я ищу

мы, очевидно, используем =LEN(A1)-LEN(SUBSTITUTE(A1," ","")) для подсчета пробелов в слове

, в настоящее время мы затем используем функцию =SEACRH() в сочетании с функциями =MID() (и некоторыми причудливыми числами), чтобы раскрыть каждое слово в его собственноминдивидуальная ячейка

затем =LEN еще раз, но все отдельные слова - очень скучный

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

Ответы [ 3 ]

4 голосов
/ 02 ноября 2019

У вас будут разные параметры в зависимости от версии Excel.


ВАРИАНТ 1: TEXTJOIN

Я думаю,Вы ищете функцию TEXTJOIN. Только помните, что вы можете использовать эту более позднюю версию Excel (см. Ссылку на документацию), и она может работать так:

enter image description here

Формула в B1:

=TEXTJOIN(",",TRUE,LEN(FILTERXML("<t><s>"&SUBSTITUTE(A1," ","</s><s>")&"</s></t>","//s")))

ПРИМЕЧАНИЕ: Это формула массива, и вам нужно ввести ее, используя Ctrl Shift Введите

Чтобы сделать так, чтобы вам не нужно было использовать вышеуказанную комбинацию клавиш, мы можем включить INDEX:

=TEXTJOIN(",",TRUE,INDEX(LEN(FILTERXML("<t><s>"&SUBSTITUTE(A1," ","</s><s>")&"</s></t>","//s")),))

Дополнительная информация:

FILTERXML

Эта функция требует(согласно документации) два обязательных аргумента:

  • Строка в действительном XML
  • Строка в действительном XPath

Поскольку мы хотим вернуть массив элементов (слов) из ячейки, нам нужно SUBSTITUTE пробелы для концатеги (</..>) и объединить его с начальным тегом (<..>) в начале строки aи еще один конечный тег в конце.

Мне придется положиться на объяснение тегов XML относительно того, почему <?><?> работает и что это означает, потому что, насколько я могу, я смог протестироватьпоменяйте местами буквы или замените их другой буквой с теми же результатами, если последний символ Xpath будет напоминать тот же символ. Было бы здорово, если бы кто-то смог дополнить этот ответ более подробным объяснением по этому вопросу.


TEXTJOIN

Если вы являетесь подписчиком Office 365 или являетесь владельцем Excel 2019, вы можете использовать эту функцию. Существует (согласно документации) как минимум 3 обязательных аргумента:

  • Разделитель, который должен быть текстовой строкой, либо пустой, либо одним или несколькими символами, заключенными в двойные кавычки, или ссылкой на действительныйтекстовая строка. Если указано число, оно будет рассматриваться как текст.
  • Второй аргумент может содержать TRUE или FALSE и определяет, хотите ли вы исключить / включить пустые значения
  • Третий аргумент - это текстовый элемент, к которому нужно присоединиться. Текстовая строка или массив строк, например диапазон ячеек.

Теперь мы можем объединить две функции, FILTERXML, возвращая массив, который мы можем использовать в TEXTJOIN.


INDEX + LEN

I 'Придется объяснять использование этих функций вместе. Я не думаю, что LEN и INDEX понадобятся сами по себе, но вместе они работают очень хорошо. Собственно, будет сила, называемая неявным пересечением, которая не позволит LEN возвращать массив значений при передаче массива значений в функцию, в нашем случае через наш FILTERXML.

Обычно вы быотключите этот механизм, используя комбинацию клавиш: Ctrl Shift Введите , более известный как CSE.

Теперь то, что делает INDEX, отключает это неявное пересечение, делая LEN способным возвращать массив, устраняя необходимость CSE формулы. INDEX - это одна из функций, которая обладает этой «силой». Более подробное объяснение неявного пересечения можно найти здесь


ВАРИАНТ 2: UDF

Бездоступ к TEXTJOIN Я думаю, вам нужно взглянуть на UDF, возможно, как показано ниже:

Function TEXTJOIN(rng As Range) As String
    TEXTJOIN = Join(Application.Evaluate("LEN({""" & Join(Split(rng, " "), """,""") & """})"), ",")
End Function

Вы можете назвать это в B1 примерно так: =TEXTJOIN(A1)


Дополнительная информация:

UDF состоит из трех основных механизмов, которые работают вместе:

JOIN

Эта функция принимает два параметра, для которых требуется первый:

  • Первый параметр - это одномерный массив, содержащий подстроки
  • Второй (необязательный) параметр - это строковый символ, используемый для разделения подстрок в возвращаемой строке. Если опущен, используется пробел (""). Если разделитель является строкой нулевой длины (""), все элементы в списке объединяются без разделителей.

Функция возвращает строковое значение


SPLIT

Эта функция принимает строку и ограничивает ее указанным символом / подстрокой. Он принимает следующие аргументы:

  • 1st: Обязательное строковое выражение, содержащее подстроки и разделители. Если выражение является строкой нулевой длины (""), Split возвращает пустой массив, то есть массив без элементов и без данных.
  • 2nd: необязательный разделитель, который является символом строки, используемым для идентификациипределы подстроки. Если опущено, символ пробела ("") считается разделителем. Если разделитель - строка нулевой длины, возвращается одноэлементный массив, содержащий всю строку выражения.
  • 3-й: Необязательный предел, количество возвращаемых подстрок;-1 указывает, что возвращаются все подстроки.
  • 4-е: Сравнение, также необязательное, представляет собой числовое значение, указывающее тип сравнения, используемый при оценке подстрок. Значения см. В разделе «Настройки».

В этом случае нам потребуются только первые два аргумента.


Application.Evaluate

Это IMO - один из самых удобных механизмов, которые вы можете использовать для извлечения возвращенного массива значений без необходимости циклически проходить по элементам / ячейкам. Это может замедлиться, если вы передадите функции формулу большого массива, но в этом случае все будет в порядке. Функция преобразует имя Microsoft Excel в объект или значение, и когда мы передаем ему формулу, оно, таким образом, возвращает результаты. В этом конкретном случае он вернет массив.

1 голос
/ 02 ноября 2019

Мне не совсем ясно, какой конечный результат вы ищете или у вас все в порядке с решением VBA, но это моя интерпретация:

Function lengths(txt As String) As String
  Dim wrd
  For Each wrd In Split(txt)
    If lengths <> "" Then lengths = lengths & ","
    lengths = lengths & Len(wrd)
  Next wrd
End Function

Вставьте код вмодуль VBA, а затем, например, если A1 содержит Black Cup With Handle, то в другой ячейке вы можете использовать =length(A1), который будет возвращать 5,3,4,6.

0 голосов
/ 02 ноября 2019

Если вы хотите использовать код VBA, вы можете попробовать это:

Option Explicit

Sub test()

    Dim arr As Variant
    Dim str As String
    Dim i As Long, j As Long, LastRow As Long

    With ThisWorkbook.Worksheets("Sheet1")

        LastRow = .Cells(.Rows.Count, "A").End(xlUp).Row

        For i = 1 To LastRow

            str = .Range("A" & i).Value

            arr = Split(str, " ")

            For j = LBound(arr) To UBound(arr)
                .Cells(i, j + 3).Value = Len(arr(j))
            Next j

        Next i

    End With

End Sub

Результаты:

enter image description here

...