Как сделать выгрузку данных документа в текстовый файл через внешнюю печатную форму или обработку?

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

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

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

Почему внешняя печатная форма выдает ошибку при выгрузке файла

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

  1. Она ожидает обязательного заполнения переданной таблицы КоллекцияПечатныхФорм готовыми объектами типа ТабличныйДокумент. Если макет не заполнен или в коллекцию ничего не добавлено, подсистема печати генерирует исключение об отсутствии сформированных печатных форм.
  2. Команда печати с типовым вызовом серверного метода выполняется исключительно в контексте сервера. На стороне сервера платформа 1С не имеет прямого доступа к файловой системе клиентского рабочего места, не может открыть ДиалогВыбораФайла и сохранить данные на диск пользователя.

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

Способ 1. Использование внешней обработки с вызовом клиентского метода

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

В функции СведенияОВнешнейОбработке модуля объекта укажем параметры команды:


Функция СведенияОВнешнейОбработке() Экспорт
    ПараметрыРегистрации = ДополнительныеОтчетыИОбработки.СведенияОВнешнейОбработке();
    ПараметрыРегистрации.Вид = ДополнительныеОтчетыИОбработкиКлиентСервер.ВидОбработкиПечатнаяФорма();
    ПараметрыРегистрации.Версия = "1.0";
    ПараметрыРегистрации.Назначение.Добавить("Документ.РеализацияТоваровУслуг");
    
    Команда = ПараметрыРегистрации.Команды.Добавить();
    Команда.Представление = НСтр("ru = 'Выгрузить в текстовый файл'");
    Команда.Идентификатор = "ВыгрузитьВФайл";
    Команда.Использование = ДополнительныеОтчетыИОбработкиКлиентСервер.ТипКомандыВызовКлиентскогоМетода();
    Команда.ПоказыватьОповещение = Истина;
    
    Возврат ПараметрыРегистрации;
КонецФункции

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


&НаСервере
Функция СформироватьФайлНаСервере(МассивОбъектов)
    ИмяВременногоФайла = ПолучитьИмяВременногоФайла("txt");
    
    ТекстовыйФайл = Новый ЗаписьТекста(ИмяВременногоФайла, КодировкаТекста.UTF8);
    Для Каждого СсылкаНаОбъект Из МассивОбъектов Цикл
        ТекстовыйФайл.ЗаписатьСтроку("Документ: " + Строка(СсылкаНаОбъект));
    КонецЦикла;
    ТекстовыйФайл.Закрыть();
    
    ДвоичныеДанные = Новый ДвоичныеДанные(ИмяВременногоФайла);
    УдалитьФайлы(ИмяВременногоФайла);
    
    Возврат ПоместитьВоВременноеХранилище(ДвоичныеДанные, УникальныйИдентификатор);
КонецФункции

&НаКлиенте
Процедура ВыполнитьКоманду(ИдентификаторКоманды, ОбъектыНазначения) Экспорт
    АдресФайла = СформироватьФайлНаСервере(ОбъектыНазначения);
    ПараметрыПолучения = Новый ПараметрыПолученияФайлаССервера("ВыгрузкаДокументов.txt");
    НачатьПолучениеФайлаССервера(Новый ОписаниеОповещения("ПослеПолученияФайла", ЭтотОбъект), АдресФайла, ПараметрыПолучения);
КонецПроцедуры

&НаКлиенте
Процедура ПослеПолученияФайла(Результат, ДополнительныеПараметры) Экспорт
    ПоказатьОповещениеПользователя(НСтр("ru = 'Выгрузка завершена'"));
КонецПроцедуры

Способ 2. Регистрация обработки с другим видом назначения

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

  1. ВидОбработкиСозданиеСвязанныхОбъектов() — команда появится в командной панели документа в подменю создания на основании.
  2. ВидОбработкиЗаполнениеОбъекта() — команда разместится в меню заполнения документа или его табличных частей.

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

Способ 3. Перехват через собственную форму обработки

Рассмотрим вариант, при котором команда печати открывает пользовательскую форму внешней обработки (тип команды ОткрытиеФормы):

  1. При вызове команды система открывает экранную форму обработки, где пользователь может указать дополнительные параметры выгрузки или путь к каталогу.
  2. По нажатию кнопки в форме выполняется серверный алгоритм формирования файла.
  3. Двоичные данные передаются на клиент и сохраняются методом НачатьПолучениеФайлаССервера().
  4. После завершения записи форма программно закрывается методом Закрыть(). До вызова серверного обработчика стандартной печати дело даже не доходит, что полностью исключает ошибку незаполненного макета.

Способ 4. Формирование текстового файла через ТабличныйДокумент

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

  1. В процедуре Печать создаем стандартный ТабличныйДокумент.
  2. Построчно выводим требуемые текстовые данные в ячейки первой колонки документа.
  3. Регистрируем сформированный документ в КоллекцияПечатныхФорм.

В этом случае подсистема БСП отработает штатно и откроет форму предварительного просмотра печати. Пользователь сможет сохранить полученный результат через меню программы «Файл — Сохранить как», выбрав тип файла «Текстовый документ (*.txt)».

Важные рекомендации при работе с файлами

Обратим внимание на критические нюансы платформы 1С:

  1. Асинхронность вызовов: избегаем использования устаревшего синхронного метода ПолучитьФайл(), так как при отключенной модальности или работе в веб-клиенте он вызовет исключительную ситуацию. Всегда используем метод НачатьПолучениеФайлаССервера().
  2. Кодировка текста: при инициализации объекта ЗаписьТекста обязательно явно указываем кодировку (например, КодировкаТекста.UTF8 или КодировкаТекста.ANSI), чтобы предотвратить искажение символов при передаче файла между сервером под управлением Linux и клиентским приложением под Windows.
← На главную