Почему не открывается макет MS Word в серверной базе 1С и как это исправить?

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

При переходе с файловой базы 1С на клиент-серверный вариант (SQL) разработчики часто сталкиваются с ошибкой: печатная форма или макет отчета в формате Word перестает открываться. На сервере запускается фоновый процесс WinWord.exe, но пользователь не видит открытый документ, либо платформа выдает ошибку преобразования данных XDTO.

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

Причины возникновения ошибок

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

  1. Изоляция контекста сервера: Сервер 1С выполняется в отдельной системной сессии без доступа к графическому интерфейсу пользователя. Если вызывать создание COMОбъект("Word.Application") на сервере и устанавливать свойство Visible = Истина, процесс Word действительно зародится в диспетчере задач сервера, но на мониторе клиета ничего не появится.
  2. Невозможность передать COM-объект с сервера на клиент: COM-объекты жестко привязаны к процессу операционной системы, в котором они были созданы. Их нельзя передавать через параметры процедур или возвращать из серверных функций. Попытка вернуть созданный документ Word на клиент приводит к ошибке сериализации XDTO.
  3. Ошибки обращения к объектной модели Word: Коллекция закладок Bookmarks принадлежит объекту конкретного документа (Document), а не всему приложению Word.Application. Вызов метода непосредственно у приложения приводит к ошибке «Метод объекта не обнаружен».

Шаг 1. Передача макета с сервера на клиент

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

Сначала напишем серверную функцию, которая извлекает двоичные данные макета и помещает их во временное хранилище:


&НаСервере
Функция ПолучитьАдресМакетаНаСервере()
    
    ОбработкаОбъект = РеквизитФормыВЗначение("Отчет");
    ДвоичныеДанныеМакета = ОбработкаОбъект.ПолучитьМакет("ТД_Помбур4р");
    
    // Помещаем двоичные данные во временное хранилище
    АдресХранилища = ПоместитьВоВременноеХранилище(ДвоичныеДанныеМакета, ЭтаФорма.УникальныйИдентификатор);
    
    Возврат АдресХранилища;
    
КонецФункции

Шаг 2. Сохранение файла и вызов MS Word на клиенте

Теперь разберем клиентскую часть. На клиенте мы принимаем адрес временного хранилища, забираем двоичные данные, сохраняем их во временный файл на диске пользователя и работаем с 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();
    
КонецПроцедуры

Важные рекомендации при работе с COM-объектами

Посмотрим на несколько важных нюансов, которые помогут избежать ошибок при дальнейшей разработке:

  1. Разграничение объектной модели: Всегда обращайтесь к коллекциям Bookmarks, Tables, Paragraphs через объект открытого документа (Документ.Bookmarks), а к операциям выделения и вставки текста — через контекст приложения (WordApp.Selection).
  2. Очистка ресурсов: Если макет формируется в фоновом режиме (например, отправляется по почте) и не должен показываться пользователю, обязательно закрывайте документ Документ.Close() и завершайте процесс WordApp.Quit() внутри блока Попытка ... Исключение, чтобы на компьютере не накапливались зависшие процессы.
  3. Кроссплатформенность: Обратите внимание, что работа через COMОбъект поддерживается только на ОС Windows. Если сервер 1С работает под управлением Linux или пользователи заходят через веб-клиент, рекомендуется использовать подсистему «Управление печатью» из Библиотеки Стандартных Подсистем (БСП) для генерации DOCX-документов без использования COM.
← На главную