Vba excel размер объединенной ячейки

Автоподбор ширины объединенной ячейки с помощью кода VBA Excel, когда метод AutoFit не работает. Обработка ячеек по списку адресов из массива.

Автоподбор ширины ячейки

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

Здесь мы рассмотрим макрос для автоподбора ширины ячейки, объединенной с другими по горизонтали в одной строке, которые обычно используются в заголовках электронных таблиц Excel. Ширина столбцов, пересекающихся с объединенной ячейкой, будет одинаковой. Код работает и с необъединенными ячейками.

Для решения задачи по автоподбору ширины необходимо с помощью кода VBA определить:

  1. Длину текста (количество символов). Длина одного символа текста со шрифтом и его размером по умолчанию приблизительно соответствует длине символа, в котором измеряется ширина ячейки.
  2. Размер шрифта, чтобы рассчитать коэффициент, увеличивающий или уменьшающий ширину ячейки в зависимости от его (шрифта) размера.
  3. Количество столбцов в объединенной ячейке, чтобы вычислить ширину одного столбца.

Макрос VBA Excel для автоподбора ширины ячейки с учетом размера используемого шрифта:

Sub PodborShiriny()

Dim myCell As Range, myLen As Integer, _

myCount As Integer, k As Single, n As Single

myLen = Len(CStr(ActiveCell))

myCount = Selection.Columns.Count

n = 11

k = ActiveCell.Font.Size / n

    For Each myCell In Selection

        myCell.ColumnWidth = myLen * k / myCount

    Next

End Sub

Переменные:

  • myCell — отдельная ячейка в объединенной;
  • myLen — длина текста в активной ячейке;
  • myCount — количество столбцов, которое соответствует количеству горизонтально расположенных отдельных ячеек в объединенной;
  • k — коэффициент, вносящий поправку в зависимости от размера шрифта;
  • n — размер шрифта по умолчанию.*

* У меня по умолчанию установлен шрифт Calibri размером 11, поэтому n = 11. Если у вас по умолчанию Arial размером 10, тогда и в коде укажите n = 10. Далее подкорректируйте значение переменной n опытным путем, так как длина текста зависит от процентного соотношения широких и узких символов, если шрифт не моноширинный. Переменной n можно присваивать и дробные значения для более точного автоподбора.

Данный код VBA Excel работает с выделенной ячейкой. Вы можете задать список адресов объединенных ячеек и пройтись макросом по каждой из них.

Обработка списка ячеек

Укажите список объединенных ячеек в качестве аргументов функции Array. Для списка используйте адреса только первых ячеек из состава объединенных. Можно добавлять в список и адреса одиночных ячеек.

Sub ObkhodYacheyek1()

Dim myCell() As Variant, myElem As Variant

myCell = Array(«A1», «D1», «G1»)

    For Each myElem In myCell

        Range(myElem).Select

        Call PodborShiriny

    Next

End Sub

Переменные:

  • myCell — массив со списком адресов объединенных ячеек;
  • myElem — используется как элемент массива myCell.

Макрос ObkhodYacheyek по адресам из списка обращается к каждой ячейке по очереди, выделяет ее и запускает код автоподбора ширины PodborShiriny.

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

Sub ObkhodYacheyek2()

Dim myCell() As String, myElem As Variant

myCell = Split(Selection.Address, «,»)

    For Each myElem In myCell

        Range(myElem).Select

        Call PodborShiriny

    Next

End Sub


Хитрости »

10 Август 2016              35689 просмотров


Подбор высоты строки/ширины столбца объединенной ячейки

Для начала немного теории. Если в ячейках листа 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
ссылки
статистика

 

Лузер™

Пользователь

Сообщений: 2410
Регистрация: 01.01.1970

#1

23.01.2015 15:21:20

Имеется счет-фактура, которую выплевывает 1С.
По договору точность отображения цены составляет 11 знаков после запятой.
Кроме того, имеется замороченный сотрудник контрагента, который докапывается до каждой запятой в документе.
Для успокоения этого сотрудника применяется нехитрый

