Одной из классических и в то же время трудоемких задач в 1С является автоматизация документооборота с использованием внешних приложений, таких как Microsoft Word. Часто возникает ситуация: код прекрасно работает на клиентской части (у пользователя на компьютере), но при попытке перенести его на сервер или запустить через регламентное задание он «зависает» или выдает ошибки. В этой статье мы подробно разберем, почему так происходит, и рассмотрим несколько надежных способов решения этой задачи.
Прежде чем переходить к коду, выясним причину сбоев. Microsoft Word — это интерактивное приложение, созданное для работы в сессии пользователя. Когда 1С пытается запустить его на сервере (особенно в фоновом задании), возникают следующие препятствия:
USR1CV8), часто нет прав на инициализацию COM-объектов MS Office.Desktop в профиле системного пользователя для временных файлов, которой по умолчанию не существует в системных директориях.Проанализируем самый простой с точки зрения программирования подход, предложенный участниками форума. Если код &НаКлиенте работает безупречно, мы можем создать выделенный сеанс пользователя, который будет заниматься только формированием документов.
Разберем алгоритм настройки:
ПриНачалеРаботыСистемы прописываем вызов вашей процедуры формирования документов.Этот метод хорош тем, что Word запускается в полноценной интерактивной сессии, и вы избегаете всех «серверных» ошибок доступа к COM-объектам.
Если нам принципиально запускать код именно &НаСервере, необходимо подготовить среду Windows. Рассмотрим пошагово, что нужно сделать.
Шаг 1. Создание папок Desktop.
Для корректной инициализации Word на 64-битных серверах необходимо вручную создать следующие директории:
C:\Windows\SysWOW64\config\systemprofile\DesktopC:\Windows\System32\config\systemprofile\DesktopПосле создания папок необходимо дать пользователю, от имени которого работает сервер 1С, полные права на них.
Шаг 2. Настройка DCOM.
Проанализируем ситуацию, когда прав все равно недостаточно. Нам потребуется утилита dcomcnfg:
Посмотрим на пример кода, который выполняет замену меток в тексте и экспорт в PDF. Важно правильно использовать параметры метода SaveAs. Для сохранения в PDF используется значение 17 (wdFormatPDF).
// Пример серверной процедуры заполнения шаблона
Процедура СформироватьСертификатНаСервере(ДанныеСотрудника, ПутьКШаблону, ПутьКРезультату)
Попытка
Word = Новый COMОбъект("Word.Application");
Word.Visible = Ложь; // На сервере всегда Ложь
Word.DisplayAlerts = 0; // Отключаем уведомления
Исключение
ЗаписьЖурналаРегистрации("Ошибка.Word", УровеньЖурналаРегистрации.Ошибка, , , ОписаниеОшибки());
Возврат;
КонецПопытки;
Попытка
Документ = Word.Documents.Open(ПутьКШаблону);
// Поиск и замена меток (например, {ФИО})
Замена = Word.Selection.Find;
Замена.Execute("{ФИО}",,,,,,,,, ДанныеСотрудника.ФИО, 2);
// Сохраняем как PDF (параметр 17)
Документ.SaveAs(ПутьКРезультату, 17);
Документ.Close(0); // Закрываем без сохранения изменений в шаблоне
Исключение
Сообщить("Ошибка обработки документа: " + ОписаниеОшибки());
КонецПопытки;
Word.Quit(); // Обязательно завершаем процесс
КонецПроцедуры
Важный момент: Всегда используйте блоки Попытка...Исключение и гарантированно закрывайте процесс Word.Quit(). Если этого не делать, при любой ошибке на сервере будет оставаться «зависший» процесс WINWORD.EXE, что со временем приведет к нехватке памяти.
Выясним причину, по которой многие опытные разработчики стараются избегать использования COM на сервере. Это нестабильность. Самым надежным способом является использование встроенных средств 1С.
Рассмотрим алгоритм:
ТабДок = Новый ТабличныйДокумент;
Макет = ПолучитьМакет("МакетСертификата");
Область = Макет.ПолучитьОбласть("Тело");
Область.Параметры.ФИО = "Иванов Иван Иванович";
ТабДок.Вывести(Область);
// Прямое сохранение в PDF средствами 1С
ТабДок.Записать("C:\Sertificates\Sert.pdf", ТипФайлаТабличногоДокумента.PDF);
Преимущества этого метода:
Если макет в 1С создать невозможно (например, очень сложная верстка docx), можно использовать LibreOffice. Он отлично работает через командную строку без графического интерфейса.
Проанализируем команду вызова:
КомандаЗапуска = """C:\Program Files\LibreOffice\program\soffice.exe"" --headless --convert-to pdf ""C:\Docs\file.docx"" --outdir ""C:\Docs\""";
ЗапуститьПриложение(КомандаЗапуска, , Истина);
Параметр --headless сообщает программе, что её нужно запустить как сервис без окна. Это гораздо стабильнее для серверных фоновых заданий, чем использование COM-объекта.
Подводя итог, можно сказать следующее: если задача разовая и простая — используйте настройку Desktop папок и DCOM. Если же вы строите надежную корпоративную систему — переводите шаблоны в Табличные документы 1С. Это избавит вас от зависимости от стороннего ПО и проблем с обновлениями Windows.