При разработке внешних печатных форм (ВПФ) на базе Microsoft Word для типовых конфигураций 1С (таких как «1С:Управление торговлей», «1С:ERP» или «1С:Комплексная автоматизация») начинающие разработчики часто сталкиваются с серией взаимосвязанных ошибок. Проанализируем типичные причины сбоев, выясним их природу и разберем корректную реализацию формирования документов Word.
Эта ошибка возникает в общем модуле подсистемы «Дополнительные отчеты и обработки» библиотеки стандартных подсистем (БСП). Причина заключается в несоответствии типа команды в функции СведенияОВнешнейОбработке() и сигнатуры экспортной процедуры печати.
В зависимости от выбранного варианта запуска команда ожидает определенное количество и состав параметров:
В функции регистрации указывается вариант ВызовСерверногоМетода. Экспортная процедура должна быть объявлена в модуле объекта обработки со следующими четырьмя параметрами:
Процедура Печать(МассивОбъектов, КоллекцияПечатныхФорм, ОбъектыПечати, ПараметрыВывода) Экспорт
// Код формирования печатной формы на сервере
КонецПроцедуры
Если для формирования файла Word используется COM-объект, вызов приложения Word.Application должен происходить на стороне клиента. В этом случае в таблице команд задается тип ВызовКлиентскогоМетода. В модуле формы обработки объявляется клиентская процедура с двумя параметрами:
&НаКлиенте
Процедура Печать(ИдентификаторКоманды, МассивОбъектов) Экспорт
// Код вывода печатной формы на клиенте
КонецПроцедуры
Следующая ошибка, с которой сталкиваются разработчики при попытке получить макет типа ActiveDocument на сервере и вернуть его на клиент:
Ошибка при вызове метода контекста: Ошибка передачи данных между клиентом и сервером. Значение недопустимого типа. Ошибка преобразования данных XDTO...
Выясним причину: тип ActiveDocument, как и прямые COM-объекты, не является сериализуемым типом платформы 1С:Предприятие. Сервер не может передать COM-объект или макет ActiveDocument клиенту напрямую через вызов функции.
Кроме того, метод РеквизитФормыВЗначение доступен исключительно в контексте &НаСервере, поэтому попытка вызвать его на клиенте приводит к ошибке «Метод недоступен на клиенте».
Рассмотрим проверенный способ вывода печатной формы Word на стороне клиента с использованием макета типа Двоичные данные.
В конфигураторе добавьте в обработку макет. В поле «Тип макета» выберите Двоичные данные и загрузите заранее подготовленный шаблон договора или документа в формате .doc или .docx. Внутри документа расставьте маркеры для автозамены, например, {НомерДоговора}, {ДатаДоговора}, {Контрагент}.
В модуле формы обработки реализуем серверную функцию, которая извлекает двоичные данные макета:
&НаСервере
Функция ПолучитьДвоичныеДанныеМакетаНаСервере(ИмяМакета)
ОбработкаОбъект = РеквизитФормыВЗначение("Объект");
Возврат ОбработкаОбъект.ПолучитьМакет(ИмяМакета);
КонецФункции
На стороне клиента сохраняем двоичные данные во временный файл, открываем его через COM-объект Microsoft Word, выполняем замену меток и делаем окно приложения видимым для пользователя:
&НаКлиенте
Процедура Печать(ИдентификаторКоманды, МассивОбъектов) Экспорт
// 1. Получаем макет в виде двоичных данных с сервера
ДвоичныеДанныеМакета = ПолучитьДвоичныеДанныеМакетаНаСервере("ПФ_WORD_Договор");
// 2. Формируем временный файл на клиенте
ИмяВременногоФайла = ПолучитьИмяВременногоФайла("doc");
ДвоичныеДанныеМакета.Записать(ИмяВременногоФайла);
// 3. Подключаемся к MS Word через COM
Попытка
MSWord = Новый COMОбъект("Word.Application");
Исключение
Сообщить("Не удалось запустить Microsoft Word. Проверьте установку офисного пакета: " + ОписаниеОшибки());
УдалитьФайлы(ИмяВременногоФайла);
Возврат;
КонецПопытки;
// 4. Открываем созданный временный документ
Документ = MSWord.Documents.Add(ИмяВременногоФайла);
// 5. Выполняем поиск и замену текстовых маркеров
ПоискИЗамена = Документ.Content.Find;
ПоискИЗамена.Execute("{Номер}", Ложь, Истина, Ложь, , , Истина, , Ложь, "123-А");
ПоискИЗамена.Execute("{Дата}", Ложь, Истина, Ложь, , , Истина, , Ложь, Формат(ТекущаяДата(), "ДФ=dd.MM.yyyy"));
// 6. Показываем приложение пользователю
MSWord.Visible = Истина;
MSWord.Activate();
// Удаляем временный исходный файл
УдалитьФайлы(ИмяВременногоФайла);
КонецПроцедуры
Разберем важные нюансы, которые необходимо учитывать при промышленной эксплуатации решений на базе COM:
Объект COMОбъект("Word.Application") работает только под управлением ОС Windows с установленным пакетом Microsoft Office. Он не будет работать в веб-клиенте, на операционных системах Linux и macOS, а также на сервере 1С под Linux.
Запуск процессов Microsoft Word в фоновых серверных сессиях официально не поддерживается Microsoft. Это приводит к зависанию процессов WINWORD.EXE в памяти и падению рабочих процессов сервера 1С. Любая работа с COM-автоматизацией офисных программ должна выполняться строго на стороне клиента.
В современных конфигурациях 1С рекомендуется использовать встроенную подсистему «Управление печатью» (модули УправлениеПечатьюMSWordКлиент и УправлениеПечатьюOOWriterКлиент). Механизм БСП позволяет формировать печатные формы как для MS Word (DOCX), так и для OpenOffice/LibreOffice (ODT) по унифицированным правилам разметки областей.
Если нет жесткого требования использовать готовый документ Word со сложным форматированием, наиболее надежным и кроссплатформенным решением является создание макета типа Табличный документ. Сформированный результат можно программно сохранить в формат DOCX или PDF штатным методом платформы ТабличныйДокумент.Записать(ИмяФайла, ТипФайлаТабличногоДокумента.DOCX), что не требует наличия стороннего офисного ПО.