Код
Set rSF = .Cells.Find("Цена (тариф) за единицу измерения", , , xlPart)
If Not rSF Is Nothing Then
    rSF.Offset(2, 0).NumberFormat = "#,##0.00000000000"
End If 

После него бывало, что число не влезает в ячейку и отображается  как «#########»
Решался вопрос просто:
rSF.EntireColumn.AutoFit

Однако ребятам в 1С тоже хочется кушать и они выпускают новую версию, где rSF является объединенной ячейкой и соответственно плюет на .EntireColumn.AutoFit

Замороченный сотрудник в ярости, я боюсь за его душевное здоровье. Как мне его спасти без потери своего душевного здоровья?
Вообще давно интересовал вопрос: есть некое содержимое ячейки .Value, кроме того про ячейку я знаю вид и размер шрифта, перенос строк и т.п.
Как эти знания перевести в ширину столбца?

Прикрепленные файлы

  • СФ.xls (33 КБ)

Bite my shiny metal ass!      

 

The_Prist

Пользователь

Сообщений: 14182
Регистрация: 15.09.2012

Профессиональная разработка приложений для MS Office

#2

23.01.2015 15:28:18

Хм…делал я такое где-то уже…Надо поковырять — тоже с накладными возился. Выводил в отдельную функцию, кстати.
Вот, нашел:

Код
'---------------------------------------------------------------------------------------
' Procedure : RowHeightForContent
' DateTime  : 20.03.2012 15:28
' Author    : The_Prist(Щербаков Дмитрий)
'             WebMoney - R298726502453; Яндекс.Деньги - 41001332272872
'             http://www.excel-vba.ru
' Purpose   : Функция подбирает ширину объединенных ячеек по содержимому(можно и под высоту подстроить)
'---------------------------------------------------------------------------------------
Function RowHeightForContent(rc As Range)
    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
            If .WrapText = True Then
                'запоминаем кол-во столбцов
                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
                .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
            End If
        End With
    End If
End Function

Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы…

 

Лузер™

Пользователь

Сообщений: 2410
Регистрация: 01.01.1970

#3

23.01.2015 15:37:07

The_Prist, Спасибо!
Воткнул не глядя:

Код
If Not rSF Is Nothing Then
 rSF.Offset(2, 0).NumberFormat = "#,##0.00000000000"
'rSF.EntireColumn.AutoFit
y = RowHeightForContent(rSF.Offset(2, 0))
End If 

Работает!

Bite my shiny metal ass!      

 

Лузер™

Пользователь

Сообщений: 2410
Регистрация: 01.01.1970

Не, поторопился
Это второй хороший Ваш код, но он про .EntireRow.AutoFit
А про EntireColumn.AutoFit поищете?

 

The_Prist

Пользователь

Сообщений: 14182
Регистрация: 15.09.2012

Профессиональная разработка приложений для MS Office

#5

23.01.2015 16:05:30

Что-то вроде:

Код
'---------------------------------------------------------------------------------------
' Procedure : RowHeightForContent
' DateTime  : 23.01.2015 16:02
' Author    : The_Prist(Щербаков Дмитрий)
'             WebMoney - R298726502453; Яндекс.Деньги - 41001332272872
'             http://www.excel-vba.ru
' Purpose   : Функция подбирает высоту строки объединенных ячеек по содержимому
'---------------------------------------------------------------------------------------
Function RowColHeightForContent(rc As Range, Optional bRowHeight As Boolean = True)
    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
            If .WrapText = True Then
                'запоминаем кол-во столбцов
                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
                    .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 If
        End With
    End If
End Function

Т.е. универсальная для обоих случаев. Отвечает за это доп.параметр: bRowHeight.
В случае с автоподбором высоты строки вызывается как и раньше. Для ширины столбцов:

Код
RowColHeightForContent Range("K17"), False

И есть нюанс: код будет работать только если в изменяемой объединенной ячейке установлен перенос текста: .WrapText = True
В принципе, данную строку можно и убить. Но я таким образом «помечал» ячейки, которые надо изменять.

