Склеивание текста по условию
Про то, как можно быстро склеивать текст из нескольких ячеек в одну и, наоборот, разбирать длинную текстовую строку на составляющие я уже писал. Теперь же давайте рассмотрим близкую, но чуть более сложную задачу — как склеивать текст из нескольких ячеек при выполнении определенного заданного условия.
Допустим, что у нас имеется база данных по клиентам, где одному названию компании может соответствовать несколько разных email’ов ее сотрудников. Наша задача состоит в том, чтобы собрать все адреса по названиям компаний и сцепить их (через запятую или точку с запятой), чтобы сделать потом, например, почтовую рассылку по клиентам, т.е. получить на выходе что-то похожее на:
Другими словами, нам нужен инструмент, который будет склеивать (сцеплять) текст по условию — аналог функции СУММЕСЛИ (SUMIF), но для текста.
Способ 0. Формулой
Не очень изящный, зато самый простой способ. Можно написать несложную формулу, которая будет проверять отличается ли компания в очередной строке от предыдущей. Если не отличается, то приклеиваем через запятую очередной адрес. Если отличается, то «сбрасываем» накопленное, начиная заново:
Минусы такого подхода очевидны: из всех ячеек полученного дополнительного столбца нам нужны только последние по каждой компании (желтые). Если список большой, то чтобы их быстро отобрать придется добавить еще один столбец, использующий функцию ДЛСТР (LEN), проверяющий длину накопленных строк:
Теперь можно отфильтровать единички и скопировать нужные склейки адресов для дальнейшего использования.
Способ 1. Макрофункция склейки по одному условию
Если исходный список не отсортирован по компаниям, то приведенная выше простая формула не работает, но можно легко выкрутиться с помощью небольшой пользовательской функции на VBA. Откройте редактор Visual Basic нажатием на сочетание клавиш Alt+F11 или с помощью кнопки Visual Basic на вкладке Разработчик (Developer). В открывшемся окне вставьте новый пустой модуль через меню Insert — Module и скопируйте туда текст нашей функции:
Function MergeIf(TextRange As Range, SearchRange As Range, Condition As String) Dim Delimeter As String, i As Long Delimeter = ", " 'символы-разделители (можно заменить на пробел или ; и т.д.) 'если диапазоны проверки и склеивания не равны друг другу - выходим с ошибкой If SearchRange.Count <> TextRange.Count Then MergeIf = CVErr(xlErrRef) Exit Function End If 'проходим по все ячейкам, проверяем условие и собираем текст в переменную OutText For i = 1 To SearchRange.Cells.Count If SearchRange.Cells(i) Like Condition Then OutText = OutText & TextRange.Cells(i) & Delimeter Next i 'выводим результаты без последнего разделителя MergeIf = Left(OutText, Len(OutText) - Len(Delimeter)) End Function
Если теперь вернуться в Microsoft Excel, то в списке функций (кнопка fx в строке формул или вкладка Формулы — Вставить функцию) можно будет найти нашу функцию MergeIf в категории Определенные пользователем (User Defined). Аргументы у функции следующие:
Способ 2. Сцепить текст по неточному условию
Если заменить в 13-й строчке нашего макроса первый знак = на оператор приблизительного совпадения Like, то можно будет осуществлять склейку по неточному совпадению исходных данных с критерием отбора. Например, если название компании может быть записано в разных вариантах, то мы можем одной функцией проверить и собрать их все:
Поддерживаются стандартные спецсимволы подстановки:
- звездочка (*) — обозначает любое количество любых символов (в т.ч. и их отсутствие)
- вопросительный знак (?) — обозначает один любой символ
- решетка (#) — обозначает одну любую цифру (0-9)
По умолчанию оператор Like регистрочувствительный, т.е. понимает, например, «Орион» и «оРиОн» как разные компании. Чтобы не учитывать регистр можно добавить в самое начало модуля в редакторе Visual Basic строчку Option Compare Text, которая переключит Like в режим, когда он невосприимчив к регистру.
Таким образом можно составлять весьма сложные маски для проверки условий, например:
- ?1##??777RUS — выборка по всем автомобильным номерам 777 региона, начинающимся с 1
- ООО* — все компании, название которых начинается на ООО
- ##7## — все товары с пятизначным цифровым кодом, где третья цифра 7
- ????? — все названия из пяти букв и т.д.
Способ 3. Макрофункция склейки текста по двум условиям
В работе может встретиться задача, когда сцеплять текст нужно больше, чем по одному условию. Например представим, что в нашей предыдущей таблице добавился еще один столбец с городом и склеивание нужно проводить не только для заданной компании, но еще и для заданного города. В этом случае нашу функцию придется немного модернизировать, добавив к ней проверку еще одного диапазона:
Function MergeIfs(TextRange As Range, SearchRange1 As Range, Condition1 As String, SearchRange2 As Range, Condition2 As String) Dim Delimeter As String, i As Long Delimeter = ", " 'символы-разделители (можно заменить на пробел или ; и т.д.) 'если диапазоны проверки и склеивания не равны друг другу - выходим с ошибкой If SearchRange1.Count <> TextRange.Count Or SearchRange2.Count <> TextRange.Count Then MergeIfs = CVErr(xlErrRef) Exit Function End If 'проходим по все ячейкам, проверяем все условия и собираем текст в переменную OutText For i = 1 To SearchRange1.Cells.Count If SearchRange1.Cells(i) = Condition1 And SearchRange2.Cells(i) = Condition2 Then OutText = OutText & TextRange.Cells(i) & Delimeter End If Next i 'выводим результаты без последнего разделителя MergeIfs = Left(OutText, Len(OutText) - Len(Delimeter)) End Function
Применяться она будет совершенно аналогично — только аргументов теперь нужно указывать больше:
Способ 4. Группировка и склейка в Power Query
Решить проблему можно и без программирования на VBA, если использовать бесплатную надстройку Power Query. Для Excel 2010-2013 ее можно скачать здесь, а в Excel 2016 она уже встроена по умолчанию. Последовательность действий будет следующей:
Power Query не умеет работать с обычными таблицами, поэтому первым шагом превратим нашу таблицу в «умную». Для этого ее нужно выделить и нажать сочетание Ctrl+T или выбрать на вкладке Главная — Форматировать как таблицу (Home — Format as Table). На появившейся затем вкладке Конструктор (Design) можно задать имя таблицы (я оставил стандартное Таблица1):
Теперь загрузим нашу таблицу в надстройку Power Query. Для этого на вкладке Данные (если у вас Excel 2016) или на вкладке Power Query (если у вас Excel 2010-2013) жмем Из таблицы (Data — From Table):
В открывшемся окне редактора запросов выделяем щелчком по заголовку столбец Компания и сверху жмем кнопку Группировать (Group By). Вводим имя нового столбца и тип операции в группировке — Все строки (All Rows):
Жмем ОК и получаем для каждой компании мини-таблицу сгруппированных значений. Содержимое таблиц хорошо видно, если щелкать левой кнопкой мыши в белый фон ячеек (не в текст!) в получившемся столбце:
Теперь добавим еще один столбец, где с помощью функции склеим через запятую содержимое столбцов Адрес в каждой из мини-таблиц. Для этого на вкладке Добавить столбец жмем Пользовательский столбец (Add column — Custom column) и в появившемся окне вводим имя нового столбца и формулу сцепки на встроенном в Power Query языке М:
Обратите внимание, что все М-функции регистрочувствительные (в отличие от Excel). После нажатия на ОК получаем новый столбец со склееными адресами:
Осталось удалить ненужный уже столбец ТаблАдресов (правой кнопкой мыши по заголовку — Удалить столбец) и выгрузить результаты на лист, нажав на вкладке Главная — Закрыть и загрузить (Home — Close and load):
Важный нюанс: в отличие от предыдущих способов (функций), таблицы из Power Query не обновляются автоматически. Если в будущем произойдут какие-либо изменения в исходных данных, то нужно будет щелкнуть правой кнопкой в любое место таблицы результатов и выбрать команду Обновить (Refresh).
Ссылки по теме
- Как разделить длинную текстовую строку на части
- Несколько способов склеить текст из разных ячеек в одной
- Использование оператора Like для проверки текста по маске
In this article, we are going to show you how to consolidate text by a condition in Excel.
Download Workbook
Please note that we will be using the new dynamic array functions UNIQUE and FILTER in this post. These functions currently are only available to Office 365 users.
If you don’t have Office 365, a great alternative to these formulas is using a Pivot Table instead. To learn more about this method, please see How to consolidate text with Pivot Table in Excel.
Consolidating text by a condition
The example we are going to be looking at consists of categories (Name), and corresponding text values (Ability) we want to consolidate.
Note that you can convert your data into an Excel Table by pressing Ctrl + T when the data is selected. An Excel Table provides a dynamically updating table layout and makes formulas easier to apply. See Tips for Excel Tables for more.
First, we need a list of conditions (categories). This list needs to include unique names to avoid any duplicate entries. If you already have a list of conditions, you can use it as is.
You can generate a unique list using the UNIQUE function. Use the Name column to populate a list of unique categories.
Next, we can use these unique values to “filter”, and merge the values under the Ability column. The consolidation formula will include FILTER and TEXTJOIN functions.
=TEXTJOIN(«, «,TRUE,FILTER(Table1[Ability],Table1[Name]=<Category>))
In summary, the FILTER formula can return an array of values based on a criteria, and the TEXTJOIN can merge text values in an array, adding a delimiter.
The criteria in our scenario can be defined with the Table1[Name]=<Category> expression. So, replace <Category> with the reference of the unique Name value.
The first argument of the TEXTJOIN function determines the delimiter. Our choice is a comma and a space «, «. You can replace this with any value you want like “ — «, “ | “, etc.
0 / 0 / 0 Регистрация: 20.06.2013 Сообщений: 18 |
|
1 |
|
Необходимо объединение строк по условию26.11.2013, 11:23. Показов 6318. Ответов 6
Всем доброго времени суток! Чтобы стало понятнее что имею и что требуется, прилагаю пример. Благодарю за помощь всех откликнувшихся!
0 |
5942 / 3154 / 698 Регистрация: 23.11.2010 Сообщений: 10,524 |
|
26.11.2013, 11:48 |
2 |
Для столбцов B, C, D формула массива Код =ИНДЕКС(B$2:B$7;ПОИСКПОЗ(1;($A$2:$A$7=$A22)*ЕТЕКСТ(B$2:B$7);0))
1 |
5942 / 3154 / 698 Регистрация: 23.11.2010 Сообщений: 10,524 |
|
26.11.2013, 11:59 |
3 |
Далее для столбца «Дополнительное» формула массива и протянуть вправо по столбцам Код =ИНДЕКС($E$2:$E$7;НАИМЕНЬШИЙ(ЕСЛИ(($A$2:$A$7=$A22)*ЕТЕКСТ($E$2:$E$7);СТРОКА($1:$6));СТОЛБЕЦ(A1)))
1 |
0 / 0 / 0 Регистрация: 20.06.2013 Сообщений: 18 |
|
26.11.2013, 15:39 [ТС] |
4 |
Далее для столбца «Дополнительное» формула массива и протянуть вправо по столбцам Код =ИНДЕКС($E$2:$E$7;НАИМЕНЬШИЙ(ЕСЛИ(($A$2:$A$7=$A22)*ЕТЕКСТ($E$2:$E$7);СТРОКА($1:$6));СТОЛБЕЦ(A1))) Благодарю за помощь) Но почему-то у меня даже в файлике примеров по такой формуле выдает #Н/Д. Что может быть не так?
0 |
5942 / 3154 / 698 Регистрация: 23.11.2010 Сообщений: 10,524 |
|
26.11.2013, 15:41 |
5 |
Формулу вводили Ctrl+Shift+Enter?
1 |
0 / 0 / 0 Регистрация: 20.06.2013 Сообщений: 18 |
|
26.11.2013, 16:34 [ТС] |
6 |
Формулу вводили Ctrl+Shift+Enter? Да, с Ctrl+Shift+Enter, все равно Н/Д Реальный пример отличается тем, что не только в дополнительно могут быть повторы у объектов под одним ID. Добавлено через 40 минут
0 |
5942 / 3154 / 698 Регистрация: 23.11.2010 Сообщений: 10,524 |
|
26.11.2013, 16:50 |
7 |
Если конечный файл, т.е. потом не будет изменений. Скопировать — Вставить — Специальная вставка — Значения. Затем Выделение группы ячеек — тут надо посмотреть, или формулы, или ошибки — Del. Добавлено через 59 секунд
0 |
Здравствуйте.
В первом столбце excel значения, во втором соответствующие им, но в разных строках:
Нужно объединить все «a» в ячейку напротив 1, все b напротив 2 и т.д, причем с сохранением переноса строк:
Записей, естественно, тысячи.
Подскажите, пожалуйста, как это сделать?
-
Вопрос заданболее трёх лет назад
-
1098 просмотров
Накидал без особых красивостей
Из минусов:
— между значениями после обработки остаются пустые строки, равные количеству элементов — 1 во втором столбце (соответственно конкатенированные значения); пустые строки в экселе подчистить не должно быть проблемой;
— начальная инициализация завязана на расположение элементов.
Не забудьте расширить диапазон Range() для цикла.
Sub concat()
txt = Range("B1").Text
Range("A1").Select
Set hCell = ActiveCell
For Each cell In Range("A1:A20")
If cell.Value <> "" Or cell.Offset(0, 1).Value = "" Then
hCell.Offset(0, 1).Value = txt
cell.Select
Set hCell = ActiveCell
txt = ""
End If
If cell.Offset(0, 1).Value = "" Then
Exit Sub
End If
txt = txt + vbCrLf + cell.Offset(0, 1).Text
' Очистка ячейки
cell.Offset(0, 1).Value = ""
Next
End Sub
Пригласить эксперта
-
Показать ещё
Загружается…
16 апр. 2023, в 14:44
4500 руб./за проект
16 апр. 2023, в 14:28
8000 руб./за проект
16 апр. 2023, в 13:46
1000 руб./за проект
Минуточку внимания
Как объединить данные строк по условиям |
||||||||
Ответить |
||||||||
Ответить |
||||||||
Ответить |
||||||||
Ответить |
||||||||
Ответить |
||||||||
Ответить |
||||||||
Ответить |
||||||||
Ответить |
||||||||
Ответить |
||||||||
Ответить |
||||||||
Ответить |
||||||||
Ответить |
||||||||
Ответить |