Как создать эффект вертикального объединения ячеек в табличном поле на обычных формах 1С 8.3?

Программист 1С v8.3 (Обычные формы)
← На главную

При работе с формами в 1С:Предприятии, особенно на обычных формах, разработчики часто сталкиваются с необходимостью визуально объединить ячейки в табличном поле, чтобы представить данные более наглядно или сгруппировать их. Однако, прямой функциональности для вертикального объединения ячеек, аналогичной той, что мы видим в Excel или в объекте "Табличный документ" 1С, для элемента управления "Табличное поле" не предусмотрено. Тем не менее, существуют программные подходы, которые позволяют добиться подобного визуального эффекта. Рассмотрим эти методы подробнее.

Введение: Ключевые различия между Табличным полем и Табличным документом

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

  1. Табличное поле (TableField):

    Этот элемент управления предназначен для отображения данных из таблиц значений, динамических списков, запросов или других источников данных, где каждая строка представляет собой отдельную запись. Каждая ячейка в строке является частью этой записи. Табличное поле оптимизировано для интерактивной работы с данными, такими как сортировка, фильтрация, редактирование. Структурно каждая строка и каждая ячейка в ней независимы, и возможности прямого объединения ячеек (как горизонтального, так и вертикального) здесь отсутствуют.

  2. Табличный документ (TabularDocument):

    Это объект предназначен для формирования печатных форм, отчетов и макетов. Он предоставляет широкие возможности для сложного форматирования, включая реальное объединение ячеек по горизонтали и вертикали с помощью метода Область().Объединить(). Табличный документ позволяет создавать произвольные макеты с объединенными ячейками, различным шрифтом, цветом и границами, но он менее приспособлен для интерактивной работы с большим объемом данных.

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

Решение 1: Создание эффекта вертикального объединения ячеек путем скрытия повторяющихся элементов

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

Рассмотрим по шагам, как это реализовать:

  1. Определим событие для оформления строк

    Для управления видимостью ячеек мы будем использовать событие табличного поля ПриВыводеСтроки. Это событие срабатывает для каждой строки перед её отображением на форме, предоставляя нам доступ к объекту ОформлениеСтроки, через который мы можем изменить внешний вид ячеек текущей строки. Хотя автор в своем решении использовал ПриАктивацииСтроки, событие ПриВыводеСтроки является более подходящим для задач постоянного визуального оформления, так как оно обеспечивает корректное отображение для всех строк таблицы, а не только для активной.

    Перейдем в свойства табличного поля на форме, найдем событие ПриВыводеСтроки и создадим для него обработчик.

  2. Реализуем логику скрытия ячеек

    Внутри процедуры обработчика ПриВыводеСтроки нам потребуется сравнивать значение текущей ячейки с значением той же ячейки в предыдущей строке. Если значения совпадают, и это не первая строка группы "объединения", мы будем скрывать текущую ячейку.

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

    Предположим, у нас есть колонка с именем ИмяКолонкиДляОбъединения, и мы хотим объединить ячейки по её значению.

    В модуле формы объявим переменные:

    
    Перем глПредыдущееЗначениеДляОбъединения Экспорт;
    Перем глНомерГруппыДляОбъединения Экспорт;
    

    Теперь добавим код в процедуру ПриВыводеСтроки. Обратите внимание, что необходимо аккуратно управлять значениями глПредыдущееЗначениеДляОбъединения и глНомерГруппыДляОбъединения, особенно при первичной инициализации или при изменении сортировки/фильтрации данных в табличном поле.

    
    Процедура ТабличноеПолеПриВыводеСтроки(Элемент, ОформлениеСтроки, ДанныеСтроки)
    
        // Получаем текущее значение колонки, по которой хотим сделать "объединение"
        // Предполагаем, что ДанныеСтроки - это Структура или ОбъектДанных,
        // содержащий поле с именем ИмяКолонкиДляОбъединения
        ТекущееЗначение = ДанныеСтроки.ИмяКолонкиДляОбъединения;
        // Получаем значение колонки, которое используется для группировки, если есть.
        // Например, если объединение идет внутри каждой "Жалобы", то нужно учитывать
        // значение поля "Жалоба", чтобы объединение не "перескакивало" на следующую жалобу.
        // Если объединение просто идет по одинаковым значениям колонки,
        // то эта часть кода может быть упрощена или пропущена.
        ТекущийИдентификаторГруппы = ДанныеСтроки.ИдентификаторГруппы; // Например, номер жалобы или другой ключ
    
        // Инициализация при первом вызове или сброс при изменении данных
        Если Элемент.ТекущаяСтрока = Неопределено Тогда // Проверка на первый вывод или сброс
            глПредыдущееЗначениеДляОбъединения = Неопределено;
            глНомерГруппыДляОбъединения = Неопределено;
        КонецЕсли;
    
        // Проверяем, совпадает ли текущее значение с предыдущим
        // и находимся ли мы в той же группе объединения
        Если ТекущееЗначение = глПредыдущееЗначениеДляОбъединения И
           ТекущийИдентификаторГруппы = глНомерГруппыДляОбъединения И
           глПредыдущееЗначениеДляОбъединения <> Неопределено Тогда
    
            // Если значения совпадают, скрываем ячейку в текущей строке
            ОформлениеСтроки.Ячейки.ИмяКолонкиДляОбъединения.Видимость = Ложь;
        Иначе
            // Если значения не совпадают или это новая группа,
            // делаем ячейку видимой (по умолчанию она видима, но
            // лучше явно установить, если она могла быть скрыта ранее)
            ОформлениеСтроки.Ячейки.ИмяКолонкиДляОбъединения.Видимость = Истина;
        КонецЕсли;
    
        // Обновляем предыдущее значение для следующей строки
        глПредыдущееЗначениеДляОбъединения = ТекущееЗначение;
        глНомерГруппыДляОбъединения = ТекущийИдентификаторГруппы;
    
    КонецПроцедуры
    

    Обратите внимание на необходимость сброса переменных глПредыдущееЗначениеДляОбъединения и глНомерГруппыДляОбъединения, например, при изменении порядка сортировки данных или при каждой новой загрузке данных в табличное поле. Это можно сделать в событии ПриЗагрузкеДанных табличного поля или перед первым выводом строк.

