Макрос для разъединения ячеек в excel

В программе Excel присутствует кнопка для разъединения объединенных ячеек таблицы на закладке: «ГЛАВНАЯ»-«Выравнивание»-«Отменить объединение ячеек». Но что, если эту операцию нужно выполнять многократно, да еще и после нее заполнять данными ново созданные ячейки. Реализовать данную задачу вручную – это весьма затратное занятие по времени и силам. Здесь рационально воспользоваться макросом.

Макрос для разъединения объединенных ячеек в Excel

Допустим у нас уже имеется вполне читабельная таблица списка заказов, в которой имеются объединенные ячейки в столбце «Год». Пример, такой таблицы изображен ниже на рисунке:

таблица списка заказов.

Но нам необходимо преобразовать данную таблицу в стандартный формат, например, для создания отчета на основе сводной таблицы. Для этого откроем редактор Visual Basic (ALT+F11):

Visual Basic.

И вставим новый стандартный модуль используя инструмент в редакторе: «Insert»-«Module». А после чего запишем в модуль VBA код макроса для разъединения объединенных ячеек:

Sub RazdelitVstavit()
Dim adres As String
adres = ActiveCell.MergeArea.Address
If adres <> ActiveCell.Address Then
  ActiveCell.UnMerge
  ActiveCell.Copy
  ActiveSheet.Paste ActiveSheet.Range(adres)
  Application.CutCopyMode = False
End If
End Sub

модуль VBA код макроса.

Если мы хотим отменить объединение ячеек в столбце «Год» и заполнить созданные ячейки соответствующими значениями (годами), тогда перейдите на одну большую объединенную ячейку B2 и запустите макрос: «РАЗРАБОТЧИК»-«Код»-«Макросы»-«RazdelitVstavit»-«Выполнить».

отменить объединение ячеек.

В данном VBA коде макроса используется только одна переменная. Она хранит в себе адрес диапазона ячеек B2:B15 которые охватывает одна активная объединенная ячейка.

adres = ActiveCell.MergeArea.Address

Адрес активной ячейки отображается в поле «Имя» (напротив строки формул Excel). Но там не отображается полный адрес объединенной ячейки.

Адрес активной ячейки.

Для пользователя в поле «Имя» будет адрес отображаться одинаково, но в макросе их можно различить с помощью методов объекта ActiveCell.MergeArea.Addres. В зависимости какой тип активных ячеек будет возвращен тип адреса – одна ячейка или диапазон. Если активная ячейка не является объединенной, тогда в переменной будет храниться только адрес одной активной ячейки, а не целого диапазона. Далее макрос проверяет является ли текущая активная ячейка – объединенной, с помощью сравнения двух способов получения адреса для одной и той же активной ячейки. Тот способ, который передал адрес в переменную из метода объекта ActiveCell.MergeArea.Addres и обычный – ActiveCell.Addres. Если адрес в переменной и адрес получен обычным способом не совпадает, значит она является объединенной и код выполняется дальше.

С помощью метода объекта ActiveCell.UnMerge выполняется разъединение объединенной активной ячейки. Далее копируется ее содержимое и заполняется диапазон на листе, адрес которого получен из переменной, его же ранее содержала в себе объединенная активная ячейка. После копирования значения для объекта CutCopyMode устанавливается свойство False, чтобы прекратить процесс копирования. В результате таблица листа заказов будет иметь такой же вид как показано ниже на рисунке:

Пример.

Данный макрос позволяет разъединить объединенные ячейки, которые используют любое направление объединения: как по вертикали, так и полгоризонтали. Ее значение будет одинаково вставлено во все ячейки, созданные после разъединения.

Внимание! Объединенная ячейка может содержать в качестве значения формулы. В такие случаи после запуска макроса эта формула будет вставлена во все ячейки созданных в результате отмены объединения только из относительных ссылок в адресах, поскольку в переменной не будет символа $ необходимого для абсолютного или смешанного адреса.



