Vba excel объединение в одну строку

Объединение диапазона ячеек в одну или построчно с помощью кода VBA Excel. Метод Range.Merge и свойство MergeCells. Отмена объединения ячеек. Примеры.

Метод Range.Merge

Метод Merge объекта Range объединяет ячейки заданного диапазона в одну или построчно из кода VBA Excel.

Синтаксис метода:

  1. Expression — выражение, возвращающее объект Range.
  2. Across — логическое значение, определяющее характер объединения ячеек:
    • True — ячейки объединяются построчно: каждая строка заданного диапазона преобразуется в одну ячейку.
    • False — весь диапазон преобразуется в одну ячейку. False является значением по умолчанию.

Преимущество метода Range.Merge перед свойством MergeCells заключается в возможности построчного объединения ячеек заданного диапазона без использования цикла.

Свойство MergeCells

Свойство MergeCells объекта Range применяется как для объединения ячеек, так и для его отмены.

Синтаксис свойства с присвоением значения:

Expression.MergeCells = Boolean

  1. Expression — выражение, представляющее объект Range.
  2. Boolean — логическое значение, определяющее необходимость объединения ячеек или его отмены:
    • True — объединение ячеек заданного диапазона.
    • False — отмена объединения ячеек.

С помощью свойства MergeCells можно из кода VBA Excel проверять диапазон (отдельную ячейку), входит ли он (она) в объединенную ячейку (True) или нет (False). Если проверяемый диапазон окажется комбинированным, то есть содержащим объединенные и необъединенные ячейки, компилятор сгенерирует ошибку.

Переменная Expression для отмены объединения ячеек с помощью свойства Range.MergeCells может представлять одну любую ячейку, входящую в объединенный диапазон.

Метод Range.UnMerge

Метод UnMerge объекта Range разделяет объединенную область на отдельные ячейки из кода VBA Excel.

Синтаксис метода:

Expression — выражение, возвращающее объект Range.

Переменная Expression для отмены объединения ячеек методом UnMerge может представлять одну любую ячейку, входящую в объединенный диапазон.

Примеры объединения ячеек и его отмены

Пример 1
Наблюдаем, как происходит объединение ячеек при разных значениях параметра Across:

Sub Primer1()

‘Объединяем ячейки диапазона «A1:D4» построчно

   Range(«A1:D4»).Merge (True)

‘Объединяем диапазон «A5:D8» в одну ячейку

‘Across принимает значение False по умолчанию

   Range(«A5:D8»).Merge

End Sub

Не забываем, что логическое выражение True можно заменить единичкой, а False — нулем.

Пример 2
Отменяем объединение ячеек в диапазонах из первого примера:

Sub Primer2()

   Range(«A1:D8»).MergeCells = False

End Sub

Пример 3
Предполагается, что перед этим примером отменено объединение ячеек кодом из предыдущего примера.

Sub Primer3()

‘Объединяем ячейки диапазона «A1:D4»

   Range(«A1:D4»).MergeCells = 1

‘Проверяем принадлежность диапазона

‘объединенной ячейке*

   MsgBox Range(«A1:C2»).MergeCells

   MsgBox Range(«A6:C7»).MergeCells

‘Ячейки диапазона «A5:D8»

‘можно объединить и так

   Cells(5, 1).Resize(4, 4).Merge

End Sub

*Если проверяемый диапазон окажется комбинированным, VBA Excel сгенерирует ошибку.
Пример 4
Отмена объединения ячеек с помощью метода Range.UnMerge:

Sub Primer4()

‘Объединяем ячейки диапазона «A1:C4»

    Range(«A1:C4»).Merge

    MsgBox «Ячейки диапазона ««A1:C4»» объединены»

‘Смотрим адрес диапазона, входящего в объединенную ячейку

    MsgBox Range(«A2»).MergeArea.Address

‘Отменяем объединение ячеек диапазона «A1:C4»

    Range(«B3»).UnMerge  ‘или: Range(«B3»).MergeArea.UnMerge

    MsgBox «Объединение ячеек диапазона ««A1:C4»» отменено»