Важные моменты при использовании этого подхода:

Решение 2: Отображение многострочного текста в одной ячейке для увеличения ее высоты

Иногда под "вертикальным объединением" подразумевается не скрытие повторяющихся значений, а возможность выводить в одной ячейке многострочный текст, чтобы она занимала больше вертикального пространства. Это полезно, когда содержимое ячейки слишком длинное и не помещается в одну строку стандартной высоты. Такой подход не является "объединением" в строгом смысле, но может создавать схожий визуальный эффект за счет увеличения высоты самой ячейки.

Разберем, как это можно сделать:

  1. Используем свойство АвтоВысотаЯчейки

    Для колонки табличного поля, в которой мы хотим отображать многострочный текст, можно включить свойство АвтоВысотаЯчейки. Это свойство, доступное через объект ОформлениеСтроки.Ячейки.ИмяКолонки, заставит ячейку автоматически подстраивать свою высоту под содержимое, если текст не помещается в одну строку.

    Добавим следующий код в процедуру ПриВыводеСтроки:

    
    Процедура ТабличноеПолеПриВыводеСтроки(Элемент, ОформлениеСтроки, ДанныеСтроки)
        // Включаем автоматическую высоту для колонки "Описание",
        // чтобы текст в ячейке мог занимать несколько строк
        ОформлениеСтроки.Ячейки.Описание.АвтоВысотаЯчейки = Истина;
    
        // Также, можно явно указать, что текст в колонке должен переноситься
        // (это свойство обычно устанавливается для самой колонки в конфигураторе,
        // но может быть переопределено и программно)
        ОформлениеСтроки.Ячейки.Описание.ПереносТекста = Истина;
    КодКонец;
    

    При использовании АвтоВысотаЯчейки = Истина, общая высота строки будет определяться самой высокой ячейкой в этой строке, что может привести к увеличению высоты всей строки, а не только отдельной ячейки.

  2. Устанавливаем фиксированную высоту ячейки

    В некоторых случаях нам может потребоваться задать фиксированную высоту для ячейки, независимо от содержимого. Это можно сделать с помощью свойства ВысотаЯчейки.

    
    Процедура ТабличноеПолеПриВыводеСтроки(Элемент, ОформлениеСтроки, ДанныеСтроки)
        // Устанавливаем фиксированную высоту ячейки для колонки "ДополнительнаяИнформация"
        // Например, 3 означает высоту, примерно равную трем строкам текста
        ОформлениеСтроки.Ячейки.ДополнительнаяИнформация.ВысотаЯчейки = 3;
        // Обязательно устанавливаем перенос текста, чтобы он был виден
        ОформлениеСтроки.Ячейки.ДополнительнаяИнформация.ПереносТекста = Истина;
    КонецПроцедуры
    

    Как и в случае с АвтоВысотаЯчейки, установка ВысотаЯчейки для одной ячейки повлияет на высоту всей строки. Если другие ячейки в этой строке не имеют достаточного количества текста для заполнения новой высоты, они просто станут выше, оставаясь пустыми внизу.

Дополнительные возможности оформления шапки табличного поля

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

  1. Регулировка высоты шапки

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

  2. Использование декораций (менее применимо, но упомянем)

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

Заключение

Мы выяснили, что "вертикальное объединение ячеек" в табличном поле на обычных формах 1С 8.3 не является прямым функционалом, а достигается путем программного оформления. Мы рассмотрели два основных подхода:

  1. Скрытие повторяющихся ячеек с помощью свойства ОформлениеСтроки.Ячейки.ИмяКолонки.Видимость = Ложь в событии ПриВыводеСтроки, что позволяет создать эффект, при котором одна ячейка "занимает" несколько строк. Этот метод требует внимательного управления состоянием и данными для корректного отображения.
  2. Использование многострочного текста в одной ячейке путем установки свойств АвтоВысотаЯчейки = Истина или ВысотаЯчейки = N, что увеличивает высоту самой ячейки и, как следствие, всей строки, позволяя тексту располагаться в несколько строк.

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

← На главную