======================================================= Функция (UDF) "СцепитьЕсли" ======================================================= Данная Определенная пользователем функция (User-Defined Function или UDF) возвращает в ячейку листа, куда она введена, "склеенные" в одну строку тексты из ячеек заданного диапазона при выполнении заданного условия с задаваемыми при необходимости разделителями данных из разных ячеек. [vba]
Код
Function СцепитьЕсли(ByRef Диапазон As Range, _ ByVal Критерий As String, _ ByRef Диапазон_сцепления As Range, _ Optional Разделитель As String = " ") As String '--------------------------------------------------------------------------------------- ' Procedure : СцепитьЕсли ' Author : The_Prist & Alex_ST ' Topic_HEADER : "Помогите создать СЦЕПИТЬЕСЛИ() - аналог СУММЕСЛИ()" ' Topic_URL : http://www.planetaexcel.ru/forum.php?thread_id=14935 ' Post_Author : The_Prist ' Post_URL : http://www.planetaexcel.ru/docs/forum_upload/post_113923.xls ' DateTime : 02.04.2010 22:24 ' Purpose : СЦЕПИТЬЕСЛИ() - аналог СУММЕСЛИ() ' Notes : По умолчанию разделитель слов - пробел, но можно задать любой другой символ/символы. ' Диапазон - диапазон с критериями(указывается один столбец) ' Критерий - критерий. Просматривается Диапазон. ' Диапазон_сцепления - из этого диапазона берется значение для сцепления, ' если значение в аргументе Диапазон совпадает с аргументом Критерий (указывается один столбец). '--------------------------------------------------------------------------------------- Dim rCell As Range, rFndrng As Range, sStr As String Set Диапазон = Intersect(Диапазон, ActiveSheet.UsedRange) Set Диапазон_сцепления = Intersect(Диапазон_сцепления, ActiveSheet.UsedRange) For Each rCell In Диапазон If rCell.Value Like Критерий Then If Trim(Диапазон_сцепления.Cells(rCell.Row - Диапазон.Row + 1, 1)) <> "" Then _ sStr = sStr & IIf(sStr <> "", Разделитель, "") & Диапазон_сцепления.Cells(rCell.Row - Диапазон.Row + 1, 1) End If Next rCell СцепитьЕсли = sStr End Function
[/vba]
======================================================= Функция (UDF) "СцепитьЕсли" ======================================================= Данная Определенная пользователем функция (User-Defined Function или UDF) возвращает в ячейку листа, куда она введена, "склеенные" в одну строку тексты из ячеек заданного диапазона при выполнении заданного условия с задаваемыми при необходимости разделителями данных из разных ячеек. [vba]
Код
Function СцепитьЕсли(ByRef Диапазон As Range, _ ByVal Критерий As String, _ ByRef Диапазон_сцепления As Range, _ Optional Разделитель As String = " ") As String '--------------------------------------------------------------------------------------- ' Procedure : СцепитьЕсли ' Author : The_Prist & Alex_ST ' Topic_HEADER : "Помогите создать СЦЕПИТЬЕСЛИ() - аналог СУММЕСЛИ()" ' Topic_URL : http://www.planetaexcel.ru/forum.php?thread_id=14935 ' Post_Author : The_Prist ' Post_URL : http://www.planetaexcel.ru/docs/forum_upload/post_113923.xls ' DateTime : 02.04.2010 22:24 ' Purpose : СЦЕПИТЬЕСЛИ() - аналог СУММЕСЛИ() ' Notes : По умолчанию разделитель слов - пробел, но можно задать любой другой символ/символы. ' Диапазон - диапазон с критериями(указывается один столбец) ' Критерий - критерий. Просматривается Диапазон. ' Диапазон_сцепления - из этого диапазона берется значение для сцепления, ' если значение в аргументе Диапазон совпадает с аргументом Критерий (указывается один столбец). '--------------------------------------------------------------------------------------- Dim rCell As Range, rFndrng As Range, sStr As String Set Диапазон = Intersect(Диапазон, ActiveSheet.UsedRange) Set Диапазон_сцепления = Intersect(Диапазон_сцепления, ActiveSheet.UsedRange) For Each rCell In Диапазон If rCell.Value Like Критерий Then If Trim(Диапазон_сцепления.Cells(rCell.Row - Диапазон.Row + 1, 1)) <> "" Then _ sStr = sStr & IIf(sStr <> "", Разделитель, "") & Диапазон_сцепления.Cells(rCell.Row - Диапазон.Row + 1, 1) End If Next rCell СцепитьЕсли = sStr End Function
'--------------------------------------------------------------------------------------- ' Procedure : СцепитьЕсли ' Author : The_Prist(Дмитрий); http://www.excel-vba.ru ' Purpose : Функция сцепляет данные из диапазона, указанного критерием Диапазон_сцепления ' в том случае, если ячейка из критерия Диапазон входит в условие ' указанное Критерием. В качекстве Критерия может быть ссылка на ячейку, ' либо текст/число, либо операторы сравнения ' (как все привыкли в СУММЕСЛИ, СЧЁТЕСЛИ и т.д. - "<>""",">8" и пр.). '--------------------------------------------------------------------------------------- Function СцепитьЕсли(ByRef Диапазон As Range, ByVal Критерий As String, ByRef Диапазон_сцепления As Range, Optional Разделитель As String = " ") As String Dim li As Long, sStr As String, avItem, avDateArr(), avRezArr(), lUBnd As Long If Диапазон.Count > 1 Then avDateArr = Intersect(Диапазон, Application.Caller.Parent.UsedRange).Value avRezArr = Intersect(Диапазон_сцепления, Application.Caller.Parent.UsedRange).Value If Диапазон.Rows.Count = 1 Then avDateArr = Application.Transpose(avDateArr) avRezArr = Application.Transpose(avRezArr) End If Else 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) 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 СцепитьЕсли = sStr End Function
'--------------------------------------------------------------------------------------- ' Procedure : СцепитьЕсли ' Author : The_Prist(Дмитрий); http://www.excel-vba.ru ' Purpose : Функция сцепляет данные из диапазона, указанного критерием Диапазон_сцепления ' в том случае, если ячейка из критерия Диапазон входит в условие ' указанное Критерием. В качекстве Критерия может быть ссылка на ячейку, ' либо текст/число, либо операторы сравнения ' (как все привыкли в СУММЕСЛИ, СЧЁТЕСЛИ и т.д. - "<>""",">8" и пр.). '--------------------------------------------------------------------------------------- Function СцепитьЕсли(ByRef Диапазон As Range, ByVal Критерий As String, ByRef Диапазон_сцепления As Range, Optional Разделитель As String = " ") As String Dim li As Long, sStr As String, avItem, avDateArr(), avRezArr(), lUBnd As Long If Диапазон.Count > 1 Then avDateArr = Intersect(Диапазон, Application.Caller.Parent.UsedRange).Value avRezArr = Intersect(Диапазон_сцепления, Application.Caller.Parent.UsedRange).Value If Диапазон.Rows.Count = 1 Then avDateArr = Application.Transpose(avDateArr) avRezArr = Application.Transpose(avRezArr) End If Else 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) 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 СцепитьЕсли = sStr End Function
Мало того что ссылка на источник, так ещё и автор указан
Сергей, то, что в коде указан автор и его сайт не является ссылкой на источник. Ссылка на источник выглядит как ссылка на статью(саму ссылку можешь потом удалить из моего поста - это для демонстрации того, как ссылка выглядит). Я её не вижу :-) Мое мнение: раз уж листинг кода полностью берётся с какой-либо страницы сайта, то и ссылка должна быть на страницу первоисточника. Конечно, мое мнение может не совпадать с твоим и спорить не собираюсь. Это лишь высказывание мнения.
Quote (Serge_007)
Мало того что ссылка на источник, так ещё и автор указан
Сергей, то, что в коде указан автор и его сайт не является ссылкой на источник. Ссылка на источник выглядит как ссылка на статью(саму ссылку можешь потом удалить из моего поста - это для демонстрации того, как ссылка выглядит). Я её не вижу :-) Мое мнение: раз уж листинг кода полностью берётся с какой-либо страницы сайта, то и ссылка должна быть на страницу первоисточника. Конечно, мое мнение может не совпадать с твоим и спорить не собираюсь. Это лишь высказывание мнения.The_Prist
Errare humanum est, stultum est in errore perseverare
Сообщение отредактировал The_Prist - Вторник, 10.05.2011, 11:00
...раз уж листинг кода полностью берётся с какой-либо страницы сайта...
Дим, я не брал код с твоего сайта, поэтому не знаю на какой он там странице, он давно у меня в файлах от тебя был, может ты мне его в личку присылал, может на сайте каком выкладывал, не помню я источник...
Ссылку твою удалять не буду. Более того, добавил её в тот пост с кодом.
Quote (The_Prist)
...раз уж листинг кода полностью берётся с какой-либо страницы сайта...
Дим, я не брал код с твоего сайта, поэтому не знаю на какой он там странице, он давно у меня в файлах от тебя был, может ты мне его в личку присылал, может на сайте каком выкладывал, не помню я источник...
Ссылку твою удалять не буду. Более того, добавил её в тот пост с кодом.Serge_007
Alex_ST, Serge_007, очень интересные функции. Но хотелось бы спросить: 1. Чем отличаются функция представленная Alex_ST, от функции представленной Serge_007; 2. Пожалуйста авторы если не трудно выложите примеры использования данных функций в Excel, а то не получается разобраться.
Alex_ST, Serge_007, очень интересные функции. Но хотелось бы спросить: 1. Чем отличаются функция представленная Alex_ST, от функции представленной Serge_007; 2. Пожалуйста авторы если не трудно выложите примеры использования данных функций в Excel, а то не получается разобраться.Kirigant
"Все следует делать настолько простым, насколько это возможно, но не проще."
Kirigant, а вы статью Дмитрия по ссылке в этом посте Сергея читали? Там же всё разжёвано... Просто то, что выкладывал я, отлавливает только точные совпадения, а макрос Дмитрия кроме того ещё и условия типа больше, больше и равно, меньше, меньше и равно. Кроме того Дмитрий добавил ещё и возможность унификации полученного списка (получения в списке только уникальных значений).
Kirigant, а вы статью Дмитрия по ссылке в этом посте Сергея читали? Там же всё разжёвано... Просто то, что выкладывал я, отлавливает только точные совпадения, а макрос Дмитрия кроме того ещё и условия типа больше, больше и равно, меньше, меньше и равно. Кроме того Дмитрий добавил ещё и возможность унификации полученного списка (получения в списке только уникальных значений).Alex_ST
С уважением, Алексей MS Excel 2003 - the best!!!
Сообщение отредактировал Alex_ST - Четверг, 01.03.2012, 17:08