Как использовать внешний mxl-файл в качестве макета для заполнения параметров?

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

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

Анализ исходной проблемы

Рассмотрим ситуацию, с которой столкнулся автор вопроса. При попытке прочитать внешний файл и вывести его области с заполненными параметрами, 1С выдает две страницы: одну с именами параметров (как в макете) и вторую — с реальными данными. Посмотрим на исходный код, который привел к такому результату:


ТабДок = новый ТабличныйДокумент;
табдок.Прочитать("C:\LNA\LNA.mxl");
Областьмакета = табдок.ПолучитьОбласть("ОбластьПечать");
Областьмакета.Параметры.ДатаДок = Формат(ТекущаяДата(), "ДФ='''""''дд''""'' ММММ гггг ''г.'''");
ТабДок.Вывести(областьмакета);
Табдок.Показать();

Выясним причину ошибки: когда мы вызываем метод Прочитать(), объект ТабДок перестает быть «чистым листом». Он превращается в сам макет. Когда мы получаем область из этого же документа и затем делаем ТабДок.Вывести(Областьмакета), мы просто дописываем (дублируем) в конец этого же макета еще одну область, но уже с заполненными параметрами. В итоге мы видим и исходный шаблон, и результат под ним.

Правильная архитектура работы с внешним макетом

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

  1. Объект-источник (Макет): он служит только для хранения структуры, оформления и имен параметров. Мы читаем его из файла.
  2. Объект-приемник (Результат): это пустой документ, в который мы будем последовательно «собирать» заполненные области.

Разберем исправленный код, который решает задачу:


// 1. Создаем объект, который будет содержать наш макет
МакетИсточник = Новый ТабличныйДокумент;
МакетИсточник.Прочитать("C:\LNA\LNA.mxl");

// 2. Создаем чистый объект для формирования итогового отчета
ТабДокРезультат = Новый ТабличныйДокумент;

// 3. Извлекаем нужную область из макета-источника
Область = МакетИсточник.ПолучитьОбласть("ОбластьПечать");

// 4. Заполняем параметры в полученной области
Область.Параметры.ДатаДок = Формат(ТекущаяДата(), "ДФ='дд ММММ гггг'");
Область.Параметры.ФИО = "Иванов Иван Иванович";

// 5. Выводим заполненную область в итоговый документ
ТабДокРезультат.Вывести(Область);

// 6. Показываем результат пользователю
ТабДокРезультат.Показать("Печать документа из внешнего макета");

Настройка самого файла .mxl

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

Установка параметров в ячейках: в режиме 1С:Предприятие (при редактировании макета) выделите ячейку, нажмите правую кнопку мыши и выберите «Свойства». В поле «Заполнение» должно быть выбрано значение «Параметр». Если там стоит «Текст», 1С воспримет название параметра просто как обычную надпись и код Область.Параметры.ИмяПараметра выдаст ошибку.

Использование шаблонов: если вам нужно смешать статичный текст и динамические данные в одной ячейке (например, «Договор № [Номер] от [Дата]»), установите в свойстве «Заполнение» значение «Шаблон». Тогда текст внутри квадратных скобок будет программно доступен через коллекцию Параметры.

Именованные области: обязательно выделите строки или колонки, которые планируете выводить, и через меню «Таблица -> Имена -> Назначить имя» задайте имя области (например, ОбластьПечать). Именно к этому имени мы обращаемся в методе ПолучитьОбласть().

Рекомендации по работе в клиент-серверном режиме

При использовании внешних файлов важно помнить о среде выполнения. Рассмотрим подробнее проблемы доступа к путям:

Разберем пример безопасного чтения макета, если он хранится в справочнике как двоичные данные:


// Получаем двоичные данные из хранилища (примерная логика)
ДвоичныеДанныеМакета = Справочники.МакетыПечатныхФорм.НайтиПоНаименованию("МойМакет").Данные.Получить();

// Создаем временный файл
ИмяВременногоФайла = ПолучитьИмяВременногоФайла("mxl");
ДвоичныеДанныеМакета.Записать(ИмяВременногоФайла);

// Читаем макет
Макет = Новый ТабличныйДокумент;
Макет.Прочитать(ИмяВременногоФайла);

// Удаляем временный файл после использования
УдалитьФайлы(ИмяВременногоФайла);

Оптимизация производительности

Посмотрим на ситуацию с точки зрения ресурсов. Метод Прочитать() — достаточно «дорогой» для системы, так как обращается к диску. Если вы печатаете 100 документов в цикле, не стоит читать файл 100 раз.

Проанализируем правильный цикл: сначала мы один раз считываем макет в переменную-контейнер, а затем в цикле только получаем области и заполняем их. Это ускорит работу в разы, так как данные будут браться из оперативной памяти, а не с жесткого диска.

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

← На главную