Как разъединить объединенные ячейки сразу в нескольких диапазонах

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

Dim i As Long

Создадим цикл, который будет перемещаться по всем выделенным объединенным ячейкам:

For i = 1 To Selection.Count

В конце кода не забудем добавить конец цикла:

Next

Вместо ссылки на активную ячейку Active.Cell теперь будем использовать ссылку на очередную по счету ячейку в выделенном диапазоне: Selection.(i). Полная версия усовершенствованного макроса выглядит следующим образом:

Sub RazdelitVstavit()
Dim adres As String
Dim i As Long
For i = 1 To Selection.Count
  adres = Selection(i).MergeArea.Address
  If adres <> Selection(i).Address Then
    Selection(i).UnMerge
    Selection(i).Copy
    ActiveSheet.Paste ActiveSheet.Range(adres)
    Application.CutCopyMode = False
  End If
Next
End Sub

Пример2.

Цикл, который перемещается по каждой объединенной ячейке выделенного диапазона, каждый раз вызывает VBA код макроса для разъединения их диапазона объединения с учетом всех выше описанных условий.

Читайте также: Как объединить ячейки в Excel с помощью кода макроса VBA.

Так же стоит отметить, что выделенный диапазон может содержать необъединенные ячейки, которые будут просто игнорироваться макросом. Если бы мы не усовершенствовали наш макрос, то при выделении нескольких объединенных ячеек – разделилась бы только первая.

Правильно разъединить ячейки макросом

Модератор:Naeel Maqsudov

vadim245

Сообщения:99
Зарегистрирован:11 май 2007, 15:46

Нужно, чтобы при разъединении вертикально объединенных 3-х ячеек в каждой отдельной ячейке оказалось содержимое того, что было в объединенной ячейке.
Как?

Vikar

Сообщения:51
Зарегистрирован:24 апр 2007, 14:21

07 сен 2007, 14:14

Допустим объеденены ячейки A1:A3.
Тогда можно сделать так:

Код: Выделить всё

Sub Un_Merge()
    a = Cells(1, 1)
    Cells(1, 1).UnMerge
    Range(Cells(1, 1), Cells(3, 1)) = a
End Sub

Если нужно то же сделать с целым столбцом (или строкой), то вместо фиксированных значений a = Cells(1, 1) можно использовать переменные a = Cells(i, j) меняя их значения в цикле.

vadim245

Сообщения:99
Зарегистрирован:11 май 2007, 15:46

10 сен 2007, 07:43

Помогите пожалуйста с кодом — нужно работая только с выделенными ячейками —
разъединять (тоже чтоб то что было в общей ячейке попало во все три ячейки) последовательно идущие сверху вниз объединенные по 3 штуки.

Serge_Bliznykov

Сообщения:366
Зарегистрирован:31 авг 2007, 03:06

10 сен 2007, 10:30

vadim245 писал(а):Помогите пожалуйста с кодом — нужно работая только с выделенными ячейками —
разъединять (тоже чтоб то что было в общей ячейке попало во все три ячейки) последовательно идущие сверху вниз объединенные по 3 штуки.

вот рабочий код. может можно и короче, но, главное, работает.
Выделяете нужные ячейки (можно хоть весь столбец) и вызываете макрос

Код: Выделить всё

Sub Un_Merge_AllSelected()
 Dim c As Range
 Dim ma As Range
 Dim a As Variant
 For Each c In Selection
    With c
      If .MergeCells Then
        Set ma = .MergeArea
        a = c.Value
        .MergeArea.UnMerge
        ma.Value = a
      End If
    End With
 Next
End Sub

