======================================================= Функция (UDF) "СКЛЕИТЬ" ======================================================= Данная Определенная пользователем функция (User-Defined Function или UDF) возвращает в ячейку листа, куда она введена, "склеенные" в одну строку тексты из ячеек заданного диапазона с задаваемыми при необходимости разделителями данных из разных ячеек. [vba]
Код
Function СКЛЕИТЬ(Диапазон As Range, _ Optional Разделитель_Данных$ = "", _ Optional Переносить_ДА_НЕТ$ = "ДА") As String '--------------------------------------------------------------------------------------- ' Procedure : СКЛЕИТЬ ' Author : Alex_ST ' Purpose : склеить тексты из выделенных ячеек в одну строку с задаваемыми при необходимости разделителями данных из разных ячеек ' Notes : по умолчанию включен перенос строк внутри ячейки '--------------------------------------------------------------------------------------- Dim Слитый_Текст$, Перенос_Строки$, Ячейка As Range If Переносить_ДА_НЕТ$ <> "НЕТ" Then Перенос_Строки = vbLf For Each Ячейка In Диапазон If Слитый_Текст = "" Then Слитый_Текст = Application.WorksheetFunction.Trim(Ячейка.Value) ' будут удаляться лидирующие и финиширующие пробелы, а также многократные пробелы между словами (исползуется стандартная функция СЖПРОБЕЛЫ) Else Слитый_Текст = Слитый_Текст & Разделитель_Данных & Перенос_Строки & Application.WorksheetFunction.Trim(Ячейка.Value) End If Next Ячейка СКЛЕИТЬ = Слитый_Текст End Function
[/vba]
Примечания: При "склеивании" удаляются лидирующие и финиширующие пробелы, а также многократные пробелы между словами (используется стандартная функция СЖПРОБЕЛЫ). Если это не нужно, то можно в коде заменить [vba]
Код
Application.WorksheetFunction.Trim(Ячейка.Value)
на
Код
Ячейка.Value
[/vba]
======================================================= Функция (UDF) "СКЛЕИТЬ" ======================================================= Данная Определенная пользователем функция (User-Defined Function или UDF) возвращает в ячейку листа, куда она введена, "склеенные" в одну строку тексты из ячеек заданного диапазона с задаваемыми при необходимости разделителями данных из разных ячеек. [vba]
Код
Function СКЛЕИТЬ(Диапазон As Range, _ Optional Разделитель_Данных$ = "", _ Optional Переносить_ДА_НЕТ$ = "ДА") As String '--------------------------------------------------------------------------------------- ' Procedure : СКЛЕИТЬ ' Author : Alex_ST ' Purpose : склеить тексты из выделенных ячеек в одну строку с задаваемыми при необходимости разделителями данных из разных ячеек ' Notes : по умолчанию включен перенос строк внутри ячейки '--------------------------------------------------------------------------------------- Dim Слитый_Текст$, Перенос_Строки$, Ячейка As Range If Переносить_ДА_НЕТ$ <> "НЕТ" Then Перенос_Строки = vbLf For Each Ячейка In Диапазон If Слитый_Текст = "" Then Слитый_Текст = Application.WorksheetFunction.Trim(Ячейка.Value) ' будут удаляться лидирующие и финиширующие пробелы, а также многократные пробелы между словами (исползуется стандартная функция СЖПРОБЕЛЫ) Else Слитый_Текст = Слитый_Текст & Разделитель_Данных & Перенос_Строки & Application.WorksheetFunction.Trim(Ячейка.Value) End If Next Ячейка СКЛЕИТЬ = Слитый_Текст End Function
[/vba]
Примечания: При "склеивании" удаляются лидирующие и финиширующие пробелы, а также многократные пробелы между словами (используется стандартная функция СЖПРОБЕЛЫ). Если это не нужно, то можно в коде заменить [vba]
Хочу предложить свой вариант аналогичной ф-ции с преобразованием размерности массива: [vba]
Code
Declare Function VarPtr Lib "msvbvm60" (variable As Any) As Long Declare Function ArrPtr Lib "msvbvm60" Alias "VarPtr" (arr() As Any) As Long Declare Function PutMem2 Lib "msvbvm60" (ByVal pDst As Long, ByVal NewValue As Long) As Long Declare Function PutMem4 Lib "msvbvm60" (ByVal pDst As Long, ByVal NewValue As Long) As Long Declare Function GetMem4 Lib "msvbvm60" (ByVal pSrc As Long, ByVal pDst As Long) As Long
Function JoinRange(srcRng As Range, Optional delim As String = "") As String 'Конкатенация для диапазона ячеек Dim transformArray() As Variant, SA_Ptr As Long
Хочу предложить свой вариант аналогичной ф-ции с преобразованием размерности массива: [vba]
Code
Declare Function VarPtr Lib "msvbvm60" (variable As Any) As Long Declare Function ArrPtr Lib "msvbvm60" Alias "VarPtr" (arr() As Any) As Long Declare Function PutMem2 Lib "msvbvm60" (ByVal pDst As Long, ByVal NewValue As Long) As Long Declare Function PutMem4 Lib "msvbvm60" (ByVal pDst As Long, ByVal NewValue As Long) As Long Declare Function GetMem4 Lib "msvbvm60" (ByVal pSrc As Long, ByVal pDst As Long) As Long
Function JoinRange(srcRng As Range, Optional delim As String = "") As String 'Конкатенация для диапазона ячеек Dim transformArray() As Variant, SA_Ptr As Long
Function СКЛЕИТЬ(Диапазон As Range, _ Optional Разделитель_Данных$ = "", _ Optional Переносить_ДА_НЕТ$ = "ДА") As String '--------------------------------------------------------------------------------------- ' Procedure : СКЛЕИТЬ ' Author : Alex_ST ' Purpose : склеить тексты из выделенных ячеек в одну строку с задаваемыми при необходимости разделителями данных из разных ячеек ' Notes : по умолчанию включен перенос строк внутри ячейки '--------------------------------------------------------------------------------------- Dim Слитый_Текст$, Перенос_Строки$, a, i& Перенос_Строки = IIf(UCase(Переносить_ДА_НЕТ) <> "НЕТ", vbLf, " ") a = Application.Trim(Диапазон.Value) If Диапазон.Rows.Count = 1 Then СКЛЕИТЬ = Join(a, Разделитель_Данных): Exit Function For i = 1 To UBound(a) Слитый_Текст = Слитый_Текст & Join(Application.Index(a, i, 0), Разделитель_Данных) & Перенос_Строки Next СКЛЕИТЬ = Left$(Слитый_Текст, Len(Слитый_Текст) - 1) End Function
[/vba] Помедленней, чем у Формуляра, но быстрей Лешиного. И компактней, чем оба предыдущих Исправил для варианта с одной строкой.
И мой: [vba]
Code
Function СКЛЕИТЬ(Диапазон As Range, _ Optional Разделитель_Данных$ = "", _ Optional Переносить_ДА_НЕТ$ = "ДА") As String '--------------------------------------------------------------------------------------- ' Procedure : СКЛЕИТЬ ' Author : Alex_ST ' Purpose : склеить тексты из выделенных ячеек в одну строку с задаваемыми при необходимости разделителями данных из разных ячеек ' Notes : по умолчанию включен перенос строк внутри ячейки '--------------------------------------------------------------------------------------- Dim Слитый_Текст$, Перенос_Строки$, a, i& Перенос_Строки = IIf(UCase(Переносить_ДА_НЕТ) <> "НЕТ", vbLf, " ") a = Application.Trim(Диапазон.Value) If Диапазон.Rows.Count = 1 Then СКЛЕИТЬ = Join(a, Разделитель_Данных): Exit Function For i = 1 To UBound(a) Слитый_Текст = Слитый_Текст & Join(Application.Index(a, i, 0), Разделитель_Данных) & Перенос_Строки Next СКЛЕИТЬ = Left$(Слитый_Текст, Len(Слитый_Текст) - 1) End Function
[/vba] Помедленней, чем у Формуляра, но быстрей Лешиного. И компактней, чем оба предыдущих Исправил для варианта с одной строкой.KuklP
Блин! Мыла о репликах в старых постах почему-то перестали приходить Хотя раньше (когда я их создавал) точно приходили. Какой-то глюк форума. Я сюда случайно заглянул чтобы посмотреть что новенького и увидел, что мои старые посты всплыли и в них есть реплики. Ща будем посмотреть.
Блин! Мыла о репликах в старых постах почему-то перестали приходить Хотя раньше (когда я их создавал) точно приходили. Какой-то глюк форума. Я сюда случайно заглянул чтобы посмотреть что новенького и увидел, что мои старые посты всплыли и в них есть реплики. Ща будем посмотреть.Alex_ST
Посмотрел у себя. Увидел, что макрос давно уже переделан в обработку массива [vba]
Code
Function СКЛЕИТЬ$(ДИАПАЗОН As Range, _ Optional Разделитель$ = "", _ Optional Переносить As Boolean = True) '--------------------------------------------------------------------------------------- ' Procedure : СКЛЕИТЬ ' Author : Alex_ST ' Purpose : склеить тексты из выделенных ячеек в одну строку с задаваемыми при необходимости разделителями данных ' Notes : по умолчанию включен перенос строк внутри ячейки '--------------------------------------------------------------------------------------- Разделитель = Разделитель & IIf(Переносить, Chr(10), "") Dim Arr, i& Arr = Application.Trim(ДИАПАЗОН.Value) For i = 1 To UBound(Arr) СКЛЕИТЬ = СКЛЕИТЬ & IIf(Len(СКЛЕИТЬ), Разделитель, "") & Arr(i, 1) Next End Function
[/vba]
P.S. Долго гадал над тайным скрытым смыслом Серёгиного
Quote (KuklP)
Join(Application.Index(a, i, 0), Разделитель_Данных)
Т.к. не работает, попробовал исправить, порывшись по Справке... Нифига не понял. Наверное, Серёга описАлся. (или моей ерундиции не хватает и Справка у меня кривая)
Посмотрел у себя. Увидел, что макрос давно уже переделан в обработку массива [vba]
Code
Function СКЛЕИТЬ$(ДИАПАЗОН As Range, _ Optional Разделитель$ = "", _ Optional Переносить As Boolean = True) '--------------------------------------------------------------------------------------- ' Procedure : СКЛЕИТЬ ' Author : Alex_ST ' Purpose : склеить тексты из выделенных ячеек в одну строку с задаваемыми при необходимости разделителями данных ' Notes : по умолчанию включен перенос строк внутри ячейки '--------------------------------------------------------------------------------------- Разделитель = Разделитель & IIf(Переносить, Chr(10), "") Dim Arr, i& Arr = Application.Trim(ДИАПАЗОН.Value) For i = 1 To UBound(Arr) СКЛЕИТЬ = СКЛЕИТЬ & IIf(Len(СКЛЕИТЬ), Разделитель, "") & Arr(i, 1) Next End Function
[/vba]
P.S. Долго гадал над тайным скрытым смыслом Серёгиного
Quote (KuklP)
Join(Application.Index(a, i, 0), Разделитель_Данных)
Т.к. не работает, попробовал исправить, порывшись по Справке... Нифига не понял. Наверное, Серёга описАлся. (или моей ерундиции не хватает и Справка у меня кривая)Alex_ST
С уважением, Алексей MS Excel 2003 - the best!!!
Сообщение отредактировал Alex_ST - Пятница, 17.08.2012, 13:00
Не описался. Application.Index(a, i, 0) берет строку i из массива a. См. исправленный вариант в том сообщении. С примером. А в твоем варианте одной строки хватит: [vba]
Code
СКЛЕИТЬ = join(Arr,Разделитель)
[/vba]
Не описался. Application.Index(a, i, 0) берет строку i из массива a. См. исправленный вариант в том сообщении. С примером. А в твоем варианте одной строки хватит: [vba]
Серёга, я, естественно, первым же делом попробовал применить Join, но массив Arr = Application.Trim(ДИАПАЗОН.Value) может получиться и двумерным в зависимости от размерности ДИАПАЗОНА, а с ним Join не работает. Поэтому чтобы не запариваться с размерностями массива я переделал так:[vba]
Code
Function СКЛЕИТЬ$(ДИАПАЗОН As Range, _ Optional Разделитель$ = "", _ Optional Переносить As Boolean = True) '--------------------------------------------------------------------------------------- ' Procedure : СКЛЕИТЬ ' Author : Alex_ST ' Purpose : склеить тексты из выделенных ячеек в одну строку с задаваемыми при необходимости разделителями данных ' Notes : по умолчанию включен перенос строк внутри ячейки '--------------------------------------------------------------------------------------- Разделитель = Разделитель & IIf(Переносить, Chr(10), "") Dim Arr, xArr Arr = Application.Trim(ДИАПАЗОН.Value) For Each xArr In Arr If Len(xArr) Then СКЛЕИТЬ = СКЛЕИТЬ & IIf(Len(СКЛЕИТЬ), Разделитель, "") & xArr Next End Function
[/vba]
А по поводу Application.Index(a, i, 0) - не знаю. У меня почему-то работать не хочет даже если я ставлю не Application.Index, а Application.WorksheetFunction.Index Да и это моё крайнее решение, ИМХО, достаточно простое и должно быть не тормозным
Серёга, я, естественно, первым же делом попробовал применить Join, но массив Arr = Application.Trim(ДИАПАЗОН.Value) может получиться и двумерным в зависимости от размерности ДИАПАЗОНА, а с ним Join не работает. Поэтому чтобы не запариваться с размерностями массива я переделал так:[vba]
Code
Function СКЛЕИТЬ$(ДИАПАЗОН As Range, _ Optional Разделитель$ = "", _ Optional Переносить As Boolean = True) '--------------------------------------------------------------------------------------- ' Procedure : СКЛЕИТЬ ' Author : Alex_ST ' Purpose : склеить тексты из выделенных ячеек в одну строку с задаваемыми при необходимости разделителями данных ' Notes : по умолчанию включен перенос строк внутри ячейки '--------------------------------------------------------------------------------------- Разделитель = Разделитель & IIf(Переносить, Chr(10), "") Dim Arr, xArr Arr = Application.Trim(ДИАПАЗОН.Value) For Each xArr In Arr If Len(xArr) Then СКЛЕИТЬ = СКЛЕИТЬ & IIf(Len(СКЛЕИТЬ), Разделитель, "") & xArr Next End Function
[/vba]
А по поводу Application.Index(a, i, 0) - не знаю. У меня почему-то работать не хочет даже если я ставлю не Application.Index, а Application.WorksheetFunction.Index Да и это моё крайнее решение, ИМХО, достаточно простое и должно быть не тормознымAlex_ST
Посмотрел. Почему-то заработало. Хотя раньше ругалось на Application.Index Не пойму, в чём было дело. Правда, я тут подвисал и пришлось перегружаться, а потом отвлекли. Вот сразу и не отписался.
Но всё равно, мой код тоже не плох (ИМХО, конечно )
Посмотрел. Почему-то заработало. Хотя раньше ругалось на Application.Index Не пойму, в чём было дело. Правда, я тут подвисал и пришлось перегружаться, а потом отвлекли. Вот сразу и не отписался.
Но всё равно, мой код тоже не плох (ИМХО, конечно )Alex_ST
С уважением, Алексей MS Excel 2003 - the best!!!
Сообщение отредактировал Alex_ST - Пятница, 17.08.2012, 20:17
Не знаю, на сколько важна скорострельность, а этот сцепляет и по столбцам, и из закрытой книги. [vba]
Code
Function СЦЕПДИАП_A(Диапазон As Variant, Optional Разделитель As String = " ", _ Optional ПоСтолбцам As Boolean = False, Optional сПереносом As Boolean = False) As String '--------------------------------------------------------------------------------------- ' Author : RAN ' Purpose : Сцепляет текст ячеек из заданного диапазона ' Notes : Разделитель по умолчанию " " ' Notes : Optional ПоСтолбцам - просмотр по строкам(умолчание) и по столбцам ' Notes : Optional сПереносом по умолчанию - "нет" '--------------------------------------------------------------------------------------- Dim i&, j&, k&, arr
If сПереносом Then If Разделитель <> " " Then Разделитель = Разделитель & vbLf Else Разделитель = vbLf End If End If
If TypeName(Диапазон) = "Range" Then Диапазон = Диапазон.Value If Not IsArray(Диапазон) Then СЦЕПДИАП_A = Диапазон: Exit Function ReDim arr(1 To UBound(Диапазон, 1) * UBound(Диапазон, 2)) If ПоСтолбцам Then For i = 1 To UBound(Диапазон, 2) For j = 1 To UBound(Диапазон, 1) If Len(Диапазон(j, i)) Then k = k + 1: arr(k) = Диапазон(j, i) Next: Next Else For j = 1 To UBound(Диапазон, 1) For i = 1 To UBound(Диапазон, 2) If Len(Диапазон(j, i)) Then k = k + 1: arr(k) = Диапазон(j, i) Next: Next End If СЦЕПДИАП_A = Join(arr, Разделитель) СЦЕПДИАП_A = Application.Trim(СЦЕПДИАП_A) End Function
[/vba]
Не знаю, на сколько важна скорострельность, а этот сцепляет и по столбцам, и из закрытой книги. [vba]
Code
Function СЦЕПДИАП_A(Диапазон As Variant, Optional Разделитель As String = " ", _ Optional ПоСтолбцам As Boolean = False, Optional сПереносом As Boolean = False) As String '--------------------------------------------------------------------------------------- ' Author : RAN ' Purpose : Сцепляет текст ячеек из заданного диапазона ' Notes : Разделитель по умолчанию " " ' Notes : Optional ПоСтолбцам - просмотр по строкам(умолчание) и по столбцам ' Notes : Optional сПереносом по умолчанию - "нет" '--------------------------------------------------------------------------------------- Dim i&, j&, k&, arr
If сПереносом Then If Разделитель <> " " Then Разделитель = Разделитель & vbLf Else Разделитель = vbLf End If End If
If TypeName(Диапазон) = "Range" Then Диапазон = Диапазон.Value If Not IsArray(Диапазон) Then СЦЕПДИАП_A = Диапазон: Exit Function ReDim arr(1 To UBound(Диапазон, 1) * UBound(Диапазон, 2)) If ПоСтолбцам Then For i = 1 To UBound(Диапазон, 2) For j = 1 To UBound(Диапазон, 1) If Len(Диапазон(j, i)) Then k = k + 1: arr(k) = Диапазон(j, i) Next: Next Else For j = 1 To UBound(Диапазон, 1) For i = 1 To UBound(Диапазон, 2) If Len(Диапазон(j, i)) Then k = k + 1: arr(k) = Диапазон(j, i) Next: Next End If СЦЕПДИАП_A = Join(arr, Разделитель) СЦЕПДИАП_A = Application.Trim(СЦЕПДИАП_A) End Function
ReDim arr(1 To UBound(Диапазон, 1) * UBound(Диапазон, 2)
[/vba]
Интересный подход абсолютно с другой стороны: сначала сделать массив-строку, а потом уже её сцеплять Join'ом. Надо будет попробовать подпилить-подсократить код на досуге. По поводу вытягивания из закрытых книг - не уверен, что это шибко нужно. Но если не даёт усложнения кода, то пусть будет
Про скорострельность, Андрей, ты по-моему абсолютно прав. Это UDF для применения в качестве формулы листа. И объединять она должна не тысячи ячеек, а от силы десяток-два.
А вот научить UDF-ку обрабатывать (склеивать) тексты ячеек из разбросанных по листу (-ам) ячеек было бы очень здорово. Тогда бы получилась усовершенствованная функция СЦЕПИТЬ. Но к сожалению тогда ей параметры надо задавать как ParamArray, а при таком типе аргументов нет возможности задать ещё и параметры "переносить" и "разделитель"
Quote (RAN)
[vba]
Code
ReDim arr(1 To UBound(Диапазон, 1) * UBound(Диапазон, 2)
[/vba]
Интересный подход абсолютно с другой стороны: сначала сделать массив-строку, а потом уже её сцеплять Join'ом. Надо будет попробовать подпилить-подсократить код на досуге. По поводу вытягивания из закрытых книг - не уверен, что это шибко нужно. Но если не даёт усложнения кода, то пусть будет
Про скорострельность, Андрей, ты по-моему абсолютно прав. Это UDF для применения в качестве формулы листа. И объединять она должна не тысячи ячеек, а от силы десяток-два.
А вот научить UDF-ку обрабатывать (склеивать) тексты ячеек из разбросанных по листу (-ам) ячеек было бы очень здорово. Тогда бы получилась усовершенствованная функция СЦЕПИТЬ. Но к сожалению тогда ей параметры надо задавать как ParamArray, а при таком типе аргументов нет возможности задать ещё и параметры "переносить" и "разделитель" Alex_ST
С уважением, Алексей MS Excel 2003 - the best!!!
Сообщение отредактировал Alex_ST - Воскресенье, 19.08.2012, 12:35
Ну-ка, ну-ка! А слабо сделать примерчик, в котором процедура может ОДНОВРЕМЕННО (ведь для функции листа именно так и делается) получать параметры и как ParamArray, и как обычные? Во всех учебниках по VBA написано, что если аргументы задаются как ParamArray, то других аргументов задать нельзя.
Конечно, можно извратиться и договориться, что первые 2-3 элемента массива - параметры склеивания, а остальные - склеиваемые элементы. Но это будет не удобно в использовании, т.к. все элементы UDF при её вводе юзером будут называться одинаково и нужно будет просто тупо помнить в какой последовательности их надо вводить.
Quote (nerv)
все возможно )
Ну-ка, ну-ка! А слабо сделать примерчик, в котором процедура может ОДНОВРЕМЕННО (ведь для функции листа именно так и делается) получать параметры и как ParamArray, и как обычные? Во всех учебниках по VBA написано, что если аргументы задаются как ParamArray, то других аргументов задать нельзя.
Конечно, можно извратиться и договориться, что первые 2-3 элемента массива - параметры склеивания, а остальные - склеиваемые элементы. Но это будет не удобно в использовании, т.к. все элементы UDF при её вводе юзером будут называться одинаково и нужно будет просто тупо помнить в какой последовательности их надо вводить.Alex_ST
А слабо сделать примерчик, в котором процедура может ОДНОВРЕМЕННО (ведь для функции листа именно так и делается) получать параметры и как ParamArray, и как обычные? Во всех учебниках по VBA написано, что если аргументы задаются как ParamArray, то других аргументов задать нельзя.
Вообще-то, брать "на слабо" не хорошо. Но, раз ты просишь пример: [vba]
Code
Sub nerv() MsgBox io(",", 1, 2, 3) End Sub
Function io(delimiter, ParamArray arr()) As String io = Join(arr, delimiter) End Function
[/vba]
RAN, ну вот зачем это извращение? [vba]
Code
Next: Next
[/vba] если так хочется записать в одну строчку, тогда уж [vba]
Code
Next j, i
[/vba]
Quote (Alex_ST)
А слабо сделать примерчик, в котором процедура может ОДНОВРЕМЕННО (ведь для функции листа именно так и делается) получать параметры и как ParamArray, и как обычные? Во всех учебниках по VBA написано, что если аргументы задаются как ParamArray, то других аргументов задать нельзя.
Вообще-то, брать "на слабо" не хорошо. Но, раз ты просишь пример: [vba]
Code
Sub nerv() MsgBox io(",", 1, 2, 3) End Sub
Function io(delimiter, ParamArray arr()) As String io = Join(arr, delimiter) End Function
[/vba]
RAN, ну вот зачем это извращение? [vba]
Code
Next: Next
[/vba] если так хочется записать в одну строчку, тогда уж [vba]
Все пробовал либо со всеми заполненными ячейками, либо с разделителем пробел. А лишние пробелы и Trim хорошо убирал. Сейчас попробовал сразделителем ";" - лишние появляются. Пришлось подкорректировать [vba]
Code
Function СЦЕПДИАП_A(Диапазон As Variant, Optional Разделитель As String = " ", _ Optional ПоСтолбцам As Boolean = False, Optional сПереносом As Boolean = False) As String '--------------------------------------------------------------------------------------- ' Author : RAN ' Purpose : Сцепляет текст ячеек из заданного диапазона ' Notes : Разделитель по умолчанию " " ' Notes : Optional ПоСтолбцам - просмотр по строкам(умолчание) и по столбцам ' Notes : Optional сПереносом по умолчанию - "нет" '--------------------------------------------------------------------------------------- Dim i&, j&, k&, arr If сПереносом Then If Разделитель <> " " Then Разделитель = Разделитель & vbLf Else Разделитель = vbLf End If End If If TypeName(Диапазон) = "Range" Then Диапазон = Диапазон.Value If Not IsArray(Диапазон) Then СЦЕПДИАП_A = Диапазон: Exit Function ReDim arr(1 To UBound(Диапазон, 1) * UBound(Диапазон, 2)) If ПоСтолбцам Then For i = 1 To UBound(Диапазон, 2) For j = 1 To UBound(Диапазон, 1) If Len(Диапазон(j, i)) Then k = k + 1: arr(k) = Диапазон(j, i) Next: Next Else For j = 1 To UBound(Диапазон, 1) For i = 1 To UBound(Диапазон, 2) If Len(Диапазон(j, i)) Then k = k + 1: arr(k) = Диапазон(j, i) Next: Next End If ReDim Preserve arr(1 To k) СЦЕПДИАП_A = Join(arr, Разделитель) СЦЕПДИАП_A = Application.Trim(СЦЕПДИАП_A) End Function
[/vba]
Все пробовал либо со всеми заполненными ячейками, либо с разделителем пробел. А лишние пробелы и Trim хорошо убирал. Сейчас попробовал сразделителем ";" - лишние появляются. Пришлось подкорректировать [vba]
Code
Function СЦЕПДИАП_A(Диапазон As Variant, Optional Разделитель As String = " ", _ Optional ПоСтолбцам As Boolean = False, Optional сПереносом As Boolean = False) As String '--------------------------------------------------------------------------------------- ' Author : RAN ' Purpose : Сцепляет текст ячеек из заданного диапазона ' Notes : Разделитель по умолчанию " " ' Notes : Optional ПоСтолбцам - просмотр по строкам(умолчание) и по столбцам ' Notes : Optional сПереносом по умолчанию - "нет" '--------------------------------------------------------------------------------------- Dim i&, j&, k&, arr If сПереносом Then If Разделитель <> " " Then Разделитель = Разделитель & vbLf Else Разделитель = vbLf End If End If If TypeName(Диапазон) = "Range" Then Диапазон = Диапазон.Value If Not IsArray(Диапазон) Then СЦЕПДИАП_A = Диапазон: Exit Function ReDim arr(1 To UBound(Диапазон, 1) * UBound(Диапазон, 2)) If ПоСтолбцам Then For i = 1 To UBound(Диапазон, 2) For j = 1 To UBound(Диапазон, 1) If Len(Диапазон(j, i)) Then k = k + 1: arr(k) = Диапазон(j, i) Next: Next Else For j = 1 To UBound(Диапазон, 1) For i = 1 To UBound(Диапазон, 2) If Len(Диапазон(j, i)) Then k = k + 1: arr(k) = Диапазон(j, i) Next: Next End If ReDim Preserve arr(1 To k) СЦЕПДИАП_A = Join(arr, Разделитель) СЦЕПДИАП_A = Application.Trim(СЦЕПДИАП_A) End Function