P.S. Думаю, мы с Вами вполне можем на ты общаться.

Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы…

 

Лузер™

Пользователь

Сообщений: 2410
Регистрация: 01.01.1970

Спасибо!
Выкинул  If .WrapText = True Then за ненадобностью.
Отлично работает :)
Единственная проблема может возникнуть в других строках, в которых тоже объединенные ячейки, но объединены другие столбцы  — там может поехать, так как ширина всех столбцов становится одинаковой. Хорошо, что мне надо только одну (пока одну, пока 1С еще не замутил) и ее можно выравнивать последней.

Да, вполне можно на ты :)
Просто я по умолчанию всегда на Вы. Прошу меня извинить, если я забуду и опять начну выкать :)  :oops:

 

The_Prist

Пользователь

Сообщений: 14182
Регистрация: 15.09.2012

Профессиональная разработка приложений для MS Office

Рад, что помогло.
.WrapText = True — оно очень нужно, когда надо подбор по высоте строк сделать.

Да я тоже тот еще Выкальщик :-)

Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы…

 

Лузер™

Пользователь

Сообщений: 2410
Регистрация: 01.01.1970

#8

26.01.2015 10:51:09

А я сначала подумал, что без этого вообще не работает, потом голову ломал зачем таким странным способом метить ячейки. О_о

Bite my shiny metal ass!      

Что получилось у меня и чем пока пользуюсь. Описание кода, по возможности подробное, в самом коде.

Sub RowHeightFiting1()
‘ Объединённая ячейка должна быть активной!!!
Application.ScreenUpdating = False

Dim MyRanAdr As String
Dim MergeAreaTotalWidth, MergeAreaTotalHeight
Dim MergeAreaFirstCellColWidth, MergeAreaFirstCellColHeight
Dim SumCW, SumRH
Dim i As Integer
Dim NewRH
Dim dCW ‘

MyRanAdr = ActiveCell.MergeArea.Address ‘адрес области с объединённой ячейкой
MergeAreaTotalWidth = Range(MyRanAdr).Width ‘ ширина всей объединённой ячейки в ед. пт
MergeAreaTotalHeight = Range(MyRanAdr).Height ‘ высота всей объединённой ячейки в ед. пт
MergeAreaFirstCellColWidth = Range(MyRanAdr).Cells(1, 1).EntireColumn.ColumnWidth ‘ ширина первого столбца в объединённой ячейке
MergeAreaFirstCellColHeight = Range(MyRanAdr).Cells(1, 1).EntireRow.RowHeight ‘ высота первой строки в объединённой ячейке

‘ подсчёт суммарной ширины объед. ячейки в единицах ColumnWidth
SumCW = 0
For i = 1 To Range(MyRanAdr).Columns.Count
SumCW = SumCW + Range(MyRanAdr).Columns(i).ColumnWidth
Next

‘ Установка ширины первого столбца равной суммарной ширины объед. ячейки плюс поправка
‘ Поправка состоит из количества как бы «убранных» столбцов, умноженной на корректировочный коэффициент
Range(MyRanAdr).Cells(1, 1).ColumnWidth = SumCW + (Range(MyRanAdr).Columns.Count — 1) / 1.2 ‘ 1.2=3.75 / 4.5
‘ корректировочный коэффициент возникает из-за «краёв» каждого столбца

‘далее, при необходимости, максимально точная подгонка
dCW = 0.1 ‘ шаг изменения ширины столбца в единицах ColumnWidth при подгонке
sgndcw = Sgn(MergeAreaTotalWidth — Range(MyRanAdr).Cells(1, 1).Width)
SumCW = Range(MyRanAdr).Cells(1, 1).ColumnWidth
While sgndcw * (MergeAreaTotalWidth — Range(MyRanAdr).Cells(1, 1).Width) > 0
SumCW = SumCW + dCW * sgndcw
Range(MyRanAdr).Cells(1, 1).EntireColumn.ColumnWidth = SumCW
Wend
While MergeAreaTotalWidth — Range(MyRanAdr).Cells(1, 1).Width < 0
SumCW = SumCW — dCW
Range(MyRanAdr).Cells(1, 1).EntireColumn.ColumnWidth = SumCW
Wend
‘ хотя, вообще-то, обычно эта часть процедуры не нужна
‘ просто на случай, если поправка к ширине первого столбца вдруг окажется неверной. Напр., из-за того, что ширина стольца меняется дискретно с шагом 0.167, но не всегда.