Может и мой корявенький макрос кому-нибудь пригодится. Обрабатывает таблицу HTML, в которой в полях одной записи встречаются и объединенные и отдельные ячейки. В результате получается запись в одной строке, а лишние удаляются. Для наглядности кусочек исходной таблицы в файле.  
Sub UnMergeAndPack()    ‘ Если в поле А есть объединенные строки (ячейки) разъединяет их  
   Dim iCell As Range      ‘ а из необъединенных ячеек собирает текст в верхнюю ячейку.После этого  
   Dim nRow As Long        ‘ удаляет строки с пустыми ячейками в столбце А  
   Dim howRow As Integer  
   Dim endRow As Long  
   Dim nCol As Integer  
   Dim addRow As Long  
   Dim iLastRow As Long  
   Application.DisplayStatusBar = True  
   ‘Установка текста строки состояния.  
   Application.StatusBar = «Преобразование таблицы»  
   Application.ScreenUpdating = False                 ‘Отключить обновление экрана  
   iLastRow = ActiveSheet.UsedRange.Row — 1 + ActiveSheet.UsedRange.Rows.Count  
   For Each iCell In Range(«A3:A» & iLastRow)  
       With iCell  
           If .MergeCells And .Address = .MergeArea.Cells(1).Address Then  ‘ Если ячейка Merge и она первая в Merge  
               nRow = iCell.Row                    ‘ номер первой строки в объкдиненной ячейке  
               howRow = .MergeArea.Rows.Count      ‘ кол-во строк в объединенной ячейке  
               endRow = nRow + howRow — 1          ‘ номер последней строки в объединенной ячейке  
                   For nCol = 1 To 7               ‘ обработка записи в полях  
                       If Cells(nRow, nCol).MergeCells = True Then ‘ Если ячейка объединенная,  
                           Cells(nRow, nCol).UnMerge   ‘ то разъединяем  
                           Else  
                              For addRow = nRow + 1 To endRow  ‘ если ячейки отдельные, то собираем из них текст в верхнюю ячейку  
                               Cells(nRow, nCol) = Cells(nRow, nCol) & Chr(10) & Cells(addRow, nCol)  
                              Next addRow  
                       End If  
                   Next nCol  
           End If  
       End With  
   Next  

         iLastRow = ActiveSheet.UsedRange.Row — 1 + ActiveSheet.UsedRange.Rows.Count  
   Range(«A2», «G» & iLastRow).AutoFilter Field:=1, Criteria1:=»=», Operator:=xlFilterValues ‘ Фильтрация по «Пусто» в поле А  
   Range(«A3:A» & iLastRow).SpecialCells(xlCellTypeVisible).EntireRow.Delete ‘ Удаление отфильтрованных строк  
   Range(«A2», «G» & iLastRow).AutoFilter ‘ Отключение автофильтра  

         ActiveSheet.UsedRange.Replace Empty, «insert», xlWhole ‘ Устанавливаем рабочую область  
   ActiveSheet.UsedRange.Replace «insert», Empty          ‘ по размерам таблицы  

         Columns(«B:G»).EntireColumn.AutoFit ‘ Автоподбор ширины ячеек  
   Cells.EntireRow.AutoFit             ‘ Автоподбор высоты ячеек  
Range(«H2»).Select  
   Application.ScreenUpdating = True  
   Application.StatusBar = False  

  End Sub

Разъединить объединенную ячейку и заполнить данными.

Aleksej

Дата: Вторник, 16.08.2016, 07:22 |
Сообщение № 1

Группа: Пользователи

Ранг: Участник

Сообщений: 69


Репутация:

0

±

Замечаний:
0% ±


Excel 2010

Всем доброго времени суток! :)

Нужна помощь знатоков VBA в написании макроса!

Задача:
1. Имеется файл Excel с объединенными ячейками (см. приложение)
2. Необходим макрос который находит объединенную ячейку, разъединяет её и во все получившиеся после разъединения ячейки записывает значение, которое было в объединенной ячейке. %)
3. В примере файла Excel: на листе1 исходные данные, на листе 2 как должно быть после применения макроса.

Спасибо! :)

К сообщению приложен файл:

3333333.xls
(49.5 Kb)

 

Ответить

