Разработка серверных механизмов в среде 1С часто сопряжена с необходимостью автоматического формирования, выгрузки или анализа отчетов в формате Microsoft Excel. Когда подобный код выполняется на стороне клиента, проблем обычно не возникает. Однако при переносе выполнения на сервер (например, в регламентное задание или серверный общий модуль) разработчики регулярно сталкиваются с классической ошибкой: «Ошибка при вызове конструктора (COMОбъект): -2147...». При этом на клиентских машинах тот же самый код работает без нареканий.
В этой статье мы подробно разберем, почему возникает данная проблема, проанализируем архитектурные особенности взаимодействия сервера 1С с COM-объектами Windows, найдем недостающие системные папки Desktop, настроим службы компонентов DCOM и рассмотрим современные безопасные альтернативы, которые позволяют полностью отказаться от использования нестабильного механизма COM-соединения на сервере.
Для начала проанализируем ситуацию, описанную на форуме. У нас есть трехзвенная архитектура: сервер СУБД (SQL), сервер приложений 1С и клиентские рабочие станции. Код, вызывающий Excel, выполняется в контексте регламентного задания на сервере 1С. Программа выдает ошибку инициализации COM-объекта.
Первое, что необходимо понять: где физически должен быть установлен Microsoft Excel?
Поскольку вызов конструктора Новый COMОбъект("Excel.Application") происходит в серверном модуле, операционная система сервера приложений 1С пытается инициализировать COM-сервер локально. Это значит, что пакет Microsoft Office (в частности, Excel) должен быть физически установлен и лицензирован именно на том сервере, где запущена служба 1C:Enterprise 8 Server Agent (агент сервера 1С).
Установка Excel на сервере баз данных (SQL) или на пользовательских компьютерах никак не поможет серверу приложений 1С создать объект. Как верно заметил автор темы в итоговом сообщении, одной из самых банальных причин ошибки является физическое отсутствие Excel на сервере 1С. Однако даже после установки программы вы гарантированно столкнетесь со следующей проблемой — ограничением прав системного профиля Windows.
Когда служба сервера 1С запускается от имени системной учетной записи (например, NETWORK SERVICE, LocalSystem) или под специальным пользователем USR1CV8, операционная система Windows создает для этого сеанса изолированное окружение. При инициализации COM-объекта Microsoft Excel по умолчанию пытается проверить наличие рабочей папки рабочего стола (Desktop) в профиле пользователя, от имени которого запущен процесс.
Если служба работает под системным профилем, этих папок физически не существует в структуре каталогов Windows. Процесс excel.exe аварийно завершается, возвращая ошибку инициализации конструктора.
Для решения этой проблемы нам необходимо вручную создать пустые папки Desktop по специфическим системным путям. Выбор пути зависит от разрядности вашей операционной системы и разрядности установленного Excel.
Рассмотрим эти пути подробнее:
C:\Windows\SysWOW64\config\systemprofile\DesktopC:\Windows\System32\config\systemprofile\DesktopВажное примечание: Мы рекомендуем создать обе эти папки одновременно, независимо от текущей разрядности вашей платформы 1С. Это гарантирует, что при обновлении платформы или изменении разрядности службы сервера механизм импорта/экспорта продолжит работать стабильно. После создания папок обязательно убедитесь, что у пользователя, под которым запущена служба сервера 1С (например, USR1CV8), есть полные права доступа (чтение и запись) к этим созданным директориям Desktop.
Даже при наличии папок Desktop операционная система может заблокировать запуск локального COM-сервера Excel из-за недостаточных прав безопасности службы DCOM. Давайте разберем по шагам, как предоставить необходимые права учетной записи сервера 1С:
Win + R на сервере 1С, введите команду dcomcnfg и нажмите Enter. Откроется панель «Службы компонентов».USR1CV8), и установите для него галочки разрешений: Локальный запуск и Локальная активация.После внесения этих изменений обязательно перезапустите службу сервера 1С, чтобы новые параметры безопасности вступили в силу.
Иногда системные администраторы сталкиваются с ситуацией, когда в списке утилиты dcomcnfg отсутствует компонент Microsoft Excel Application. Это происходит из-за конфликта разрядностей: например, операционная система Windows и сервер приложений 1С имеют разрядность 64-бит, а пакет Microsoft Office установлен в 32-битной версии (или наоборот).
Для того чтобы увидеть 32-битные COM-компоненты на 64-битной операционной системе, нам необходимо запустить консоль управления в специальном 32-битном режиме совместимости. Разберем, как это сделать:
Откройте командную строку или меню «Выполнить» (Win + R) и выполните следующую команду:
mmc comexp.msc /32
В открывшемся окне службы компонентов вы гарантированно увидите целевой объект Excel и сможете настроить его права по схеме, описанной в Шаге 2.
Если объект все равно не появился в списке, выполните принудительную перерегистрацию Excel в реестре Windows. Для этого запустите командную строку от имени администратора, перейдите в папку установки MS Office и выполните команду саморегистрации:
excel.exe /regserver
Мы успешно настроили права и папки, и наш код заработал. Однако важно понимать, что использование COMОбъект для работы с офисными документами на стороне сервера несет в себе колоссальные архитектурные риски:
excel.exe «застревает» в оперативной памяти сервера навсегда. Со временем количество таких «зомби-процессов» растет, они монополизируют ресурсы процессора и оперативную память, что приводит к полной остановке сервера приложений.Чтобы избежать нестабильной работы сервера 1С, настоятельно рекомендуется переписать алгоритмы чтения и записи файлов Excel на современные механизмы, встроенные в саму платформу 1С:Предприятие 8.3.
Платформа 1С умеет читать файлы табличных документов напрямую, без привлечения сторонних приложений и COM-объектов. Проанализируем пример кода для загрузки данных из файла Excel:
&НаСервере
Процедура ПрочитатьФайлExcelНаСервере(ПутьКФайлу)
// Создаем объект ТабличныйДокумент для загрузки данных
ТабДок = Новый ТабличныйДокумент;
Попытка
// Читаем файл напрямую, указывая способ чтения Excel
ТабДок.Прочитать(ПутьКФайлу, СпособЧтенияТабличныхДокументов.Excel);
Исключение
ЗаписьЖурналаРегистрации("ЗагрузкаДанных", УровеньЖурналаРегистрации.Ошибка, , ,
"Ошибка при чтении файла: " + ОписаниеОшибки());
ВызватьИсключение "Не удалось прочитать файл Excel. Возможно, он поврежден.";
КонецПопытки;
// Обходим строки и колонки загруженного документа
КоличествоСтрок = ТабДок.ВысотаТаблицы;
КоличествоКолонок = ТабДок.ШиринаТаблицы;
Для НомерСтроки = 1 По КоличествоСтрок Цикл
// Читаем значение конкретной ячейки
Артикул = ТабДок.Область(НомерСтроки, 1).Текст;
Наименование = ТабДок.Область(НомерСтроки, 2).Текст;
Цена = ТабДок.Область(НомерСтроки, 3).Значение; // если там число
// Обрабатываем полученные данные...
КонецЦикла;
КонецПроцедуры
Этот метод работает в десятки раз быстрее, абсолютно стабилен и не требует наличия установленного Excel на сервере приложений.
Если вам необходимо сформировать отчет или выгрузку в формате Excel, используйте стандартный метод сохранения табличного документа платформы 1С:
&НаСервере
Процедура ВыгрузитьДанныеВExcelНаСервере(ПутьКФайлуСохранения)
ТабДок = Новый ТабличныйДокумент;
// Заполняем табличный документ данными из запроса или макета
// Например, добавим простую шапку
ОбластьШапки = ТабДок.Область("R1C1:R1C2");
ТабДок.Область(1, 1).Текст = "Код товара";
ТабДок.Область(1, 2).Текст = "Остаток на складе";
// Сохраняем табличный документ в современном формате XLSX
Попытка
ТабДок.Записать(ПутьКФайлуСохранения, ТипФайлаТабличногоДокумента.XLSX);
Исключение
ЗаписьЖурналаРегистрации("ВыгрузкаДанных", УровеньЖурналаРегистрации.Ошибка, , ,
"Ошибка при сохранении файла: " + ОписаниеОшибки());
ВызватьИсключение "Не удалось записать файл Excel.";
КонецПопытки;
КонецПроцедуры
Используя встроенные методы платформы 1С Прочитать() и Записать(), вы полностью обезопасите свой сервер от зависаний процессов excel.exe, избавитесь от сложных настроек прав DCOM и обеспечите высокую производительность системы.