End Sub

Предупреждение перед объединением

Если объединяемые ячейки не являются пустыми, пред их объединением появится предупреждающее диалоговое окно с сообщением: «В объединенной ячейке сохраняется только значение из верхней левой ячейки диапазона. Остальные значения будут потеряны.»

Пример 5
Наблюдаем появление предупреждающего окна:

Sub Primer5()

‘Отменяем объединение ячеек в диапазоне «A1:D4»

   Range(«A1:D4»).MergeCells = 0

‘Заполняем ячейки диапазона текстом

   Range(«A1:D4») = «Ячейка не пустая»

‘Объединяем ячейки диапазона «A1:D4»

   Range(«A1:D4»).MergeCells = 1

‘Наблюдаем предупреждающее диалоговое окно

End Sub

Предупреждающее окно перед объединением ячеек

Чтобы избежать появление предупреждающего окна, следует использовать свойство Application.DisplayAlerts, с помощью которого можно отказаться от показа диалоговых окон при работе кода VBA Excel.

Пример 6

Sub Primer6()

‘Отменяем объединение ячеек в диапазоне «A5:D8»

   Range(«A5:D8»).MergeCells = 0

‘Заполняем ячейки диапазона «A5:D8» текстом

   Range(«A5:D8») = «Ячейка не пустая»

Application.DisplayAlerts = False

   Range(«A5:D8»).MergeCells = 1

Application.DisplayAlerts = True

End Sub

Теперь все прошло без появления диалогового окна. Главное, не забывать после объединения ячеек возвращать свойству Application.DisplayAlerts значение True.

Кстати, если во время работы VBA Excel предупреждающее окно не показывается, это не означает, что оно игнорируется. Просто программа самостоятельно принимает к действию ответное значение диалогового окна по умолчанию.

Хитрости »

5 Август 2013              151201 просмотров


Сцепить много ячеек с указанным разделителем

Часто бывает ситуация, когда необходимо из трех разных столбцов сцепить данные в одну строку с разделителем. Допустим в А1 Фамилия, в В1Имя, в С1Отчество, а надо получить все вместе Фамилия Имя Отчество. Как обычно в Excel объединяют значения нескольких ячеек в одну? Правильно, при помощи функции СЦЕПИТЬ или при помощи амперсанда:
=СЦЕПИТЬ(A1;» «;B1;» «;C1;» «)
=A1&» «&B1&» «&C1&» «
Это достаточно эффективно, если необходимо сцепить значения из трех-пяти ячеек. А если ячеек 50? Или того больше? Не очень удобно объединять их все описанными выше способами. А других встроенных функций в Excel для подобных операций не существует. С момента написания статьи Microsoft порадовал нас новыми функциями и теперь в составе функций есть функция ОБЪЕДИНИТЬ(TEXTJOIN), которая способна решить задачу без лишних телодвижений.
=ОБЪЕДИНИТЬ(«, «;ИСТИНА;A2:A100)
=TEXTJOIN(«, «,TRUE,A2:A100)

    Разделитель(«, «) — разделитель, с которым объединять текст из указанных ячеек
    Пропускать пустые(ИСТИНА) — указывает пропускать ли пустые ячейки. Т.е. если указано ИСТИНА или 1(а так же если аргумент вовсе не указан) — пустые ячейки будут пропускаться и не попадут в общую строку сцепки. Если указано ЛОЖЬ — сцепляться будут все ячейки, независимо от их содержимого. Например, если указать три ячейки A1:A3 в которых А2 пустая, то при указании ИСТИНА результат будет таким: «один, два». Если указать ЛОЖЬ, то пустая ячейка тоже попадет в сцепку: «один, , два».
    Так же этот аргумент удобен, если неизвестен заранее размер диапазона сцепления. Можно указать ячейки чуть с запасом(A1:A300) и тогда сцепляться будут только ячейки заполненного диапазона.
    Текст(A2:A100) — указывается непосредственно диапазон либо текст для сцепления. Этот аргумент расширяемый — т.е. можно указать не один диапазон, а несколько или просто текст: =ОБЪЕДИНИТЬ(«, «;ИСТИНА;A2:A100;B2:B70;»текст»)