Pelena

Дата: Вторник, 16.08.2016, 07:30 |
Сообщение № 2

Группа: Админы

Ранг: Местный житель

Сообщений: 18797


Репутация:

4284

±

Замечаний:
±


Excel 2016 & Mac Excel

Здравствуйте.
Последовательность действий такая:
— выделяем нужный диапазон (в примере А3:G29)
— снимаем объединение ячеек
— нажимаем F5 — Выделить — Пустые ячейки — ОК
— нажимаем на клавиатуре = и стрелку вверх. В строке формул должно получиться =A3
— нажимаем на клавиатуре сочетание Ctrl+Enter

Если нужен именно макрос, запишите действия макрорекодером
На эту тему можно посмотреть видео http://www.excelworld.ru/video….n_range


«Черт возьми, Холмс! Но как??!!»
Ю-money 41001765434816

 

Ответить

Aleksej

Дата: Вторник, 16.08.2016, 07:39 |
Сообщение № 3

Группа: Пользователи

Ранг: Участник

Сообщений: 69


Репутация:

0

±

Замечаний:
0% ±


Excel 2010

Pelena,

Цитата

Если нужен именно макрос, запишите действия макрорекодером

Это если несколько ячеек то можно и так, а если их сотни или тысячи в файле, как сделать чтоб макрос нашел все и преобразовал? %)

 

Ответить

Pelena

Дата: Вторник, 16.08.2016, 07:43 |
Сообщение № 4

Группа: Админы

Ранг: Местный житель

Сообщений: 18797


Репутация:

4284

±

Замечаний:
±


Excel 2016 & Mac Excel

Какая разница? Выделите весь диапазон с данными (Ctrl+*)


«Черт возьми, Холмс! Но как??!!»
Ю-money 41001765434816

 

Ответить

Aleksej

Дата: Вторник, 16.08.2016, 07:44 |
Сообщение № 5

Группа: Пользователи

Ранг: Участник

Сообщений: 69


Репутация:

0

±

Замечаний:
0% ±


Excel 2010

Pelena,

Цитата

Какая разница? Выделите весь диапазон с данными (Ctrl+*)

Сори, все разобрался. Спасибо за помощь. :)

 

Ответить

Aleksej

Дата: Вторник, 16.08.2016, 07:53 |
Сообщение № 6

Группа: Пользователи

Ранг: Участник

Сообщений: 69


Репутация:

0

±

Замечаний:
0% ±


Excel 2010

Pelena,

Цитата

Выделите весь диапазон с данными

Если всё выделять другая проблема появляется, ячейки которые не были объеденены тоже заполняются, а это не нужно.
Нужно, чтоб заполнялись ячейки которые были объединенными. :)

 

Ответить

Pelena

Дата: Вторник, 16.08.2016, 08:07 |
Сообщение № 7

Группа: Админы

Ранг: Местный житель

Сообщений: 18797


Репутация:

4284

±

Замечаний:
±


Excel 2016 & Mac Excel

Тогда приведите более реальный пример


«Черт возьми, Холмс! Но как??!!»
Ю-money 41001765434816

 

Ответить

nilem

Дата: Вторник, 16.08.2016, 08:15 |
Сообщение № 8

Группа: Авторы

Ранг: Старожил

Сообщений: 1612


Репутация:

563

±

Замечаний:
0% ±


Excel 2013, 2016

можно так попробовать
[vba]

Код

Sub ertert()
Dim r As Range
For Each r In Range(«A3:G» & Cells(Rows.Count, 1).End(xlUp).Row)
    If r.MergeCells Then
        With r.MergeArea
            .UnMerge
            .Value = r.Value
        End With
    End If
Next r
End Sub

[/vba]
правда, на тысячах ячеек будет, видимо, тормозить


Яндекс.Деньги 4100159601573

 

Ответить

Aleksej

Дата: Вторник, 16.08.2016, 08:27 |
Сообщение № 9

