При переходе с файловой базы 1С на клиент-серверный вариант (SQL) разработчики часто сталкиваются с ошибкой: печатная форма или макет отчета в формате Word перестает открываться. На сервере запускается фоновый процесс WinWord.exe, но пользователь не видит открытый документ, либо платформа выдает ошибку преобразования данных XDTO.
В этой статье мы подробно проанализируем причины возникновения этой проблемы и разберем по шагам правильный алгоритм работы с макетами MS Word в управляемом приложении.
Рассмотрим, почему стандартный код, работающий в файловой базе или на локальном компьютере, сбоит на сервере:
COMОбъект("Word.Application") на сервере и устанавливать свойство Visible = Истина, процесс Word действительно зародится в диспетчере задач сервера, но на мониторе клиета ничего не появится.Bookmarks принадлежит объекту конкретного документа (Document), а не всему приложению Word.Application. Вызов метода непосредственно у приложения приводит к ошибке «Метод объекта не обнаружен».Выясним правильную схему взаимодействия. Макет хранятся в метаданных конфигурации или внешней обработки, поэтому получить его можно только на сервере. Однако открывать и заполнять его необходимо строго на клиенте.
Сначала напишем серверную функцию, которая извлекает двоичные данные макета и помещает их во временное хранилище:
&НаСервере
Функция ПолучитьАдресМакетаНаСервере()
ОбработкаОбъект = РеквизитФормыВЗначение("Отчет");
ДвоичныеДанныеМакета = ОбработкаОбъект.ПолучитьМакет("ТД_Помбур4р");
// Помещаем двоичные данные во временное хранилище
АдресХранилища = ПоместитьВоВременноеХранилище(ДвоичныеДанныеМакета, ЭтаФорма.УникальныйИдентификатор);
Возврат АдресХранилища;
КонецФункции
Теперь разберем клиентскую часть. На клиенте мы принимаем адрес временного хранилища, забираем двоичные данные, сохраняем их во временный файл на диске пользователя и работаем с COM-объектом Microsoft Word.
Проанализируем готовый пример клиентского кода:
&НаКлиенте
Процедура СформироватьИОткрытьМакет()
// 1. Получаем адрес файла во временном хранилище
АдресМакета = ПолучитьАдресМакетаНаСервере();
// 2. Извлекаем двоичные данные на стороне клиента
ДвоичныеДанныеМакета = ПолучитьИзВременногоХранилища(АдресМакета);
// 3. Создаем временный файл на диске клиента
ИмяВременногоФайла = ПолучитьИмяВременногоФайла("docx");
ДвоичныеДанныеМакета.Записать(ИмяВременногоФайла);
// 4. Инициализируем COM-объект Word на клиенте
Попытка
WordApp = Новый COMОбъект("Word.Application");
Исключение
ПоказатьПредупреждение(), "Не удалось создать объект MS Word. Проверьте, установлен ли MS Office.");
Возврат;
КонецПопытки;
// 5. Открываем сохраненный файл
Документ = WordApp.Documents.Open(ИмяВременногоФайла);
// 6. Заполняем данные по закладкам (Bookmarks) через объект Документа
Если Документ.Bookmarks.Exists("ТабН") Тогда
Документ.Bookmarks("ТабН").Select();
WordApp.Selection.TypeText("123456");
КонецЕсли;
// 7. Делаем приложение видимым для пользователя
WordApp.Visible = Истина;
WordApp.Activate();
КонецПроцедуры
Посмотрим на несколько важных нюансов, которые помогут избежать ошибок при дальнейшей разработке:
Bookmarks, Tables, Paragraphs через объект открытого документа (Документ.Bookmarks), а к операциям выделения и вставки текста — через контекст приложения (WordApp.Selection).Документ.Close() и завершайте процесс WordApp.Quit() внутри блока Попытка ... Исключение, чтобы на компьютере не накапливались зависшие процессы.COMОбъект поддерживается только на ОС Windows. Если сервер 1С работает под управлением Linux или пользователи заходят через веб-клиент, рекомендуется использовать подсистему «Управление печатью» из Библиотеки Стандартных Подсистем (БСП) для генерации DOCX-документов без использования COM.