‘ форматирование ячейки (устан. опции перенос текста и разобъединение ячейки)
Range(MyRanAdr).WrapText = True
Range(MyRanAdr).MergeCells = False

‘ применение Автоподбора высоты к необъединённой ячейке
Range(MyRanAdr).Cells(1, 1).EntireRow.AutoFit

‘ запись получившейся высоты в переменную
NewRH = Range(MyRanAdr).Cells(1, 1).EntireRow.RowHeight

‘ обратное объединение ячейки
Range(MyRanAdr).MergeCells = True

‘ принудительная установка высоты объединённой ячейки НО !!!:
‘ НО !!!: ТУТ ТОЛЬКО У ПЕРВОЙ СТРОКИ в случае, если объединённая ячейка состояла из нескольких строк
Range(MyRanAdr).Cells(1, 1).EntireRow.RowHeight = NewRH — (MergeAreaTotalHeight — MergeAreaFirstCellColHeight)
‘ Если нужно выровнять высоту строк, то можно использовать что-нибудь типа
‘Range(MyRanAdr).EntireRow.RowHeight = NewRH / Range(MyRanAdr).Rows.Count

‘ установка изначальной ширины первого столбца
Range(MyRanAdr).Cells(1, 1).EntireColumn.ColumnWidth = MergeAreaFirstCellColWidth

Application.ScreenUpdating = True
L: ‘ усё
i = MsgBox(«Das ist Fantastisch!» & Chr(10) & «Stimt das?», vbYesNo)
If i = vbNo Then GoTo L
End Sub

Глюков пока не замечал, но и не фантазировал в способах проверки
Впрочем, при большом количестве узких (менее примерно 3 симв) столбцов, входящих в объединённую ячейку или находящемся в ней длинном (более 100-150 символов) тексте (например, xls-фактуры, вытянутые из Консультант-плюс) может происходить следующее:
1. Новая высота объединённой ячейки выставляется как бы чуть-чуть «с запасом», т.е. больше, чем надо. Особенно в печатном виде. Но это, похоже, проблема самого Excelя.
2. Точная подгонка занимает ОЧЕНЬ много времени (более секунды). Просто процедура (там, где блок с While и написано, что эта часть обычно не используется) написана «в лоб» и совершенно неоптимизирована. Оставляю эту часть желающим на доделку. Или доделаю потом сам.

ЗЫ: В хелпе Office 97 не говорится о ReadOnly метода Width… А наоборот, Read and set…
Но на новый Office менять не могу, ибо с новым Office у меня внедрённые в лист Excelя картинки на печати выходят просто рамками.

Из личных архивов
[vba]

Код

Private Sub MyMaxRow(): Call MySameRow(«MaxRow»): End Sub
Private Sub MyMinRow(): Call MySameRow(«MinRow»): End Sub
Private Sub MySameRow(Optional equal As String = «SameRow»)
‘ Макрос записан 21.11.2017 (boa)
‘ Делает высоту строк одинаковой
Dim Row As Range, i As Double
    For Each Row In Selection.Rows
        Select Case equal
            Case «MaxRow»: If i < Row.RowHeight Then i = Row.RowHeight
            Case «MinRow»: If Row.RowHeight < i Or i = 0 Then i = Row.RowHeight
            Case «SameRow»: i = i + Row.RowHeight
        End Select
    Next
    If equal = «SameRow» Then i = i / Selection.Rows.Count
    For Each Row In Selection.Rows
       Row.RowHeight = i
    Next
End Sub