Правда и здесь не все так радужно: эта функция доступна только пользователям версий 2019 и выше, а так же офиса 365.


Поэтому я написал функцию пользователя, которая сцепляет данные из указанных ячеек в одну строку и использовать её можно в любой версии офиса. Чем отличается от стандартной функции СЦЕПИТЬ()? Тем, что в качестве ячеек для сцепки указывается не каждая из ячеек по очереди, а сразу весь диапазон с возможностью указания разделителя между значениями каждой ячейки. Так же, в функции сразу заложен алгоритм пропуска пустых ячеек и возможность сцеплять исключительно уникальные значения — т.е. в результате будут сцепляться только те ячейки, значения которых ранее еще не были добавлены в сцепку.

Option Explicit
'---------------------------------------------------------------------------------------
' Procedure : СцепитьМного
'             http://www.excel-vba.ru
' Purpose   : Функция сцепляет все указанные ячейки в одну с указанным разделителем.
' Аргументы функции:
' Диапазон    — диапазон ячеек, значения которых необходимо объединить в строку.
' Разделитель — необязательный аргумент.
'               Один или несколько символов, которые будут вставлены между каждым словом.
'               По умолчанию пробел.
' БезПовторов — необязательный аргумент.
'               Если указан как ИСТИНА или 1 — в результирующей строке будут значения без дубликатов.
'               Для английской локализации данный параметр указывается как TRUE и FALSE соответственно.
'---------------------------------------------------------------------------------------
Function СцепитьМного(Диапазон As Range, Optional Разделитель As String = " ", Optional БезПовторов As Boolean = False)
    Dim avData, lr As Long, lc As Long, sRes As String
    Dim oDict As Object, sTmpStr
    Set oDict = CreateObject("Scripting.Dictionary")
    oDict.comparemode = 1
 
    avData = Диапазон.Value
    If Not IsArray(avData) Then
        СцепитьМного = avData
        Exit Function
    End If
 
    For lc = 1 To UBound(avData, 2)
        For lr = 1 To UBound(avData, 1)
            If Len(avData(lr, lc)) Then
                sRes = sRes & Разделитель & avData(lr, lc)
                If БезПовторов Then
                    If Not oDict.exists(avData(lr, lc)) Then
                        oDict.Add avData(lr, lc), 0&
                    End If
                End If
            End If
        Next lr
    Next lc
    If Len(sRes) Then
        sRes = Mid(sRes, Len(Разделитель) + 1)
    End If
 
    If БезПовторов Then
        sRes = ""
        sTmpStr = oDict.keys
        For lr = LBound(sTmpStr) To UBound(sTmpStr)
            sRes = sRes & IIf(sRes <> "", Разделитель, "") & sTmpStr(lr)
        Next lr
    End If
    СцепитьМного = sRes
End Function

Чтобы правильно использовать приведенный код, необходимо сначала ознакомиться со статьей Что такое функция пользователя(UDF)?. Вкратце: скопировать текст кода выше, перейти в редактор VBA(Alt+F11) -создать стандартный модуль(InsertModule) и в него вставить скопированный текст. После чего функцию можно будет вызвать из Диспетчера функций(Shift+F3), отыскав её в категории Определенные пользователем (User Defined Functions).

Синтаксис функции:
=СцепитьМного(A2:A100;», «;ИСТИНА)

Диапазон — диапазон ячеек, значения которых необходимо объединить в строку.
Разделитель — необязательный аргумент. Один или несколько символов, которые будут вставлены между каждым словом. По умолчанию пробел.
БезПовторов — необязательный аргумент. Если указан как ИСТИНА или 1 — в результирующей строке будут значения без дубликатов. Например, из значений Сидоров, Петров, Сидоров, Иванов в результат попадут только Сидоров, Петров, Иванов. Если ЛОЖЬ или 0 — будут выведены все значения. Для английской локализации данный параметр указывается как TRUE и FALSE соответственно.

