Почему пропадают объединенные колонки при объединении табличных документов и как это исправить?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При разработке сложных отчетов или печатных форм в 1С программисты часто сталкиваются с необходимостью объединить несколько разных табличных документов в один. Стандартный механизм платформы предлагает использовать метод СоздатьФорматСтрок(), чтобы настройки колонок одной части документа не влияли на другую. Однако на практике возникает неприятный эффект: колонки, которые в макете были объединены (например, «Номенклатура», занимающая 6 стандартных столбцов), внезапно «схлопываются», становятся крайне узкими или вовсе исчезают из видимости.

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

Разбор ситуации: почему «ломается» макет?

Рассмотрим стандартный алгоритм, который обычно приводит к ошибке. Программист берет целевой ТабличныйДокумент, определяет в нем начало новой области, вставляет туда данные из другого документа методом ВставитьОбласть() и применяет СоздатьФорматСтрок(). После этого в цикле предпринимается попытка восстановить ширину колонок. Типичный код выглядит так:


Процедура ОбъединитьТабличныеДокументы(ИсходныйТабличныйДокумент, ВторойТабличныйДокумент) Экспорт
    НачалоНовогоФорматаСтрок = ИсходныйТабличныйДокумент.ВысотаТаблицы + 1;
    ОбластьПрямоугольная = ВторойТабличныйДокумент.Область(1, , ВторойТабличныйДокумент.ВысотаТаблицы, );
    
    // Вставка данных
    ИсходныйТабличныйДокумент.ВставитьОбласть(ОбластьПрямоугольная, ИсходныйТабличныйДокумент.Область(НачалоНовогоФорматаСтрок, 1));
    
    // Создание независимой сетки колонок для новых строк
    ИсходныйТабличныйДокумент.Область(НачалоНовогоФорматаСтрок, , НачалоНовогоФорматаСтрок + ВторойТабличныйДокумент.ВысотаТаблицы - 1, ).СоздатьФорматСтрок();
    
    // Попытка восстановить ширину
    Для Счетчик = 1 По ВторойТабличныйДокумент.ШиринаТаблицы Цикл
        ИсходныйТабличныйДокумент.Область(НачалоНовогоФорматаСтрок, Счетчик).ШиринаКолонки = ВторойТабличныйДокумент.Область(1, Счетчик).ШиринаКолонки;
    КонецЦикла;
КонецПроцедуры

Выясним основную причину проблемы: метод СоздатьФорматСтрок() полностью перестраивает коллекцию колонок для указанного диапазона строк. Если во вставляемом документе была объединенная ячейка, занимающая, к примеру, колонки с 2 по 7, то после создания нового формата строк платформа может некорректно сопоставить индексы. Более того, если в цикле мы устанавливаем ширину только для первой колонки из объединения (индекс 2), а для остальных (3–7) ширина остается по умолчанию или нулевой, вся объединенная область визуально сожмется до размера первой микро-колонки.

Решение №1: Использование метода Вывести()

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

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

  1. Создаем результирующий ТабличныйДокумент.
  2. Используем метод Вывести(), передавая в него второй документ.
  3. Платформа сама определит необходимость создания нового формата строк и сохранит все объединения и ширины.

// Вместо ВставитьОбласть используем прямой вывод
Результат.Вывести(ТабДокСОбъединеннымиЯчейками);

Это решение избавляет от необходимости писать циклы по колонкам и вручную управлять методом СоздатьФорматСтрок(), так как 1С сделает это «под капотом» максимально корректно.

Решение №2: Правильный порядок действий при ВставитьОбласть

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

  1. Сначала подготовим в целевом документе пустые строки.
  2. Применим к этим строкам СоздатьФорматСтрок().
  3. Настроим ширину всех колонок, включая те, что входят в объединения.
  4. Только после этого выполним ВставитьОбласть().

Посмотрим на пример правильной настройки ширин:


Для Счетчик = 1 По ВторойТабличныйДокумент.ШиринаТаблицы Цикл
    // Важно: устанавливаем ширину для каждой элементарной колонки
    ТекущаяШирина = ВторойТабличныйДокумент.Область(1, Счетчик, 1, Счетчик).ШиринаКолонки;
    ИсходныйТабличныйДокумент.Область(НачалоНовогоФорматаСтрок, Счетчик).ШиринаКолонки = ТекущаяШирина;
КонецЦикла;

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

Решение №3: Обработка свойства Видимость

Иногда колонки не удаляются, а просто становятся скрытыми. Проанализируем ситуацию: при конфликте форматов 1С может присвоить некоторым колонкам свойство Видимость = Ложь. Чтобы исключить этот вариант, в цикл по установке ширины стоит добавить принудительное включение видимости:


Для Счетчик = 1 По ШиринаМаксимальная Цикл
    ОбластьКолонки = ИсходныйТабличныйДокумент.Область(НачалоНовогоФорматаСтрок, Счетчик);
    ОбластьКолонки.ШиринаКолонки = ВторойТабличныйДокумент.Область(1, Счетчик).ШиринаКолонки;
    ОбластьКолонки.Видимость = Истина; // Гарантируем отображение
КонецЦикла;

Рекомендации по работе с макетами

Чтобы избежать подобных проблем в будущем, рекомендуем придерживаться следующих правил при проектировании макетов:

Подводя итог, можно сказать, что наиболее надежным способом является использование метода Вывести(). Если же вы вынуждены работать через ВставитьОбласть() и СоздатьФорматСтрок(), ключевым моментом будет тщательная установка ширины каждой колонки в новой области и контроль их видимости.

← На главную