Private Sub MyMaxCol(): Call MySameCol(«MaxCol»): End Sub
Private Sub MyMinCol(): Call MySameCol(«MinCol»): End Sub
Private Sub MySameCol(Optional equal As String = «SameCol»)
‘ Макрос записан 21.11.2017 (boa)
‘ Делает ширину колонок одинаковой.
Dim Col As Range, i As Double
    For Each Col In Selection.Columns
        Select Case equal
            Case «MaxCol»: If i < Col.ColumnWidth Then i = Col.ColumnWidth
            Case «MinCol»: If Col.ColumnWidth < i Or i = 0 Then i = Col.ColumnWidth
            Case «SameCol»: i = i + Col.ColumnWidth
        End Select
    Next
    If equal = «SameCol» Then i = i / Selection.Columns.Count
    For Each Col In Selection.Columns
       Col.ColumnWidth = i
    Next
End Sub

[/vba]

myth

1

Как расширить ячейку по размеру данных?

09.02.2011, 12:22. Показов 5401. Ответов 7


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

Добрый день. У нас такая проблемка: мы экспортируем в Exel данные в ячейку.
Далее объединяем этй ячейку с соседней и переносим по словам, так вот если длинное слово/предложение, exel почему-то не расширяем ячейку и невидно всех данных. Как справиться с этим?

Димит

90 / 37 / 14

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

Сообщений: 429

09.02.2011, 14:36

2

Можно так:

Visual Basic
1
2
Range('C6').Rows.AutoFit
Range('C6').Columns.AutoFit



0



myth

09.02.2011, 15:20

3

Не получается, эффект тот же.

myth

09.02.2011, 15:24

4

Для необъединенных ячеек действует, для объединенных нет

Димит

90 / 37 / 14

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

Сообщений: 429

09.02.2011, 17:35

5

Действительно не работает.
Эта химия работать будет:

Visual Basic
1
2
3
4
5
6
7
8
Range('Z2').Value = Range('B2:J3').Value
Range('Z2').WrapText = False
Range('Z2').Columns.AutoFit
Range('Z2').WrapText = True
Range('Z2').Columns.AutoFit
Range('Z2').Rows.AutoFit
Range('B2:J3').ColumnWidth = Range('Z2').ColumnWidth / Range('B2:J3').Columns.Count
Range('B2:J3').RowHeight = Range('Z2').RowHeight / Range('B2:J3').Rows.Count

Но наверно можно и по лутше



0



myth

10.02.2011, 09:12

6

Я наверное не очень правильно объяснила.
В Excele я сделала из 2-ух ячеек одну и вот эту одну надо расширить по размеру данных.
Хотя мне кажется Дмит Вы навели меня на мысль. Попробую сейчас, если не получиться — буду опять просить помощи.
Большое спасибо Дмит за отзывчивость. :-)

90 / 37 / 14

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

Сообщений: 429

10.02.2011, 17:50

7

Из кода видна идея (может быть и не очень)
1. Переносим Текст из объединённой ячейки в одну (Z2)
2. Методом AutoFit изменяем её размеры под текст.
3. Изменяем размеры объединённой ячейки до размеров ячейки Z2.
Замечание — все столбцы (строки) объединённой ячейки становятся равны по ширине (высоте).
Поделись своей мыслью — мне будет интересно.



0



Искатель

10.02.2011, 19:40

8

Ну, типа, считается, что если ячейки объединены, то автоматом нельзя решить какую из строк или столбцов расширять. Вот только даже если объединённые ячейки на одной строке, он всё равно строку не расширяет.
Кстати, лучше не использовать для временных данных ячейки типа ‘zz1000’, так как в этом случае при сохранении получится огромный размер файла — он сохранит форматы всех ячеек в диапазоне ‘a1:zz1000’. Лучше сохранить размеры ячейки до объединения, вставить текст, померять размер, вернуть старый размер, объединить и присвоить померянный.

Автовысота строки для объединенных ячеек

Написание статьи на эту тему назревало очень долго. Да, таких постов полно в интернете, но их всегда приходится искать.

Исходные данные

