Как сцепить несколько значений в одну ячейку по критерию? СцепитьЕсли
Все чаще вижу на разных форумах вопросы типа:
Получить такую:
Стандартными функциями это сделать весьма проблематично, т.к. заранее неизвестно сколько будет этих оценок и фамилий.. MIcrosoft работает над усовершенствованием Excel и теперь стало возможным сделать это и стандартными функциями. Правда, с небольшими ограничениями: сделать это могут только пользователи
Аргументы функции:
("; ") - символ(или несколько символов), которым необходимо объединять найденные значения( - диапазон, в котором искать критерийA2:A20 )( - критерий. Значение, на основании которого необходимо сцеплять значения. Значение просматривается в диапазоне значений(A2 ) )A2:A20 ( - из этого диапазона берется значение для сцепления, если значение напротив в диапазонe(B2:B20 ) ) совпадает с искомым значениемA2:A20 A2
Для любителей "старой школы" можно вместо функции
Аргументы точно такие же, как в формуле выше. Правда эта формула вводится в ячейку как формула массива(т.е. одновременным нажатием трех клавиш
А для пользователей Excel 2016 и ниже я написал небольшую функцию пользователя на VBA, которая решает данную проблему. Так же подобную функцию называют "многоразовый ВПР", потому что она по критерию возвращает ВСЕ значения для этого критерия, а не только первое.
'--------------------------------------------------------------------------------------- ' Author : The_Prist(Щербаков Дмитрий) ' Профессиональная разработка приложений для MS Office любой сложности ' Проведение тренингов по MS Excel ' http://www.excel-vba.ru ' Purpose: '--------------------------------------------------------------------------------------- Function СцепитьЕсли(ByRef Диапазон As Range, ByVal Критерий As String, ByRef Диапазон_сцепления As Range, Optional Разделитель As String = " ", Optional БезПовторов As Boolean = False) As String Dim li As Long, sStr As String, avItem, avDateArr(), avRezArr(), lUBnd As Long If Диапазон.Count > 1 Then avDateArr = Intersect(Диапазон, Диапазон.Parent.UsedRange).Value avRezArr = Intersect(Диапазон_сцепления, Диапазон_сцепления.Parent.UsedRange).Value If Диапазон.Rows.Count = 1 Then avDateArr = Application.Transpose(avDateArr) avRezArr = Application.Transpose(avRezArr) End If Else ReDim avDateArr(1, 1): ReDim avRezArr(1, 1) avDateArr(1, 1) = Диапазон.Value avRezArr(1, 1) = Диапазон_сцепления.Value End If lUBnd = UBound(avDateArr, 1) 'Определяем вхождение операторов сравнения в Критерий Dim objRegExp As Object, objMatches As Object Set objRegExp = CreateObject("VBScript.RegExp") objRegExp.Global = False: objRegExp.Pattern = "=|<>|=>|>=|<=|=<|>|<" Set objMatches = objRegExp.Execute(Критерий) 'Если есть вхождения If objMatches.Count > 0 Then Dim sStrMatch As String sStrMatch = objMatches.Item(0) Критерий = Replace(Replace(Критерий, sStrMatch, "", 1, 1), Chr(34), "", 1, 2) If IsNumeric(Критерий) And Критерий <> "" Then Критерий = CDbl(Критерий) End If Select Case sStrMatch Case "=" For li = 1 To lUBnd If avDateArr(li, 1) = Критерий Then If Trim(avRezArr(li, 1)) <> "" Then _ sStr = sStr & IIf(sStr <> "", Разделитель, "") & avRezArr(li, 1) End If Next li Case "<>" For li = 1 To lUBnd If avDateArr(li, 1) <> Критерий Then If Trim(avRezArr(li, 1)) <> "" Then _ sStr = sStr & IIf(sStr <> "", Разделитель, "") & avRezArr(li, 1) End If Next li Case ">=", "=>" For li = 1 To lUBnd If avDateArr(li, 1) >= Критерий Then If Trim(avRezArr(li, 1)) <> "" Then _ sStr = sStr & IIf(sStr <> "", Разделитель, "") & avRezArr(li, 1) End If Next li Case "<=", "=<" For li = 1 To lUBnd If avDateArr(li, 1) <= Критерий Then If Trim(avRezArr(li, 1)) <> "" Then _ sStr = sStr & IIf(sStr <> "", Разделитель, "") & avRezArr(li, 1) End If Next li Case ">" For li = 1 To lUBnd If avDateArr(li, 1) > Критерий Then If Trim(avRezArr(li, 1)) <> "" Then _ sStr = sStr & IIf(sStr <> "", Разделитель, "") & avRezArr(li, 1) End If Next li Case "<" For li = 1 To lUBnd If avDateArr(li, 1) < Критерий Then If Trim(avRezArr(li, 1)) <> "" Then _ sStr = sStr & IIf(sStr <> "", Разделитель, "") & avRezArr(li, 1) End If Next li End Select Else 'Если нет вхождения For li = 1 To lUBnd If avDateArr(li, 1) Like Критерий Then If Trim(avRezArr(li, 1)) <> "" Then _ sStr = sStr & IIf(sStr <> "", Разделитель, "") & avRezArr(li, 1) End If Next li End If If БезПовторов Then Dim oDict As Object, sTmpStr Set oDict = CreateObject("Scripting.Dictionary") sTmpStr = Split(sStr, Разделитель) On Error Resume Next For li = LBound(sTmpStr) To UBound(sTmpStr) oDict.Add sTmpStr(li), sTmpStr(li) Next li sStr = "" sTmpStr = oDict.keys For li = LBound(sTmpStr) To UBound(sTmpStr) sStr = sStr & IIf(sStr <> "", Разделитель, "") & sTmpStr(li) Next li End If СцепитьЕсли = sStr End Function |
Чтобы правильно использовать приведенный код, необходимо сначала ознакомиться со статьей Что такое функция пользователя(UDF)?. Вкратце: скопировать текст кода выше, перейти в редактор VBA(
По принципу работы функция похожа на стандартную СУММЕСЛИ. Указывается диапазон значений(где просматривать значение), критерий и диапазон значений для сцепления. Символ для разделения слов указывать необязательно.
Диапазон
Критерий
Диапазон_сцепления
Разделитель
БезПовторов - если указать 1 или ИСТИНА, то в результате получится строка, в которой нет одинаковых значений. Если указать 0 или ЛОЖЬ, то будут выведены все значения. По умолчанию значение ЛОЖЬ.
Примечание: для работы функции должны быть разрешены макросы
Пример СцепитьЕсли.xls (68,0 KiB, 16 095 скачиваний)
Также см.:
ВПР_МН
Сцепить_МН
СцепитьЕсли
Что такое функция пользователя(UDF)?
ВПР с возвратом всех значений
Статья помогла? Поделись ссылкой с друзьями!

Поиск по меткам
Access apple watch Multex Power Query и Power BI VBA управление кодами Бесплатные надстройки Дата и время Записки ИП Надстройки Печать Политика Конфиденциальности Почта Программы Работа с приложениями Разработка приложений Росстат Тренинги и вебинары Финансовые Форматирование Функции Excel акции MulTEx ссылки статистикаКомментарии, не имеющие отношения к комментируемой статье, могут быть удалены без уведомления и объяснения причин. Если есть вопрос по личной проблеме - добро пожаловать на Форум
Добрый день, Дмитрий!
Отличная функция! Может подскажете, как реализовать ее, например, к двумерному массиву (т.е. если нужно объединить ячейки из диапазона нескольких строк и столбцов) ? Пример тут не получается прикрепить, ниже привожу скриншот с данными в вашем файле:
Суть в том, что мне нужно сцепить значения из указанного диапазона (например, L9:Q11), которые являются непустыми и не содержат нулевое значение.
Буду благодарен за ответ.
Здравствуйте!
Отличная функция, но не могу переделать ее под свои нужды. Мне нужно чтобы было 3 критерия и 3 различных диапазона, получилось переделать на 2 критерия, но оба критерия ищут совпадения в одном диапазоне.
Что нужно изменить, чтобы было приблизительно так: СЦЕПИТЬЕСЛИМН (Диапазон критерия1; Критерий1; Диапазон критерия2; Критерий2; Диапазон критерия3; Критерий3; Диапазон сцепления; Разделитель; Без повторов)
Добрый день! Поделитесь, пожалуйста, решением для двух критериев, Спасибо!
Подскажите, вам помогли! Есть ли ссылка?
Дмитрий, добрый день! Отличная функция. Возможно ли функцию определить к диапазонам со скрытыми строками? То есть, где нужно поставить свойство Visible, чтобы получить результат только из видимых ячеек?
Можно, но для этого придется переписывать большую часть функции.
Добрый день! А не подскажите как перенести эту функцию в google sheet? Вставляю данный код, но пишет ошибку, я так понимаю ее надо "переделать"?
Ренат, в Google Sheets используется совершенно другой язык программирования. Поэтому функцию надо не просто "переделать" - её надо писать заново конкретно под Google.
Отличная функция. Спасибо! Для несведущих выглядит как магия Эксель!
Здравствуйте! Есть диапазон А2:А20, из него ищем критерий А2, диапазон значений для сцепления В2:В20. Как сделать, чтобы сцеплялись данные только без В2?
Александр, в текущей реализации функции никак, т.к. нет привязки к адресу ячеек.
Дмитрий, не подскажете, почему-то макрос не срабатывает корректно. Выдает не все и неверные значения. Файл прилагаю.
Логика: надо показать все самолеты, дальность полета которых больше (в идеале >= ) дальности маршрута.
Файл:https://1drv.ms/x/s!AnkXUJviq7uYgeM5E3WA5tR_oBBsAw
Здравствуйте, Дмитрий!
Огромное Вам спасибо за очень полезную функцию!
Дмитрий, подскажите, пожалуйста, как поправить код, чтобы функция работала корректно, если значения в диапазоне "Критерий" и значения в диапазоне "Диапазон" (простите за тавтологию) содержат символ "="? Я долго не мог понять, почему функция одни значения находит, а другие - нет. Методом тыка определил, что функции "мешает" именно символ "=" и в этом случае, функция ничего не возвращает.
Заранее, огромное спасибо!
Дмитрий, пример со значениями с символом "=" во вложении:
http://rgho.st/7psnp8bWR
Большое спасибо!! Макрос просто офигенный!!