Скачать пример

  СцепитьМного.xls (52,5 KiB, 11 996 скачиваний)


Если необходимо объединять значения ячеек из «рваных»(несмежных) диапазонов(выделенных через Ctrl), то код нужно немного изменить:

Option Explicit
'---------------------------------------------------------------------------------------
' Procedure : СцепитьМного
'             http://www.excel-vba.ru
' Purpose   : Функция сцепляет все указанные ячейки в одну с указанным разделителем. Допускается указание несмежных диапазонов
' Аргументы функции:
' Диапазон    — диапазон ячеек, значения которых необходимо объединить в строку.
' Разделитель — необязательный аргумент.
'               Один или несколько символов, которые будут вставлены между каждым словом.
'               По умолчанию пробел.
' БезПовторов — необязательный аргумент.
'               Если указан как ИСТИНА или 1 — в результирующей строке будут значения без дубликатов.
'               Для английской локализации данный параметр указывается как TRUE и FALSE соответственно.
'---------------------------------------------------------------------------------------
Function СцепитьМного(диапазон As Range, Optional разделитель As String = " ", Optional БезПовторов As Boolean = False)
    Dim avData, lr As Long, lc As Long, sRes As String
    Dim ra As Range
 
    For Each ra In диапазон.Areas
      avData = ra.Value
      If Not IsArray(avData) Then
          ReDim avData(1 To 1, 1 To 1)
          avData(1, 1) = ra.Value
      End If
 
      For lc = 1 To UBound(avData, 2)
          For lr = 1 To UBound(avData, 1)
              If Len(avData(lr, lc)) Then
                  sRes = sRes & разделитель & avData(lr, lc)
              End If
          Next lr
      Next lc
    Next
    If Len(sRes) Then
        sRes = Mid(sRes, Len(разделитель) + 1)
    End If
 
    If БезПовторов Then
        Dim oDict As Object, sTmpStr
        Set oDict = CreateObject("Scripting.Dictionary")
        sTmpStr = Split(sRes, разделитель)
        On Error Resume Next
        For lr = LBound(sTmpStr) To UBound(sTmpStr)
            oDict.Add sTmpStr(lr), sTmpStr(lr)
        Next lr
        sRes = ""
        sTmpStr = oDict.Keys
        For lr = LBound(sTmpStr) To UBound(sTmpStr)
            sRes = sRes & IIf(sRes <> "", разделитель, "") & sTmpStr(lr)
        Next lr
    End If
    СцепитьМного = sRes
End Function

Однако в таком случае слегка изменится и синтаксис — такие диапазоны обязательно надо будет записывать в скобках:
Синтаксис функции:
=СцепитьМного((A2:A100;F4:F60;Y2:Z43);», «;ИСТИНА)
Иначе функция просто не сработает и выдаст ошибку #ЗНАЧ!(#VALUE!)


И еще одна реализация — в ней допускается указывать не только отдельные диапазоны, но и вообще все что угодно(ячейки, отдельный текст, числа и т.п.). Единственная проблема — в этой функции иначе организован порядок аргументов: сначала указывается разделитель, а уже потом значения для сцепления. Более подробно эта функция рассмотрена в статье Что такое функция пользователя(UDF)?. Так же эта функция не убирает дубли, что впрочем, не так сложно добавить, ориентируясь на функции выше.

Function ОбъединитьВсеСРазделителем(Разделитель As String, ParamArray Значения()) As String
    Dim result As String, arg, x, rc As Range
    For Each arg In Значения
        Select Case TypeName(arg)
        Case "Range"                     'это диапазон
            'цикл по всем ячейкам
            For Each rc In arg.Cells
                If result = "" Then
                    result = rc.Value
                Else
                    result = result & Разделитель & rc.Value
                End If
            Next
        Case "Variant()"                 'это произвольный массив({"а";"б";"в"})
            'цикл по всем ячейкам
            For Each x In arg
                If result = "" Then
                    result = x
                Else
                    result = result & Разделитель & x
                End If
            Next
        Case Else 'это любой другой тип
            'суммируем
            If result = "" Then
                result = arg
            Else
                result = result & Разделитель & arg
            End If
        End Select
    Next
    ОбъединитьВсеСРазделителем = result
