При разработке фоновых заданий, регламентных обработок или рассылок отчетов программисты часто сталкиваются с ситуацией, когда код работы с Microsoft Excel через COM-соединение безупречно отрабатывает на клиенте или в файловой базе, но намертво зависает при исполнении в серверном контексте. Разберем детально, почему это происходит и как правильно настроить сервер или оптимизировать код 1С.
Рассмотрим типовой сценарий: в серверном модуле формируется табличный документ, сохраняется во временный файл, после чего вызывается функция ПолучитьCOMОбъект или конструктор Новый COMОбъект("Excel.Application") для изменения параметров страницы (например, переключения ориентации на альбомную).
Посмотрим на пример такого кода:
ПолноеИмяФайла = ПолучитьИмяВременногоФайла("xls");
ТабДок.Записать(ПолноеИмяФайла, ТипФайлаТабличногоДокумента.XLS97);
Эксель = ПолучитьCOMОбъект(ПолноеИмяФайла);
Лист = Эксель.WorkSheets(1);
Лист.PageSetup.Orientation = 2; // 2 - ландшафтная ориентация
Эксель.Save();
Эксель.Close();
Эксель = Неопределено;
Выясним причину зависания этого процесса в клиент-серверном режиме:
ragent) работает в неинтерактивной нулевой сессии Windows (Session 0). При инициализации COM-объекта Excel обращается к структуре системного профиля. Если служебная папка Desktop отсутствует, процесс EXCEL.EXE уходит в бесконечное ожидание.USR1CV8), под которым стартует служба 1С, по умолчанию не имеет прав на запуск, активацию DCOM-компонентов Microsoft Excel и доступ к системным временным папкам.Разберем по шагам, как настроить серверную операционную систему для корректной работы COM-объектов MS Office под учетной записью службы 1С.
В зависимости от разрядности Windows Server и пакета Office перейдем в системные каталоги и вручную создадим недостающие папки:
Для 64-битных систем:
C:\Windows\System32\config\systemprofile\Desktop
C:\Windows\SysWOW64\config\systemprofile\Desktop
В свойствах созданных папок на вкладке «Безопасность» предоставим полные права учетной записи, от имени которой запущена служба 1С (например, USR1CV8 или NETWORK SERVICE).
Откроем консоль управления компонентами: нажмем Win + R, введем dcomcnfg.exe (для 32-битного Office на 64-битной ОС используем команду mmc comexp.msc /32) и перейдем по пути: Службы компонентов -> Компьютеры -> Мой компьютер -> Настройка DCOM.
Найдем в списке пункт Microsoft Excel Application, откроем его «Свойства» и выполним настройки:
На вкладке «Безопасность» в разделах «Разрешения на запуск и активацию» и «Разрешения на доступ» переключим переключатель в положение «Настроить», нажмем «Изменить» и добавим пользователя службы 1С, выставив разрешения на локальный запуск, локальную активацию и локальный доступ.
На вкладке «Удостоверение» (Identity) выберем запуск от имени «Текущий пользователь» или «Указанный пользователь», задав данные администратора или сервисной учетной записи.
Выполним вход на сервер под учетной записью службы 1С и запустим Excel вручную. Примем лицензионное соглашение, закроем все всплывающие окна и проверим сохранение любого тестового документа. Это предотвратит показ блокирующих диалоговых окон в фоновом режиме.
После завершения работы с документом обязательно закрываем приложение и очищаем переменные, чтобы не оставлять в диспетчере задач зависшие процессы EXCEL.EXE:
Эксель.Save();
Эксель.Close();
Эксель = Неопределено;
Проанализируем альтернативный подход: Microsoft официально не рекомендует серверную автоматизацию приложений MS Office из-за проблем с масштабируемостью и стабильностью. В платформе 1С:Предприятие 8.3 задачу сохранения альбомной ориентации можно решить встроенными средствами без вызова сторонних программ.
Старый формат ТипФайлаТабличногоДокумента.XLS97 не передает настройки страницы в файл Excel. Однако современный формат ТипФайлаТабличногоДокумента.XLSX полностью сохраняет параметры печати, заданные в табличном документе 1С.
Посмотрим на пример реализации без использования COM-соединения:
// Устанавливаем параметры страницы непосредственно в табличном документе
ТабДок.ОриентацияСтраницы = ОриентацияСтраницы.Ландшафт;
ТабДок.АвтоМасштаб = Истина;
ТабДок.ОтображатьСетку = Ложь;
// Сохраняем файл в формате XLSX встроенным методом платформы
ПолноеИмяФайла = ПолучитьИмяВременногоФайла("xlsx");
ТабДок.Записать(ПолноеИмяФайла, ТипФайлаТабличногоДокумента.XLSX);
При открытии такого XLSX-файла в Microsoft Excel альбомная ориентация страницы и масштабирование сохраняются автоматически, что полностью исключает необходимость вызова функции ПолучитьCOMОбъект на стороне сервера.
Если же отчет формируется исключительно для ознакомления и печати получателем без последующего редактирования данных, наиболее надежным решением является сохранение в формат PDF с помощью ТипФайлаТабличногоДокумента.PDF, где геометрия и ориентация листа гарантированно зафиксированы платформой 1С.