При разработке расширений для 1С:Предприятие 8.3 программисты часто сталкиваются с неприятной ситуацией: в макете печатной формы (MXL), добавленном или измененном через расширение, настроено объединение ячеек, но при реальном выводе на экран или на печать это объединение бесследно исчезает. Ячейки «разбиваются» на исходную сетку, текст обрезается или переносится некорректно, хотя в конфигураторе макет выглядит идеально.
Рассмотрим природу этой проблемы, проанализируем причины ее возникновения на уровне платформы и разберем проверенные способы решения — от программного управления областью до настройки прав доступа и кэша.
Проблема носит технический характер и связана с тем, как платформа 1С сериализует и объединяет метаданные расширения с основной конфигурацией. Проанализируем основные факторы:
.mxl информация об объединении ячеек хранится в специальном блоке mergedItems. При использовании механизмов расширений (особенно в режиме ИзменениеИКонтроль) платформа иногда игнорирует этот блок, если структура колонок в расширении не полностью совпадает с «родительским» макетом.ТабличныйДокумент.Присоединить(), платформа пытается втиснуть новую область в существующую сетку колонок. Если ширина колонок в области из расширения отличается хотя бы на микрон, объединение «схлопывается».Разберем по шагам три основных способа решения этой проблемы.
Как показывает практика, это самый стабильный метод. Если платформа игнорирует настройки макета, мы заставим её выполнить объединение принудительно сразу после вывода области в табличный документ. Рассмотрим пример кода, который позволяет динамически определить границы области и объединить их.
Предположим, нам нужно вывести строку с комментарием, которая должна занимать всю ширину таблицы (со 2-й колонки по последнюю). Посмотрим на пример реализации:
// Получаем текст комментария из данных документа
КомментарийСтроки = СведенияОДокументе.Документ.Услуги[СтрокаТабличнойЧасти.НомерСтроки-1].КомментарийСтроки;
Если НЕ КомментарийСтроки = "" Тогда
// Выводим пустую или базовую область из макета
ТабличныйДокумент.Вывести(ОбластьКомментарий);
// Определяем координаты только что выведенной строки
НомерПоследнейСтроки = ТабличныйДокумент.ВысотаТаблицы;
НомерПоследнейКолонки = ТабличныйДокумент.ШиринаТаблицы;
// Формируем адрес области (например, от 2-й колонки до конца документа)
АдресОбласти = "R" + Формат(НомерПоследнейСтроки, "ЧГ=0") + "C2" + ":" + "R" + Формат(НомерПоследнейСтроки, "ЧГ=0") + "C" + Формат(НомерПоследнейКолонки, "ЧГ=0");
// Получаем область и объединяем ячейки программно
ОбластьДляОбъединения = ТабличныйДокумент.Область(АдресОбласти);
ОбластьДляОбъединения.Объединить();
// Устанавливаем свойства отображения
ОбластьДляОбъединения.ГоризонтальноеПоложение = ГоризонтальноеПоложение.Лево;
ОбластьДляОбъединения.Текст = КомментарийСтроки;
// При необходимости можно программно отрисовать границы (рамку)
ТонкаяЛиния = Новый Линия(ТипЛинииЯчейкиТабличногоДокумента.Сплошная, 1);
ОбластьДляОбъединения.Обвести(ТонкаяЛиния, ТонкаяЛиния, ТонкаяЛиния, ТонкаяЛиния);
КонецЕсли;
Используя свойства ВысотаТаблицы и ШиринаТаблицы, мы всегда точно попадаем в нужный диапазон, даже если количество колонок в документе меняется динамически.
Если вы не хотите менять код, стоит проверить настройки в режиме «1С:Предприятие». Часто проблема кроется в том, что система «запомнила» старую структуру макета до того, как вы объединили ячейки в расширении. Разобраться в тонкостях работы с такими шаблонами поможет инструкция по редактированию печатных форм в пользовательском режиме 1С.
Проанализируем алгоритм действий:
Если модификация стандартного макета через ИзменениеИКонтроль продолжает выдавать ошибки верстки, рассмотрим вариант создания собственного объекта. Вместо того чтобы править заимствованный макет ПФ_MXL_Акт, добавьте в расширение новый макет с уникальным именем, например Доп_ПФ_MXL_Акт.
В коде печати замените получение области:
// Вместо получения области из стандартного макета:
// Макет = УправлениеПечатью.МакетПечатнойФормы("ОбщийМакет.ПФ_MXL_Акт");
// Используем макет, созданный непосредственно в расширении:
Макет = ЭтотОбъект.ПолучитьМакет("Доп_ПФ_MXL_Акт");
Создание макета «с нуля» внутри расширения позволяет избежать конфликтов при объединении XML-структур основной конфигурации и расширения. В этом случае 1С воспринимает макет как абсолютно новый объект и корректно обрабатывает блок mergedItems.
Посмотрим на несколько важных нюансов, которые могут влиять на результат:
Очистка серверного кэша: Иногда платформа «кэширует» структуру макета. Если вы изменили объединение ячеек, но в расширении это не отразилось, попробуйте перезапустить сервер 1С или удалить содержимое папок snccntx и configsave в каталоге описания информационной базы на сервере.
Режим совместимости: Убедитесь, что режим совместимости расширения совпадает с режимом совместимости основной конфигурации. Различия в версиях движка рендеринга табличных документов часто приводят к «поплывшей» верстке.
Свойство Текст вместо Параметр: Замечено, что объединение ячеек реже «слетает», если ячейка в макете определена как Текст, а не как Параметр. Вы можете оставить ячейку текстовой и заполнять её значение программно через Область.Текст = Значение.
Подводя итог, можно сказать: если проблема носит разовый характер, проще всего поправить объединение в Пользовательских макетах печати. Если же вы разрабатываете тиражное решение, лучше один раз прописать программное объединение в коде через метод Объединить(), что гарантирует корректный вид печатной формы на любой версии платформы.