End Function

Также см.:
Сцепить_МН
Как сцепить несколько значений в одну ячейку по критерию? СцепитьЕсли
Что такое функция пользователя(UDF)?


Статья помогла? Поделись ссылкой с друзьями!

  Плейлист   Видеоуроки


Поиск по меткам



Access
apple watch
Multex
Power Query и Power BI
VBA управление кодами
Бесплатные надстройки
Дата и время
Записки
ИП
Надстройки
Печать
Политика Конфиденциальности
Почта
Программы
Работа с приложениями
Разработка приложений
Росстат
Тренинги и вебинары
Финансовые
Форматирование
Функции Excel
акции MulTEx
ссылки
статистика

Angrynik

26 / 2 / 0

Регистрация: 04.04.2012

Сообщений: 34

1

Как соединить две строки в одну

26.06.2012, 23:28. Показов 59697. Ответов 6

Метки нет (Все метки)


Студворк — интернет-сервис помощи студентам

Суть такова — есть 2е переменные, нужно склеить их в одну. Например

Visual Basic
1
2
Per1 = "Hello "
Per2 = "World!"

Нужно получить третью переменную «Hello World!»



0



Programming

Эксперт

94731 / 64177 / 26122

Регистрация: 12.04.2006

Сообщений: 116,782

26.06.2012, 23:28

6

mobile

Эксперт MS Access

26777 / 14456 / 3192

Регистрация: 28.04.2012

Сообщений: 15,782

26.06.2012, 23:31

2

Конкатенация строк умеет много

Visual Basic
1
Per3=Per1 & Per2



1



mc-black

2784 / 716 / 106

Регистрация: 04.02.2011

Сообщений: 1,443

26.06.2012, 23:32

3

Visual Basic
1
Per3 = Per1 & Per2



1



26 / 2 / 0

Регистрация: 04.04.2012

Сообщений: 34

26.06.2012, 23:53

 [ТС]

4

Еще вопрос. Можно ли добавить символ новой строки? Т.е. что бы выводило переменную «Hello World!» как

Hello
World!



0



mobile

Эксперт MS Access

26777 / 14456 / 3192

Регистрация: 28.04.2012

Сообщений: 15,782

26.06.2012, 23:56

5

Цитата
Сообщение от Angrynik
Посмотреть сообщение

Еще вопрос. Можно ли добавить символ новой строки? Т.е. что бы выводило переменную «Hello World!» как

Hello
World!

И это не запрещено.

Visual Basic
1
Per3=Per1 & vbcrlf & Per2



1



Dragokas

Эксперт WindowsАвтор FAQ

17992 / 7618 / 890

Регистрация: 25.12.2011

Сообщений: 11,351

Записей в блоге: 17

27.06.2012, 00:42

6

Лучший ответ Сообщение было отмечено как решение

Решение

Если все переменные типа String, можно пользоваться плюсами:

Visual Basic
1
Per3=Per1 + vbcrlf + Per2



1



4038 / 1423 / 394

Регистрация: 07.08.2013

Сообщений: 3,541

28.09.2016, 22:35

7

Для общего развития
В VBA при конкатенации строк через «+» есть особенности
«строка» & Null Результат «Строка»
«строка» + Null Результат Null
более того «+» при объединении строк ругается на числовые данные и данные дата/время и их нужно конвертировать с помощью CStr или Str



1



IT_Exp

Эксперт

87844 / 49110 / 22898

Регистрация: 17.06.2006

Сообщений: 92,604

28.09.2016, 22:35

7

This question comes from a comment under Range.Formula= in VBA throws a strange error.

I wrote that program by trial-and-error so I naturally tried + to concatenate strings.

But is & more correct than + for concatenating strings?

Teamothy's user avatar

Teamothy