В Excel есть табличка со строками. Ширина колонок таблицы фиксирована, но изначально не известна. Ширина столбцов Excel фиксирована и равна 0,58. То есть одна ячейка таблицы с данными — это объединение нескольких ячеек самого Excel. Так же, все строки с данными таблицы в колонке А имеют значение «l«, а после таблицы весь футер содержит значение «f» (это исторически сложилось и сильно облегчает жизнь)

Excel не умеет выставлять автовысоту строки для строки с объединенными ячейками, собственно это мы и будем решать. Сразу скажу, что автовысота требуется только для одного столбца таблицы, так что я использовал несколько констант для увеличения производительности VBA скрипта.

Теория

Excel не умеет выставлять автовысоту для объединенных ячеек, но умеет это делать для отдельной ячейки. Это значит, что алгоритм сводится к нескольким простым шагам:

  1. Вычислить длину объединенной ячейки
  2. Разбить ячейку на составляющие (на текст это никак не повлияет, поскольку он записан в первую ячейку объединенной области. Это даже нам на руку)
  3. Выставить первой ячейке нужную длину
  4. Выставить автовысоту
  5. Вернуть длину первой ячейки
  6. Объединить ячейки обратно

Реализация алгоритма

Sub AutoFitMergedCellRowHeight(ByRef ra As Range, ByRef cellWidth As Double)
    Dim CurrCell As Range
    Dim cell As Range
    Dim ma As Range: Dim col As Range, ro As Range
    Dim coef As Double
 
    coef = 1.66 ' Коэфициент границ ячеек
    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
 
                    If cellWidth = 0 Then
                        For Each col In .EntireColumn: newCW = newCW + col.ColumnWidth: Next
                        newCW = newCW * coef
                        cellWidth = newCW
                    Else
                        newCW = cellWidth
                    End If
 
                    .Columns(1).ColumnWidth = newCW: .EntireRow.autofit
                    rh = .EntireRow.RowHeight: If rh > maxRH Then maxRH = rh
                    .Merge: .Columns(1).ColumnWidth = cw
                End With
                Exit For ' Поскольку нам нужна лишь одна ячейка, то в целях оптимизации прервем цикл
            End If
        Next cell
        If maxRH > 0 Then ro.EntireRow.RowHeight = maxRH
    Next ro
End Sub

Алгоритм реализован. Один нюанс с коэффициентом 1.66 — это важная деталь. Поскольку у каждой ячейки Excel есть еще и границы, то мы полученную длину умножим на этот коэффициент, что бы получить полноценную длину, соизмеримую с длиной ячейки объединенной области.

Autofit

В этой части все просто. Делаем цикл по всем строкам с данными таблицы и вызываем AutoFitMergedCellRowHeight для каждой строки. Для оптимизации мы будем еще передавать ширину столбца с текстом, которую посчитаем при первом вызове. А вместо всей строки будем передавать только область объединенных ячеек. Такой подход заточен под жесткий шаблон и только одно поле с текстом.

Sub autofit()
    Dim row As Integer
    Dim cellWidth As Double
    Dim startRangeCell As Integer
    Dim endRangeCell As Integer
    Dim startRaw As Integer
 
    startRangeCell = 8
    endRangeCell = 32
    startRaw = 46
    cellWidth = 0
    For row = startRaw To ActiveWorkbook.Worksheets(1).UsedRange.Rows.count
        If ActiveWorkbook.Worksheets.Application.Cells(row, 1).Text = "f" Then
            Exit For
        End If
        If ActiveWorkbook.Worksheets.Application.Cells(row, 1).Text = "l" Then
            If ActiveWorkbook.Worksheets.Application.Cells(row, 8).Text <> "" Then
                AutoFitMergedCellRowHeight ActiveWorkbook.ActiveSheet.Range(Cells(row, startRangeCell), Cells(row, endRangeCell)), cellWidth
            End If
        End If
    Next row
 
End Sub

Like this post? Please share to your friends:
  • Vba excel размер листа
  • Vba excel разделить строку по словам
  • Vba excel разделить строку на строки
  • Vba excel разделить значения
  • Vba excel разделитель запятая