Группа: Пользователи

Ранг: Участник

Сообщений: 69


Репутация:

0

±

Замечаний:
0% ±


Excel 2010

Pelena,

Цитата

приведите более реальный пример

Изменил исходный файл — ЛИСТ1.
Возможно, чтоб макрос сам находил только объединенные ячейки, разъединял и заполнял их? :(
Потому что реальный исходный файл, там тысячи строк. Выложить настоящий не могу по понятным причинам.

К сообщению приложен файл:

0557251.xls
(45.5 Kb)

 

Ответить

Aleksej

Дата: Вторник, 16.08.2016, 08:33 |
Сообщение № 10

Группа: Пользователи

Ранг: Участник

Сообщений: 69


Репутация:

0

±

Замечаний:
0% ±


Excel 2010

nilem,

Цитата

можно так попробовать

Спасибо, вроде работает. :) На ошибки не проверял, но на первый взгляд все правильно. yes

Цитата

на тысячах ячеек будет, видимо, тормозит

Конечно не мгновенно, но это и не требуется. Ещё раз спасибо. :)

 

Ответить

Как разъединить объединенную ячейку и записать данные в каждую ячейку?

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

Прикладываю пример того как нужно (левая часть)

63c483743428e735658937.png

Пользуюсь библиотекой openpyxl
На данный момент код выглядит так, решение витает в воздухе но я в тупике.

#
    wb = openpyxl.open(f"excel/10_2023-01-08_excel_schedule.xlsx", data_only=False, read_only=False)
    ws = wb.active
    merged_cells = list(map(str, ws.merged_cells.ranges))   # Получаю список объединенных диапазонов
    # Разъединяю объединенные ячейки
    for item in merged_cells:
        ws.unmerge_cells(item)  
    wb.save("test_unmerge.xlsx") 
    print(merged_cells)


  • Вопрос задан

    16 янв.

  • 148 просмотров

Спасибо YK21

Сохранить значение из первой во временной переменной и подставить в цикле в каждую ячейку из дипазона

и Akina за советы

Подход простой.

В диапазоне проходите по ячейкам. Каждую проверяете на объединённость. Если очередная ячейка не объединена — сканируете дальше.

Если объединена, то:

Считываете и запоминаете значение как скалярную величину (не как массив! это важно).
Считываете и запоминаете адрес и размер.
Убираете объединение.
Выделяете отдельные ячейки, которые были раньше объединены (по адресу и размеру).
Вставляете значение в выделение — оно будет вставлено в каждую ячейку диапазона назначения.

Мое решение, возможно нелогичный велосипед, но работает

def prepare_sheet(sheet):
    merged_cells = list(map(str, sheet.merged_cells.ranges))  # Получаю список объединенных диапазонов
    # Разъединяю объединенные ячейки и дублирую запись
    for item in merged_cells:
        sheet.unmerge_cells(item)
        merged_cells_range = item.split(":")
        if merged_cells_range[0][0] == merged_cells_range[1][0]:
            letter = item.split(":").pop(0)[0]  # Символ столбца диапазона
            start = int(item.split(":").pop(0)[1:])  # Начало диапазона
            end = int(item.split(":").pop()[1:])  # Конец диапазона
            copy_cell = sheet[(letter + str(start))].value
            for n in range(start, end + 1):
                cell = letter + str(n)
                sheet[cell].value = copy_cell

Пригласить эксперта


  • Показать ещё
    Загружается…

16 апр. 2023, в 09:40

10000 руб./за проект

16 апр. 2023, в 08:25

20000 руб./за проект

16 апр. 2023, в 06:36

1000 руб./за проект

Минуточку внимания

Понравилась статья? Поделить с друзьями:
  • Макрос для гиперссылок excel
  • Макрос для разделения документа word на отдельные файлы
  • Макрос для генерации случайных чисел excel
  • Макрос для пустых ячеек excel
  • Макрос для выделения строки цветом в excel