При разработке сложных отчетов или печатных форм в 1С программисты часто сталкиваются с необходимостью объединить несколько разных табличных документов в один. Стандартный механизм платформы предлагает использовать метод СоздатьФорматСтрок(), чтобы настройки колонок одной части документа не влияли на другую. Однако на практике возникает неприятный эффект: колонки, которые в макете были объединены (например, «Номенклатура», занимающая 6 стандартных столбцов), внезапно «схлопываются», становятся крайне узкими или вовсе исчезают из видимости.
В этой статье мы подробно разберем, почему это происходит, проанализируем внутренние механизмы работы табличного документа и рассмотрим несколько способов решения данной проблемы.
Рассмотрим стандартный алгоритм, который обычно приводит к ошибке. Программист берет целевой ТабличныйДокумент, определяет в нем начало новой области, вставляет туда данные из другого документа методом ВставитьОбласть() и применяет СоздатьФорматСтрок(). После этого в цикле предпринимается попытка восстановить ширину колонок. Типичный код выглядит так:
Процедура ОбъединитьТабличныеДокументы(ИсходныйТабличныйДокумент, ВторойТабличныйДокумент) Экспорт
НачалоНовогоФорматаСтрок = ИсходныйТабличныйДокумент.ВысотаТаблицы + 1;
ОбластьПрямоугольная = ВторойТабличныйДокумент.Область(1, , ВторойТабличныйДокумент.ВысотаТаблицы, );
// Вставка данных
ИсходныйТабличныйДокумент.ВставитьОбласть(ОбластьПрямоугольная, ИсходныйТабличныйДокумент.Область(НачалоНовогоФорматаСтрок, 1));
// Создание независимой сетки колонок для новых строк
ИсходныйТабличныйДокумент.Область(НачалоНовогоФорматаСтрок, , НачалоНовогоФорматаСтрок + ВторойТабличныйДокумент.ВысотаТаблицы - 1, ).СоздатьФорматСтрок();
// Попытка восстановить ширину
Для Счетчик = 1 По ВторойТабличныйДокумент.ШиринаТаблицы Цикл
ИсходныйТабличныйДокумент.Область(НачалоНовогоФорматаСтрок, Счетчик).ШиринаКолонки = ВторойТабличныйДокумент.Область(1, Счетчик).ШиринаКолонки;
КонецЦикла;
КонецПроцедуры
Выясним основную причину проблемы: метод СоздатьФорматСтрок() полностью перестраивает коллекцию колонок для указанного диапазона строк. Если во вставляемом документе была объединенная ячейка, занимающая, к примеру, колонки с 2 по 7, то после создания нового формата строк платформа может некорректно сопоставить индексы. Более того, если в цикле мы устанавливаем ширину только для первой колонки из объединения (индекс 2), а для остальных (3–7) ширина остается по умолчанию или нулевой, вся объединенная область визуально сожмется до размера первой микро-колонки.
Проанализируем самый простой и эффективный способ. Вместо низкоуровневых манипуляций с областями и ручного создания формата строк, мы можем доверить эту работу платформе. Метод Вывести() (или Присоединить()) при выводе целого табличного документа в другой автоматически обрабатывает различия в сетках колонок.
Рассмотрим, как это реализовать правильно:
ТабличныйДокумент.Вывести(), передавая в него второй документ.
// Вместо ВставитьОбласть используем прямой вывод
Результат.Вывести(ТабДокСОбъединеннымиЯчейками);
Это решение избавляет от необходимости писать циклы по колонкам и вручную управлять методом СоздатьФорматСтрок(), так как 1С сделает это «под капотом» максимально корректно.
Если специфика задачи требует использования именно ВставитьОбласть() (например, когда вставка идет в середину документа или в определенные координаты), нужно изменить порядок выполнения операций. Опытным путем установлено, что создание формата строк после вставки данных часто приводит к потере структуры. Попробуем другой алгоритм:
СоздатьФорматСтрок().ВставитьОбласть().Посмотрим на пример правильной настройки ширин:
Для Счетчик = 1 По ВторойТабличныйДокумент.ШиринаТаблицы Цикл
// Важно: устанавливаем ширину для каждой элементарной колонки
ТекущаяШирина = ВторойТабличныйДокумент.Область(1, Счетчик, 1, Счетчик).ШиринаКолонки;
ИсходныйТабличныйДокумент.Область(НачалоНовогоФорматаСтрок, Счетчик).ШиринаКолонки = ТекущаяШирина;
КонецЦикла;
Важный нюанс: Обратите внимание на свойство ШиринаТаблицы. Оно возвращает индекс последней колонки, имеющей оформление. Если в вашем макете есть скрытые колонки или пустые области справа, цикл может отработать не до конца. Всегда проверяйте, совпадает ли ШиринаТаблицы с фактическим количеством колонок, участвующих в объединении.
Иногда колонки не удаляются, а просто становятся скрытыми. Проанализируем ситуацию: при конфликте форматов 1С может присвоить некоторым колонкам свойство Видимость = Ложь. Чтобы исключить этот вариант, в цикл по установке ширины стоит добавить принудительное включение видимости:
Для Счетчик = 1 По ШиринаМаксимальная Цикл
ОбластьКолонки = ИсходныйТабличныйДокумент.Область(НачалоНовогоФорматаСтрок, Счетчик);
ОбластьКолонки.ШиринаКолонки = ВторойТабличныйДокумент.Область(1, Счетчик).ШиринаКолонки;
ОбластьКолонки.Видимость = Истина; // Гарантируем отображение
КонецЦикла;
Чтобы избежать подобных проблем в будущем, рекомендуем придерживаться следующих правил при проектировании макетов:
Подводя итог, можно сказать, что наиболее надежным способом является использование метода Вывести(). Если же вы вынуждены работать через ВставитьОбласть() и СоздатьФорматСтрок(), ключевым моментом будет тщательная установка ширины каждой колонки в новой области и контроль их видимости.