Автоподбор высоты объединенной ячейки с помощью кода VBA Excel, когда метод AutoFit не работает. Обработка ячеек по списку адресов из массива.
Автоподбор высоты ячейки
К сожалению, в объединенных ячейках метод VBA Excel AutoFit не работает. Но есть возможность подогнать ширину или высоту такой ячейки под длину текста с помощью макроса.
Здесь мы рассмотрим макрос для автоподбора высоты ячейки, объединенной с другими по горизонтали в одной строке, которые обычно используются в заголовках электронных таблиц Excel. Для объединенной ячейки должен быть задан перенос текста по словам: Формат ячеек >> Выравнивание >> переносить текст
.
Высота ячейки будет такой, чтобы уместились все строки, на которые будет разбит контент в зависимости от ширины объединенной ячейки.
Для решения задачи по автоподбору высоты необходимо с помощью кода VBA определить:
- Длину текста (количество символов) в объединенной ячейке.
- Ширину объединенной ячейки. Длина одного символа текста со шрифтом и его размером по умолчанию приблизительно соответствует длине символа, в котором измеряется ширина ячейки.
- Размер шрифта, чтобы рассчитать коэффициент, увеличивающий или уменьшающий высоту ячейки в зависимости от его (шрифта) размера.
Макрос VBA Excel для автоподбора высоты ячейки с учетом размера используемого шрифта:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
Sub PodborVysoty() Dim myCell As Range, myLen As Integer, _ myWidth As Single, k As Single, n As Single With Selection ‘Задаем объединенной ячейке перенос текста .WrapText = True ‘Задаем объединенной ячейке такую высоту строки, ‘чтобы умещалась одна строка текста .RowHeight = ActiveCell.Font.Size * 1.3 End With myLen = Len(CStr(ActiveCell)) For Each myCell In Selection myWidth = myWidth + myCell.ColumnWidth Next n = 10 k = ActiveCell.Font.Size / n Selection.RowHeight = Selection.RowHeight * _ WorksheetFunction.RoundUp(myLen * k / myWidth, 0) End Sub |
Переменные:
- myCell — отдельная ячейка в объединенной;
- myLen — длина текста в активной ячейке;
- myWidth — ширина объединенной ячейки;
- k — коэффициент, вносящий поправку в зависимости от размера шрифта;
- n — размер шрифта по умолчанию.*
* Это не точное значение: у меня по умолчанию установлен шрифт Calibri размером 11, но точнее код работает с n = 10. Значение переменной n подбирается опытным путем, так как длина текста зависит от процентного соотношения широких и узких символов, если шрифт не моноширинный. Переменной n можно присваивать и дробные значения для более точного автоподбора высоты.
Максимальная высота строки — 409,5. Если расчетная высота объединенной ячейки окажется больше, будет сгенерирована ошибка.
Данный код VBA Excel работает с выделенной ячейкой. Вы можете задать список адресов объединенных ячеек и пройтись макросом по каждой из них.
Обработка списка ячеек
Укажите список объединенных ячеек в качестве аргументов функции Array. Для списка используйте адреса только первых ячеек из состава объединенных.
Sub ObkhodYacheyek1() Sub ObkhodYacheyek() Dim myCell() As Variant, myElem As Variant myCell = Array(«A1», «A3», «A5») For Each myElem In myCell Range(myElem).Select Call PodborVysoty Next End Sub |
Переменные:
- myCell — массив со списком адресов объединенных ячеек;
- myElem — используется как элемент массива myCell.
Макрос ObkhodYacheyek по адресам из списка обращается к каждой ячейке по очереди, выделяет ее и запускает код автоподбора высоты PodborVysoty.
Если выделить диапазон объединенных ячеек по одной, удерживая клавишу Ctrl, то запустить код автоподбора высоты можно с помощью следующего макроса:
Sub ObkhodYacheyek2() Dim myCell() As String, myElem As Variant myCell = Split(Selection.Address, «,») For Each myElem In myCell Range(myElem).Select Call PodborVysoty Next End Sub |
Хитрости »
10 Август 2016 35691 просмотров
Подбор высоты строки/ширины столбца объединенной ячейки
Для начала немного теории. Если в ячейках листа Excel записан некий длинный текст, то обычно устанавливают перенос на строки(вкладка Главная -группа Выравнивание —Перенос текста), чтобы текст не растягивался на весь экран, а умещался в ячейке. При этом высота ячейки тоже должна измениться, чтобы отобразить все содержимое. Если речь идет всего об одной простой ячейке — проблем не возникает. Обычно, чтобы установить высоту строки на основании содержимого ячейки, достаточно навести курсор мыши в заголовке строк на границу строки(курсор приобретет вид направленных в разные стороны стрелок — ) и дважды быстро щелкнуть левой кнопкой мыши. Тоже самое можно сделать и для ширины столбцов.
Но с объединенными ячейками такой фокус не прокатывает — ширина и высота для этих ячеек так не подбирается, сколько ни щелкай и приходится вручную подгонять каждую, чтобы текст ячейки отображался полностью:
Стандартными средствами такой автоподбор не сделать, но вот при помощи VBA — без проблем. Ниже приведена функция, которая поможет подобрать высоту и ширину объединенных ячеек на основании их содержимого.
'--------------------------------------------------------------------------------------- ' Procedure : RowHeightForContent ' Author : The_Prist(Щербаков Дмитрий) ' http://www.excel-vba.ru ' Purpose : Функция подбирает высоту строки/ширину столбца объединенных ячеек по содержимому '--------------------------------------------------------------------------------------- Function RowColHeightForContent(rc As Range, Optional bRowHeight As Boolean = True) 'rc - ячейка, высоту строки или ширину столбца которой необходимо подобрать 'bRowHeight - True - если необходимо подобрать высоту строки ' False - если необходимо подобрать ширину столбца Dim OldR_Height As Single, OldC_Widht As Single Dim MergedR_Height As Single, MergedC_Widht As Single Dim CurrCell As Range Dim ih As Integer Dim iw As Integer Dim NewR_Height As Single, NewC_Widht As Single Dim ActiveCellHeight As Single If rc.MergeCells Then With rc.MergeArea 'если ячейка объединена 'запоминаем кол-во столбцов iw = .Columns(.Columns.Count).Column - rc.Column + 1 'запоминаем кол-во строк. ih = .Rows(.Rows.Count).Row - rc.Row + 1 'Определяем высоту и ширину объединения ячеек MergedR_Height = 0 For Each CurrCell In .Rows MergedR_Height = CurrCell.RowHeight + MergedR_Height Next MergedC_Widht = 0 For Each CurrCell In .Columns MergedC_Widht = CurrCell.ColumnWidth + MergedC_Widht Next 'запоминаем высоту и ширину первой ячейки из объединенных OldR_Height = .Cells(1, 1).RowHeight OldC_Widht = .Cells(1, 1).ColumnWidth 'отменяем объединение ячеек .MergeCells = False 'назначаем новую высоту и ширину для первой ячейки .Cells(1).RowHeight = MergedR_Height .Cells(1, 1).EntireColumn.ColumnWidth = MergedC_Widht 'если необходимо изменить высоту строк If bRowHeight Then '.WrapText = True 'раскомментировать, если необходимо принудительно выставлять перенос текста .EntireRow.AutoFit NewR_Height = .Cells(1).RowHeight 'запоминаем высоту строки .MergeCells = True If OldR_Height < (NewR_Height / ih) Then .RowHeight = NewR_Height / ih Else .RowHeight = OldR_Height End If 'возвращаем ширину столбца первой ячейки .Cells(1, 1).EntireColumn.ColumnWidth = OldC_Widht Else 'если необходимо изменить ширину столбца .EntireColumn.AutoFit NewC_Widht = .Cells(1).EntireColumn.ColumnWidth 'запоминаем ширину столбца .MergeCells = True If OldC_Widht < (NewC_Widht / iw) Then .ColumnWidth = NewC_Widht / iw Else .ColumnWidth = OldC_Widht End If 'возвращаем высоту строки первой ячейки .Cells(1, 1).RowHeight = OldR_Height End If End With End If End Function
Пара замечаний:
- т.к. нельзя выставить и автоширину и автовысоту — то функция подбирает либо высоту, либо ширину, что логично
- чтобы подбор по высоте ячеек сработал, для ячейки должен быть выставлен перенос строк(вкладка Главная -группа Выравнивание —Перенос текста). Если ячеек много и выставлять вручную лень — можно просто убрать апостроф перед точкой в строке:’.WrapText = True ‘раскомментировать, если необходимо принудительно выставлять перенос текстатогда код сам проставит переносы. Но тут следует учитывать, что в данном случае перенос будет выставлен для всех ячеек, что не всегда отвечает условиям
- функция подбирает высоту и ширину исключительно для объединенных ячеек. Если ячейка не объединена — код оставит её без изменений
Теперь о том, как это работает и как применять. Для начала необходимо приведенный выше код функции вставить в стандартный модуль. Сама по себе функция работать не будет — её надо вызывать из другого кода, который определяет какие ячейки обрабатывать. В качестве такого кода я предлагаю следующий:
Sub ChangeRowColHeight() Dim rc As Range Dim bRow As Boolean bRow = (MsgBox("Изменять высоту строк?", vbQuestion + vbYesNo, "www.excel-vba.ru") = vbYes) 'bRow = True: для изменения высоты строк 'bRow = False: для изменения ширины столбцов Application.ScreenUpdating = False For Each rc In Selection RowColHeightForContent rc, bRow Next Application.ScreenUpdating = True End Sub
Этот код также необходимо вставить в стандартный модуль. Теперь его можно будет вызвать из этой книги, нажатием клавиш Alt+F8 и выбрав ChangeRowColHeight, или создав на листе кнопку и назначив ей макрос. После этого достаточно будет выделить диапазон ячеек, среди которых есть объединенные и вызвать макрос ChangeRowColHeight. Для всех объединенных ячеек в выделенном диапазоне будет подобрана высота или ширина.
Чтобы было нагляднее — я приложил пример, в котором помимо самих кодов есть вырезка из стандартной накладной. Именно в таких документах наиболее часто встречаются подобные казусы и необходимость подбирать высоту и ширину объединенных ячеек.
Скачать пример:
Tips_Macro_HeightWidthInMergeCell.xls (64,0 KiB, 3 476 скачиваний)
Если подобную операцию приходится производить постоянно — советую коды записать в надстройку: Как создать свою надстройку?. Так же можно воспользоваться уже готовым решением в составе MulTEx — Высота/Ширина объединенной ячейки.
Статья помогла? Поделись ссылкой с друзьями!
Видеоуроки
Поиск по меткам
Access
apple watch
Multex
Power Query и Power BI
VBA управление кодами
Бесплатные надстройки
Дата и время
Записки
ИП
Надстройки
Печать
Политика Конфиденциальности
Почта
Программы
Работа с приложениями
Разработка приложений
Росстат
Тренинги и вебинары
Финансовые
Форматирование
Функции Excel
акции MulTEx
ссылки
статистика
Цитата |
---|
cuprum написал: Если же высота строки заведомо больше чем нужно, |
можно просто в этом блоке:
Код |
---|
If OldR_Height < (NewR_Height / ih) Then .RowHeight = NewR_Height / ih Else .RowHeight = OldR_Height End If |
оставить только одну строку:
Код |
---|
.RowHeight = NewR_Height / ih |
т.е. убрать условие на проверку высоты строки ДО, подбирая таким образом подо все строки без исключения. Не очень правильный подход, на мой взгляд, особенно если собрались для нескольких столбцов сразу применять. Если объединенные ячейки будут в разных столбцах, то высота будет подобрана на основании объединенных ячеек в последних столбцах.
Правильнее всего делать иначе: если это возможно, то перед выполнением цикла по ячейкам добавить строку установки стандартной высоты:
Код |
---|
Sub ChangeRowColHeight() Dim rc As Range Dim bRow As Boolean bRow = (MsgBox("Изменять высоту строк?", vbQuestion + vbYesNo, "www.excel-vba.ru") = vbYes) 'bRow = True: для изменения высоты строк 'bRow = False: для изменения ширины столбцов Application.ScreenUpdating = False Selection.EntireRow.RowHeight = 12.75 For Each rc In Selection RowColHeightForContent rc, bRow Next Application.ScreenUpdating = True End Sub |
еще правильнее делать это только в случае, если в строке есть хоть одна объединенная ячейка. Лень сейчас писать такой код, если честно. Но не сложный — можно просто выдернуть части из предложенных кодов и все.
Автоподбор высоты объединённых ячеек
Предлагаю 2 варианта автоподбора высоты объединённых ячеек в Excel
(оба работаю не идеально, — но, тем не менее, в большинстве случаев и этого будет достаточно)
1 вариант: (разъединение, автоподбор, объединение)
Sub AutoFitMergeAreaSize(ByRef cell As Range) Dim ra As Range: Set ra = cell.MergeArea cell.UnMerge cell.EntireRow.AutoFit ra.Merge End Sub Sub ПримерИспользования_АвтоподборВысотыОбъединённойЯчейки() AutoFitMergeAreaSize ActiveCell AutoFitMergeAreaSize [d3] End Sub
2 вариант:(то же самое, по сути, только кода побольше)
Sub AutoFitMergedCellRowHeight(ByRef ra As Range) Dim CurrCell As Range, cell As Range, ma As Range: Dim col As Range, ro As Range For Each ro In ra.Rows maxRH = 0 For Each cell In ro.Cells If cell.MergeCells And cell.Address = cell.MergeArea.Cells(1).Address Then Debug.Print cell.Address Set ma = cell.MergeArea: newCW = 0 With ma cw = .Columns(1).ColumnWidth: .UnMerge For Each col In .EntireColumn: newCW = newCW + col.ColumnWidth: Next .Columns(1).ColumnWidth = newCW: .EntireRow.AutoFit rh = .EntireRow.RowHeight: If rh > maxRH Then maxRH = rh .Merge: .Columns(1).ColumnWidth = cw End With End If Next cell If maxRH > 0 Then ro.EntireRow.RowHeight = maxRH Next ro End Sub Sub ПримерИспользования() Application.ScreenUpdating = False AutoFitMergedCellRowHeight [a2:z8] End Sub
- 28246 просмотров
Не получается применить макрос? Не удаётся изменить код под свои нужды?
Оформите заказ у нас на сайте, не забыв прикрепить примеры файлов, и описать, что и как должно работать.
Xiaohny 1 / 1 / 0 Регистрация: 12.02.2017 Сообщений: 52 |
||||||
15.11.2018, 16:55 [ТС] |
2 |
|||||
Наткунлся на схожую тему AutoFit объединённой ячейки. ColumnWidth и Columns(n).Width созданнуюtolikt Предполагаю, что макрос будет сравнивать высоту объединенных ячеек и выбирать такую, что содержимое ячеек будет читабельным, ширина строк останется прежней. Предположительный алгоритм таков If HeighN>HeighG And HeighN>HeighF And HeighN/CountRows>HeighRow Then HeighN — Высота объединенной ячейки столбца N Попытка реализации описанного алгоритма не увенчалась успехом, поэтому прошу помощи умов сего ресурса.
Пример таблицы с макросом прикладываю во вложение. Вложения
0 |