Как вывести макет в режиме предприятия с параметрами на обычных формах?

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

При разработке собственных редакторов печатных форм, этикеток или ценников в режиме предприятия на обычных формах (ОФ) разработчики часто сталкиваются со следующей проблемой: при попытке вывести предопределенный макет в элемент управления ПолеТабличногоДокумента на форме стандартным методом Вывести(), все параметры и шаблоны исчезают. Вместо привычных угловых скобок <ИмяПараметра> или квадратных скобок в шаблонах пользователь видит пустые ячейки.

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

Выясняем причину: почему стандартный метод Вывести() скрывает параметры?

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

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

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

Решение №1: Использование временного MXL-файла

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

Рассмотрим по шагам программный код для реализации этого подхода:


// 1. Получаем предопределенный макет из конфигурации
МакетИсточника = ПолучитьМакет("Макет");

// 2. Формируем путь к временному файлу на диске
ПутьКФайлу = КаталогВременныхФайлов() + "ВременныйМакет.mxl";

// 3. Записываем макет во временный файл
МакетИсточника.Записать(ПутьКФайлу);

// 4. Считываем файл напрямую в ПолеТабличногоДокумента на форме
ЭлементыФормы.ПолеТабличногоДокумента1.Прочитать(ПутьКФайлу);

// 5. Переводим табличный документ в режим макета для отображения параметров
ЭлементыФормы.ПолеТабличногоДокумента1.Макет = Истина;

// 6. Обязательно удаляем временный файл после чтения
Попытка
    УдалитьФайлы(ПутьКФайлу);
Исключение
    // Обработка возможных ошибок блокировки файла операционной системой
КонецПопытки;

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

Решение №2: Использование метода ВставитьОбласть() в оперативной памяти

Мы можем обойтись без использования временных файлов на диске. Для этого перенесем структуру ячеек из макета-источника в поле табличного документа в оперативной памяти.

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

Давайте проанализируем пример кода, реализующий этот алгоритм:


// Получаем макет-источник
ТабДокИсточник = ПолучитьМакет("ШаблонПоУмолчанию");
ТабличныйДокументПриемник = ЭлементыФормы.ТабличныйДокумент;

// Очищаем приемник перед выводом
ТабличныйДокументПриемник.Очистить();

// Определяем границы заполненной области в макете-источнике
Верх = 1;
Лево = 1;
Низ = ТабДокИсточник.ВысотаТаблицы;
Право = ТабДокИсточник.ШиринаТаблицы;

// Если макет не пустой, выполняем копирование областей
Если Низ > 0 И Право > 0 Тогда

    // Получаем точные координатные области источника и приемника
    ОбластьИсточника = ТабДокИсточник.Область(Верх, Лево, Низ, Право);
    ОбластьПриемника = ТабличныйДокументПриемник.Область(Верх, Лево, Низ, Право);
    
    // Вставляем область со всеми метаданными без смещения
    ТабличныйДокументПриемник.ВставитьОбласть(
        ОбластьИсточника, 
        ОбластьПриемника, 
        ТипСмещенияТабличногоДокумента.БезСмещения, 
        Ложь
    );

КонецЕсли;

// Активируем режим макета для отображения служебных символов параметров
ТабличныйДокументПриемник.Макет = Истина;

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

Свойства табличного документа для полноценного режима редактора

Чтобы превратить обычное ПолеТабличногоДокумента на форме в полноценный конструктор макетов, одной установки свойства Макет = Истина недостаточно. Нам необходимо настроить комбинацию свойств, которые позволят пользователю интерактивно редактировать данные.

Обязательно установите следующие свойства программно или в палитре свойств элемента формы:

  1. Макет = Истина — активирует специальный режим отрисовки табличного документа. Параметры и шаблоны начинают визуально выделяться спецсимволами, а на полях документа отображаются именованные области.
  2. Редактирование = Истина — разрешает интерактивное изменение ячеек пользователем прямо на форме.
  3. ТолькоПросмотр = Ложь — снимает ограничение на изменение структуры таблицы, изменение высоты строк и ширины колонок.

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

Хранение и повторное использование измененных макетов

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

Для хранения измененных макетов обычно создают справочник (например, ПользовательскиеМакеты), в котором присутствует реквизит с типом ХранилищеЗначений. Алгоритм сохранения выглядит следующим образом:


// Подготавливаем табличный документ к сохранению
// Рекомендуется временно отключить режим макета, чтобы не сохранять лишние служебные свойства редактора
ЭлементыФормы.ТабличныйДокумент.Макет = Ложь;

// Помещаем объект "ТабличныйДокумент" в ХранилищеЗначений
НовыйМакетХранилище = Новый ХранилищеЗначений(ЭлементыФормы.ТабличныйДокумент.Получить());

// Записываем в справочник
СправочникОбъект = Справочники.ПользовательскиеМакеты.СоздатьЭлемент();
СправочникОбъект.Наименование = "Мой измененный макет";
СправочникОбъект.ДанныеМакета = НовыйМакетХранилище;
СправочникОбъект.Записать();

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

Продвинутый уровень: Программный поиск новых параметров макета

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

Поскольку стандартного метода получения списка параметров у объекта ТабличныйДокумент нет, применим алгоритм обхода ячеек по координатам:


СписокПараметров = Новый СписокЗначений;

Для Строка = 1 По ТабличныйДокумент.ВысотаТаблицы Цикл
    Для Колонка = 1 По ТабличныйДокумент.ШиринаТаблицы Цикл
        
        Ячейка = ТабличныйДокумент.Область(Строка, Колонка);
        
        // Проверяем тип заполнения ячейки
        Если Ячейка.Заполнение = ТипЗаполненияОбластиТабличногоДокумента.Параметр Тогда
            Если ЗначениеЗаполнено(Ячейка.Текст) Тогда
                СписокПараметров.Добавить(Ячейка.Текст);
            КонецЕсли;
        ИначеЕсли Ячейка.Заполнение = ТипЗаполненияОбластиТабличногоДокумента.Шаблон Тогда
            // Из шаблона вида "[Контрагент] договор № [Номер]" нужно вырезать параметры регулярным выражением или поиском подстроки
            // Добавляем найденные параметры в общий список
        КонецЕсли;
        
    КонецЦикла;
КонецЦикла;

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

← На главную