1,9903 gold badges15 silver badges24 bronze badges

asked Nov 13, 2009 at 7:31

ilya n.'s user avatar

& is always evaluated in a string context, while + may not concatenate if one of the operands is no string:

"1" + "2" => "12"
"1" + 2   => 3
1 + "2"   => 3
"a" + 2   => type mismatch

This is simply a subtle source of potential bugs and therefore should be avoided. & always means «string concatenation», even if its arguments are non-strings:

"1" & "2" => "12"
"1" &  2  => "12"
 1  & "2" => "12"
 1  &  2  => "12"
"a" &  2  => "a2"

answered Nov 13, 2009 at 7:34

Joey's user avatar

JoeyJoey

341k85 gold badges687 silver badges681 bronze badges

2

The main (very interesting) difference for me is that:
"string" & Null -> "string"
while
"string" + Null -> Null

But that’s probably more useful in database apps like Access.

answered Jun 5, 2018 at 15:48

iDevlop's user avatar

iDevlopiDevlop

24.6k11 gold badges89 silver badges147 bronze badges

There is the concatenate function. For example

=CONCATENATE(E2,"-",F2)

But the & operator always concatenates strings. + often will work, but if there is a number in one of the cells, it won’t work as expected.

Community's user avatar

answered Nov 13, 2009 at 7:38

wallyk's user avatar

wallykwallyk

56.6k16 gold badges85 silver badges147 bronze badges

I took care to develop a VBA code, I do not know your level in Excel .. I also took care to make the code as simple as possible.
In this code (below) :
Sheets1 is the sheet where the data is presented and read.
Sheet2 is the sheet where the data is written.
RowsColsTransformer() is the procedure to run.

‘VBA:

Sub RowsColsTransformer()
Dim CurrentLine As Integer
Dim CurrentLine2 As Integer
Dim CurrentCols2 As Integer
Dim Max As Integer

CurrentLine2 = 2
CurrentCols2 = 1
Max = 10 ' -- Number of lines in the sheet where data will be read.
For CurrentLine = 2 To Max
    Sheets(2).Cells(CurrentLine2, CurrentCols2) = Sheets(1).Cells(CurrentLine, 1)
    CurrentCols2 = CurrentCols2 + 1
    Sheets(2).Cells(CurrentLine2, CurrentCols2) = Sheets(1).Cells(CurrentLine, 2)
    CurrentCols2 = CurrentCols2 + 1
    Sheets(2).Cells(CurrentLine2, CurrentCols2) = Sheets(1).Cells(CurrentLine, 3)
    CurrentCols2 = CurrentCols2 + 1
    Sheets(2).Cells(CurrentLine2, CurrentCols2) = Sheets(1).Cells(CurrentLine, 4)
    CurrentCols2 = CurrentCols2 + 1
    Sheets(2).Cells(CurrentLine2, CurrentCols2) = Sheets(1).Cells(CurrentLine, 5)
    CurrentCols2 = CurrentCols2 + 1
    Sheets(2).Cells(CurrentLine2, CurrentCols2) = Sheets(1).Cells(CurrentLine, 6)
    CurrentCols2 = CurrentCols2 + 1
    Sheets(2).Cells(CurrentLine2, CurrentCols2) = Sheets(1).Cells(CurrentLine, 7)
    CurrentCols2 = CurrentCols2 + 1
    Sheets(2).Cells(CurrentLine2, CurrentCols2) = Sheets(1).Cells(CurrentLine, 8)
    CurrentCols2 = CurrentCols2 + 1
    '-- Reintialize Line and Column
    If CurrentLine Mod 4 = 1 And CurrentLine > 1 Then
        CurrentLine2 = CurrentLine2 + 1
        CurrentCols2 = 1
    End If
Next CurrentLine
End Sub

Holp this can help.

Понравилась статья? Поделить с друзьями:
  • Vba excel общая переменная
  • Vba excel найти все ячейки со значением
  • Vba excel обход ошибок
  • Vba excel найти все значения в диапазоне
  • Vba excel обращение к ячейке по индексу