Как открыть документ Word, сформированный на сервере 1С, без ошибок COM-объекта?

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

При работе в клиент-серверном режиме 1С разработчики часто сталкиваются с технической проблемой: код формирования печатной формы в формате MS Word, который отлично работал в файловой базе или на клиенте, начинает выдавать «Неизвестную ошибку» на сервере при попытке сделать приложение видимым через свойство Visible = Истина.

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

Выясняем причину: почему на сервере не работает Visible = Истина?

Проанализируем ситуацию с точки зрения операционной системы. Служба сервера «1С:Предприятие» (обычно это учетная запись USR1CV8) работает в так называемой «Сессии 0» (Session 0). Это изолированная системная сессия Windows, которая принципиально не имеет графического интерфейса (GUI).

Когда в серверном коде выполняется следующая команда:


сом = Новый COMОбъект("Word.Application");
сом.Visible = Истина; // Здесь происходит падение программы

Операционная система пытается инициализировать графическое окно текстового редактора MS Word внутри сессии службы 1С. Так как графическая подсистема для этой службы недоступна, вызов свойства Visible или метода Activate() закономерно возвращает критическую ошибку. Более того, даже если опустить свойство видимости, на сервере может банально отсутствовать установленный пакет Microsoft Office.

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

---

Решение 1. Генерация файла на сервере и его запуск на клиенте

Это самый популярный и надежный способ. Мы разделяем задачу на два этапа: сервер берет на себя тяжелую работу по формированию файла (без вывода на экран), а клиентская часть забирает готовый файл и запускает его локально у пользователя.

Разберем по шагам, как построить эту схему:

  1. На сервере создается COMОбъект("Word.Application") в фоновом (невидимом) режиме.
  2. Документ заполняется данными, после чего сохраняется во временную папку сервера.
  3. Файл упаковывается в двоичные данные и помещается во временное хранилище 1С.
  4. На клиенте адрес хранилища считывается, файл записывается на локальный диск пользователя и запускается через стандартные средства операционной системы.

Посмотрим на пример реализации серверной функции:


&НаСервере
Функция СформироватьДокументНаСервере()
    
    // Инициализируем Word в фоновом режиме
    Попытка
        WordApp = Новый COMОбъект("Word.Application");
    Исключение
        ВызватьИсключение "На сервере не установлен MS Word или отсутствуют права на COM!";
    КонецПопытки;
    
    WordApp.Visible = Ложь;
    WordApp.DisplayAlerts = 0; // Отключаем предупреждения
    
    // Создаем или открываем шаблон
    ИмяФайлаШаблона = ПолучитьИмяВременногоФайла("docx");
    // [Здесь должна быть логика извлечения макета и записи его в ИмяФайлаШаблона]
    
    НовыйДок = WordApp.Documents.Add(ИмяФайлаШаблона);
    
    // Выполняем автозамену параметров в документе
    // Например: НовыйДок.Variables("ИмяКлиента").Value = "Иванов И.И.";
    
    // Сохраняем результат во временный файл на сервере
    ИмяВыходногоФайла = ПолучитьИмяВременногоФайла("docx");
    НовыйДок.SaveAs(ИмяВыходногоФайла);
    
    // Обязательно закрываем Word и очищаем память!
    НовыйДок.Close(Ложь);
    WordApp.Quit();
    WordApp = Неопределено;
    
    // Помещаем готовый файл во временное хранилище
    ДвоичныеДанныеФайла = Новый ДвоичныеДанные(ИмяВыходногоФайла);
    АдресХранилища = ПоместитьВоВременноеХранилище(ДвоичныеДанныеФайла, Новый УникальныйИдентификатор);
    
    // Удаляем временные файлы на сервере
    УдалитьФайлы(ИмяВыходногоФайла);
    УдалитьФайлы(ИмяФайлаШаблона);
    
    Возврат АдресХранилища;
    
КонецФункции

Теперь рассмотрим клиентскую процедуру, которая забирает этот файл и открывает его для пользователя:


&НаКлиенте
Процедура СформироватьИОткрытьДокумент()
    
    // Шаг 1. Получаем адрес временного хранилища с сервера
    АдресФайла = СформироватьДокументНаСервере();
    
    Если ЗначениеЗаполнено(АдресФайла) Тогда
        
        // Шаг 2. Получаем двоичные данные на клиенте
        ДвоичныеДанныеКлиент = ПолучитьИзВременногоХранилища(АдресФайла);
        
        // Шаг 3. Записываем файл в локальную временную папку пользователя
        ИмяФайлаНаКлиенте = ПолучитьИмяВременногоФайла("docx");
        ДвоичныеДанныеКлиент.Записать(ИмяФайлаНаКлиенте);
        
        // Шаг 4. Запускаем ассоциированное приложение (MS Word, LibreOffice и т.д.)
        ЗапуститьПриложение(ИмяФайлаНаКлиенте);
        
    КонецЕсли;
    
КонецПроцедуры

---

Решение 2. Перенос выполнения внешней печатной формы на клиент (БСП)

Часто разработчики утверждают: «Я не могу выполнить код на клиенте, так как моя обработка зарегистрирована как внешняя печатная форма и вызывается из модуля объекта». Это распространенное заблуждение.

Если ваша конфигурация использует Библиотеку стандартных подсистем (БСП), вы можете гибко управлять контекстом исполнения команды. Рассмотрим, как это настроить в функции СведенияОВнешнейОбработке() в модуле объекта вашей внешней обработки.

Вместо использования серверного метода по умолчанию, настройте запуск клиентского метода:


ПараметрыРегистрации = ДополнительныеОтчетыИОбработки.СведенияОВнешнейОбработке("2.2.2.1");

// Заполняем основные параметры...
// ...

// Настройка команды печатной формы
НоваяСтрока = ПараметрыРегистрации.Команды.Добавить();
НоваяСтрока.Представление = "Печать договора в Word (на клиенте)";
НоваяСтрока.Идентификатор = "ДоговорWordКлиент";

// ВНИМАНИЕ: Указываем способ вызова на клиенте!
НоваяСтрока.Использование = ДополнительныеОтчетыИОбработкиКлиентСервер.СпособВызоваВнешнейОбработки().ОткрытиеФормы;
// Или: ДополнительныеОтчетыИОбработкиКлиентСервер.СпособВызоваВнешнейОбработки().ВызовКлиентскогоМетода;

При такой настройке БСП передаст управление в модуль формы вашей внешней обработки. Вы сможете без труда создать COMОбъект("Word.Application") непосредственно на компьютере пользователя, где Word гарантированно установлен и доступен визуально, а данные для заполнения будете получать с сервера через легкие экспортные функции.

---

Решение 3. Использование механизмов БСП для работы с .docx без COM

Самый прогрессивный и современный подход, который полностью исключает использование COM-технологий на сервере (что особенно актуально при переходе серверов 1С на операционную систему Linux).

Современная БСП умеет работать с файлами разметки .docx (Office Open XML) как с обычными ZIP-архивами. Общий модуль УправлениеПечатью предоставляет готовые инструменты для серверной сборки файлов без участия MS Word.

Основные этапы работы с БСП без COM-объектов:

Используя этот подход, вы навсегда застрахуете свою систему от зависших процессов WINWORD.EXE в диспетчере задач сервера и обеспечите высокую скорость формирования документов.

← На главную