При разработке внешних печатных форм и обработок в среде управляемого приложения разработчики часто сталкиваются с задачей заполнения шаблонов в формате Microsoft Word (DOC/DOCX). Традиционный для обычных форм подход с использованием макета типа ActiveDocument на управляемых формах приводит к системным ошибкам клиент-серверного взаимодействия.
Проанализируем причины возникновения этой проблемы и подробно рассмотрим рабочие варианты правильной реализации печати Word-документов в 1С:Предприятии 8.3.
Разберем типичную попытку получения макета на сервере с последующей передачей на клиент:
&НаСервере
Функция ПолучитьМакетДокумента()
ОбъектОбработки = РеквизитФормыВЗначение("Объект");
Возврат ОбъектОбработки.ПолучитьМакет("Макет");
КонецФункции
&НаКлиенте
Процедура СформироватьДокумент()
МакетНаКлиенте = ПолучитьМакетДокумента();
КонецПроцедуры
При выполнении этого кода платформа выдает исключение: Ошибка отображения типов: Отсутствует отображение для типа "ОболочкаActiveDocument".
Выясним причину такого поведения платформы. Объект ОболочкаActiveDocument представляет собой клиентскую OLE/COM-обертку операционной системы Windows. Данный тип данных не является сериализуемым, поэтому платформа 1С принципиально не может передать его через контекстную границу вызова между сервером и клиентом.
Попытка вызвать метод Макет.Получить() непосредственно на сервере также приводит к ошибке, если служба сервера 1С запущена в неинтерактивной сессии (Session 0) без прав на запуск COM-серверов или если сервер функционирует под управлением ОС Linux, где Microsoft Office отсутствует.
Рассмотрим надежные и проверенные способы реализации печати.
Наиболее простое и стабильное решение для вывода печатной формы через установленный у пользователя Microsoft Word — изменить тип макета в конфигураторе с ActiveDocument на Двоичные данные.
Разберем пошаговый алгоритм реализации:
.doc или .docx).Посмотрим на пример программного кода:
&НаСервере
Функция ПолучитьАдресМакетаВоВременномХранилище()
ЭтотОбъект = РеквизитФормыВЗначение("Объект");
МакетДвоичныеДанные = ЭтотОбъект.ПолучитьМакет("МакетДвоичныеДанные");
Возврат ПоместитьВоВременноеХранилище(МакетДвоичныеДанные, УникальныйИдентификатор);
КонецФункции
&НаКлиенте
Процедура СформироватьИОткрытьДокументWord()
АдресХранилища = ПолучитьАдресМакетаВоВременномХранилище();
ДвоичныеДанные = ПолучитьИзВременногоХранилища(АдресХранилища);
// Формируем имя временного файла
ИмяВременногоФайла = ПолучитьИмяВременногоФайла("docx");
ДвоичныеДанные.Записать(ИмяВременногоФайла);
// Работаем с COM-объектом Word на стороне клиента
Попытка
MSWord = Новый COMОбъект("Word.Application");
MSWord.Visible = Истина;
Документ = MSWord.Documents.Open(ИмяВременногоФайла);
// Выполняем заполнение параметров или замену закладок
// ...
MSWord.Activate();
Исключение
Предупреждение("Не удалось запустить Microsoft Word. Проверьте, установлена ли программа.");
КонецПопытки;
КонецПроцедуры
Если в макет не требуется подставлять параметры программно через COM, а нужно только выгрузить и открыть готовый сформированный файл во внешней программе, используем процедуру запуска приложений операционной системы:
&НаКлиенте
Процедура ОткрытьШаблонВWord()
АдресХранилища = ПолучитьАдресМакетаВоВременномХранилище();
ДвоичныеДанные = ПолучитьИзВременногоХранилища(АдресХранилища);
ИмяФайла = ПолучитьИмяВременногоФайла("docx");
ДвоичныеДанные.Записать(ИмяФайла);
// Запуск стандартного приложения, ассоциированного с расширением .docx
ЗапуститьПриложение(ИмяФайла);
КонецПроцедуры
Этот подход избавляет от жесткой привязки к COM-модели конкретной версии Microsoft Office и корректно открывает документ в любом офисном пакете, установленном в операционной системе пользователя по умолчанию.
Если печатная форма разрабатывается для стандартной подсистемы печати БСП или не требует специфических возможностей форматирования MS Word, рассмотрим альтернативу на основе объекта ТабличныйДокумент.
ТабличныйДокумент.Записать(ПутьКФайлу, ТипФайлаТабличногоДокумента.DOCX);
Такой подход обеспечивает максимальную производительность, кроссплатформенность серверной части и независимость от стороннего программного обеспечения.