При разработке интерфейсов на платформе «1С:Предприятие» (особенно в конфигурациях на обычных формах) разработчики часто сталкиваются с задачей красивого визуального представления данных. Одно из частых пожеланий пользователей — объединить строки в определенной колонке, если они содержат одинаковые значения (например, сгруппировать товарные позиции по складам или контрагентов по регионам).
Давайте сразу ответим на главный технический вопрос: в самой коллекции данных ТаблицаЗначений объединить ячейки невозможно. Объект ТаблицаЗначений — это строго двумерный массив, структура которого жестко привязана к строкам и колонкам. Количество ячеек в ней всегда равно произведению количества строк на количество столбцов. Каждая ячейка хранит отдельное значение, и «слить» их физически в структуре данных нельзя.
Однако мы можем решить эту задачу на уровне визуального представления. Разберем по шагам несколько эффективных практических способов, которые позволяют добиться нужного визуального эффекта объединения ячеек на форме.
Прежде чем перейти к решениям, важно устранить одно частое заблуждение. Иногда разработчики путают понятия и утверждают, что объединение ячеек поддерживает элемент управления ТабличноеПоле. Это не так. Элемент формы ТабличноеПоле, отображающий ТаблицуЗначений или ТабличнуюЧасть, имеет жесткую структуру сетки и напрямую объединять ячейки (как в Excel) не умеет. Нам придется использовать другие инструменты.
---
Если вам необходимо получить полноценный интерфейс с физически объединенными ячейками, лучшим решением будет отказаться от вывода стандартной таблицы значений и использовать элемент формы «Поле табличного документа».
При таком подходе данные по-прежнему обрабатываются в фоновой (невидимой для пользователя) ТаблицеЗначений, но выводятся программно в табличный документ, где поддерживается метод Объединить().
Рассмотрим подробнее алгоритм реализации этого способа:
ПолеТабличногоДокумента (например, с именем ЭлементыФормы.ПолеТабДок).ТаблицуЗначений по группируемой колонке, чтобы одинаковые значения шли строго друг за другом.Посмотрим на пример программного кода, реализующего этот алгоритм:
Процедура ВывестиДанныеСОбъединением()
ТабДок = ЭлементыФормы.ПолеТабДок;
ТабДок.Очистить();
// Получим и отсортируем данные (для примера)
ТЗДанные = ПолучитьТаблицуДанных();
ТЗДанные.Сортировать("Организация, Номенклатура");
// Зададим стартовые координаты
ТекущаяСтрокаВывода = 1;
НачалоОбъединения = 1;
ПредыдущееЗначение = Неопределено;
Для Каждого СтрокаДанных Из ТЗДанные Цикл
// Заполняем ячейки данными
ТабДок.Область(ТекущаяСтрокаВывода, 1).Текст = СтрокаДанных.Организация;
ТабДок.Область(ТекущаяСтрокаВывода, 2).Текст = СтрокаДанных.Номенклатура;
ТабДок.Область(ТекущаяСтрокаВывода, 3).Текст = СтрокаДанных.Количество;
// Алгоритм поиска границ для объединения ячеек первой колонки
Если ТекущаяСтрокаВывода > 1 Тогда
Если СтрокаДанных.Организация = ПредыдущееЗначение Тогда
// Продолжаем накапливать строки для текущей группы
Иначе
// Значение изменилось, пора объединить предыдущую группу строк
Если (ТекущаяСтрокаВывода - 1) > НачалоОбъединения Тогда
ОбластьДляОбъединения = ТабДок.Область(НачалоОбъединения, 1, ТекущаяСтрокаВывода - 1, 1);
ОбластьДляОбъединения.Объединить();
ОбластьДляОбъединения.ВертикальноеПоложение = ВертикальноеПоложение.Центр;
КонецЕсли;
// Запоминаем начало новой группы
НачалоОбъединения = ТекущаяСтрокаВывода;
КонецЕсли;
КонецЕсли;
ПредыдущееЗначение = СтрокаДанных.Организация;
ТекущаяСтрокаВывода = ТекущаяСтрокаВывода + 1;
КонецЦикла;
// Не забываем объединить последнюю группу строк
Если (ТекущаяСтрокаВывода - 1) > НачалоОбъединения Тогда
ОбластьДляОбъединения = ТабДок.Область(НачалоОбъединения, 1, ТекущаяСтрокаВывода - 1, 1);
ОбластьДляОбъединения.Объединить();
ОбластьДляОбъединения.ВертикальноеПоложение = ВертикальноеПоложение.Центр;
КонецЕсли;
КонецПроцедуры
Преимущества метода: Полное визуальное соответствие требованиям заказчика, возможность гибкой настройки шрифтов, рамок, цветов и выравнивания текста по центру объединенной области.
Недостатки: Усложняется интерактивное редактирование данных пользователем. Если вам нужно не просто показывать отчет, а давать пользователю возможность редактировать строки, такой вариант потребует написания сложных обработчиков событий.
---
Если вам принципиально важно оставить именно стандартное ТабличноеПоле (например, чтобы сохранить механизмы быстрого поиска, сортировки кликом по шапке или удобного ввода данных), можно прибегнуть к визуальной маскировке.
Идея заключается в том, чтобы убрать горизонтальные разделительные линии сетки таблицы, а повторяющиеся значения в колонке делать невидимыми (очищать текст или закрашивать его цветом фона). Пользователю будет казаться, что ячейка объединена по вертикали.
Разберем по шагам, как настроить такую имитацию:
ТабличноеПоле отключаем отображение горизонтальной сетки. Это можно сделать в свойствах элемента или программно:
ЭлементыФормы.ИмяТабличногоПоля.ГоризонтальныеЛинии = Ложь;
ПриПолученииДанных у нашего Табличного поля. Это событие вызывается платформой при отрисовке строк на экране.Проанализируем пример кода для обработчика событий:
Процедура ТабличноеПолеПриПолученииДанных(Элемент, ОформленияСтрок)
// Выключаем горизонтальную сетку для визуального слияния строк
Элемент.ГоризонтальныеЛинии = Ложь;
ПредыдущееЗначение = Неопределено;
Для Каждого ОформлениеСтроки Из ОформленияСтрок Цикл
ТекущиеДанные = ОформлениеСтроки.ДанныеСтроки;
Если ТекущиеДанные = Неопределено Тогда
Продолжить;
КонецЕсли;
// Проверяем значение в ключевой колонке, например, "Группа"
Если ТекущиеДанные.Группа = ПредыдущееЗначение Тогда
// Если значение совпадает с предыдущим — скрываем текст в ячейке
ОформлениеСтроки.Ячейки.Группа.ОтображатьТекст = Ложь;
ОформлениеСтроки.Ячейки.Группа.Текст = "";
Иначе
// Если значение новое — показываем его и запоминаем
ОформлениеСтроки.Ячейки.Группа.ОтображатьТекст = Истина;
ПредыдущееЗначение = ТекущиеДанные.Группа;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Преимущества метода: Сохраняется полноценный интерактивный функционал ТабличногоПоля (добавление строк, сортировки, отборы), код пишется быстро и не требует перестройки логики хранения данных.
Недостатки: Отсутствие горизонтальных линий между всеми строками может снизить читаемость таблицы в других колонках, где группировки нет.
---
Если данные имеют иерархическую структуру (например, Склад -> Группа товаров -> Товар), то вместо плоской ТаблицыЗначений логично применить ДеревоЗначений.
В дереве значений группировочные поля будут отображаться на верхних уровнях иерархии, а детальные записи — внутри них. Это избавляет от необходимости дублировать одинаковые значения в каждой строке и визуально выглядит чисто и аккуратно.
Для реализации этого метода:
ДеревоЗначений вместо ТаблицыЗначений.ТабличноеПоле с созданным деревом значений.---
Для построения сложных, нестандартных интерактивных интерфейсов в обычных формах применяется элемент «Поле HTML-документа». С его помощью вы можете сверстать абсолютно любую таблицу на языке HTML.
В HTML-разметке за объединение ячеек по вертикали отвечает стандартный атрибут rowspan тега <td>:
<table border="1">
<tr>
<td rowspan="3">Объединенная ячейка</td>
<td>Строка 1, Колонка 2</td>
</tr>
<tr>
<td>Строка 2, Колонка 2</td>
</tr>
<tr>
<td>Строка 3, Колонка 2</td>
</tr>
</table>
Программа генерирует этот HTML-код на лету на основе данных из вашей ТаблицыЗначений и передает его в поле HTML-документа. Перехват кликов по ячейкам настраивается через обработку события ПриНажатии элемента формы или скрипты на стороне HTML.
---
Выбор оптимального метода зависит от целей разработки: