При разработке регламентных заданий или переносе выполнения кода на сторону сервера разработчики часто сталкиваются со следующей проблемой: код, который идеально работал на клиенте, на сервере завершается аварийно. Типичный пример — инициализация Microsoft Excel для программного формирования отчетов или загрузки прайс-листов.
При вызове конструктора Новый COMОбъект("Excel.Application") в серверном контексте система возвращает критическую ошибку:
«Ошибка при вызове конструктора (COMОбъект): Недопустимая строка с указанием класса» (код ошибки 0x800401F3).
Давайте подробно разберем, почему возникает эта ошибка, почему стандартные попытки её решения (например, регистрация библиотеки comcntr.dll) не приносят результата, и как пошагово настроить сервер операционной системы для стабильной работы с COM-объектами.
Очень часто системные администраторы и разработчики пытаются решить эту проблему регистрацией библиотеки 1С через утилиту командной строки regsvr32. Они регистрируют файл comcntr.dll, расположенный в каталоге установленной платформы 1С. Проанализируем, почему это действие бесполезно в данном случае.
Компонент comcntr.dll отвечает исключительно за работу внешнего COM-соединителя самой платформы 1С:Предприятие (он инициализирует объекты вида V83.COMConnector или V82.COMConnector). Эта библиотека позволяет подключаться к базам данных 1С из сторонних приложений или связывать несколько информационных баз 1С между собой. К офисному пакету Microsoft Excel и его программному интерфейсу Excel.Application данная библиотека не имеет никакого отношения. Ошибка указывает на то, что серверная операционная система не может найти или запустить именно COM-класс MS Excel, поэтому регистрировать библиотеки 1С в данном контексте бессмысленно.
Главная причина возникновения ошибки кроется в разнице архитектур серверной платформы 1С и установленного пакета Microsoft Office. Рассмотрим этот механизм подробнее:
rphost.exe) функционируют в 64-разрядном адресном пространстве.Для решения этой проблемы нам потребуется настроить Windows так, чтобы она могла транслировать вызовы между процессами разной разрядности с помощью системного механизма DCOM (Distributed Component Object Model).
Если на вашем сервере установлен 32-разрядный пакет Microsoft Office, стандартная консоль настройки службы компонентов DCOM его не отобразит. Чтобы получить доступ к управлению компонентом, выполним следующие шаги:
mmc comexp.msc /32
Если этого элемента в списке нет, операционной системе требуется явно указать связь исполняемого файла Excel с его уникальным идентификатором AppID в системном реестре. Разберем, как это сделать:
regedit (от имени Администратора).HKEY_CLASSES_ROOT\AppID.EXCEL.EXE. Если он отсутствует, создайте новый раздел с именем EXCEL.EXE.REG_SZ) с именем AppID.{00020812-0000-0000-C000-000000000046}
mmc comexp.msc /32. Проверьте список — компонент Microsoft Excel теперь должен гарантированно отображаться.По умолчанию служба сервера 1С:Предприятие функционирует в контексте безопасности специального локального пользователя (чаще всего это USR1CV8 или системная учетная запись NetworkService). Эти учетные записи сильно ограничены в правах и не могут по умолчанию запускать интерактивные оконные приложения, к которым относится Excel.
Давайте настроим необходимые права в свойствах DCOM компонента Excel:
USR1CV8).Это неочевидная, но критически важная деталь. При инициализации через COM-соединение Microsoft Excel обращается к механизмам Windows, которые требуют наличия физической папки рабочего стола в профиле пользователя, от имени которого работает процесс. Так как служба 1С работает под системной учетной записью, этой папки в ее профиле физически не существует. Excel пытается создать временные файлы в несуществующей директории и аварийно завершает работу.
Решим эту проблему созданием необходимых каталогов вручную:
C:\Windows\SysWOW64\config\systemprofile\
Desktop. Полный путь должен выглядеть так:
C:\Windows\SysWOW64\config\systemprofile\Desktop
C:\Windows\System32\config\systemprofile\
C:\Windows\System32\config\systemprofile\Desktop
Desktop, откройте их Свойства -> вкладку Безопасность. Нажмите кнопку Изменить, добавьте пользователя службы сервера 1С (например, USR1CV8) и предоставьте ему полные права на эту папку (как минимум права на чтение, запись и изменение содержимого).Иногда Excel дополнительно требует папку системного кэша. Если ошибки продолжаются, создайте также папку:
C:\Windows\System32\config\systemprofile\AppData\Local\Microsoft\Windows\INetCache
И аналогично выдайте на неё права пользователю сервера 1С.
После проведения всех настроек на стороне операционной системы Windows, обязательно доработаем программный код в 1С. Любой вызов COM-объекта на сервере должен сопровождаться безопасным перехватом исключений, чтобы не приводить к падению фоновых заданий:
Попытка
Excel = Новый COMОбъект("Excel.Application");
// Отключаем интерактивные предупреждения самого Excel
Excel.DisplayAlerts = Ложь;
Excel.Visible = Ложь;
Исключение
Инфо = ИнформацияОбОшибке();
ТекстОшибки = "Не удалось инициализировать Microsoft Excel на сервере 1С! Подробности: " + КраткоеПредставлениеОшибки(Инфо);
ЗаписьЖурналаРегистрации("УправлениеExcel.ОшибкаИнициализации",
УровеньЖурналаРегистрации.Ошибка,,,
ТекстОшибки);
ВызватьИсключение ТекстОшибки;
КонецПопытки;
Хотя мы подробно разобрали, как настроить сервер для работы с COM-объектом Excel, сама корпорация Microsoft официально заявляет, что пакет MS Office не предназначен для использования на стороне сервера в многопоточном режиме. Это может повлечь за собой серьезные системные проблемы:
excel.exe часто зависают в оперативной памяти сервера и накапливаются при аварийном завершении сессий 1С, что приводит к утечкам памяти и перегрузке процессора.Рассмотрим две современные альтернативы, которые позволяют полностью отказаться от использования COM-объектов на сервере.
Начиная с версии платформы 1С:Предприятие 8.3, разработчикам доступны мощные встроенные инструменты работы с файлами табличных документов. Платформа умеет читать и записывать файлы формата XLSX (Excel) напрямую, без использования установленного в системе MS Office.
Посмотрим на пример записи данных в файл XLSX штатными средствами платформы:
// Создаем или получаем табличный документ с данными
ТабДок = Новый ТабличныйДокумент;
// Заполняем табличный документ макетом или программным выводом...
// Например, выведем простой текст
Область = ТабДок.ПолучитьОбласть("R1C1");
Область.ТекущийРисунок.Картинка = Новый Картинка; // Пример заполнения
ТабДок.Область("R1C1").Текст = "Выгрузка данных без Excel COM";
Попытка
// Записываем файл напрямую в формат XLSX на сервере
ТабДок.Записать(ПутьКФайлу, ТипФайлаТабличногоДокумента.XLSX);
Исключение
ЗаписьЖурналаРегистрации("ЭкспортДанных",
УровеньЖурналаРегистрации.Ошибка,,,
"Ошибка записи XLSX: " + ОписаниеОшибки());
КонецПопытки;
Для чтения файлов XLSX на сервере также не требуется вызывать Excel. Достаточно использовать метод Прочитать объекта ТабличныйДокумент:
ТабДок = Новый ТабличныйДокумент;
Попытка
ТабДок.Прочитать(ПутьКФайлу, СпособЧтенияЗначенийТабличногоДокумента.Значение);
// Теперь мы можем обходить строки и колонки табличного документа в цикле
Для Строка = 1 По ТабДок.ВысотаТаблицы Цикл
ЗначениеЯчейки = ТабДок.Область(Строка, 1).Текст;
// Обрабатываем полученные данные
КонецЦикла;
Исключение
ЗаписьЖурналаРегистрации("ИмпортДанных",
УровеньЖурналаРегистрации.Ошибка,,,
"Ошибка чтения XLSX: " + ОписаниеОшибки());
КонецПопытки;
Этот способ полностью решает проблему совместимости разрядностей, прав доступа в операционной системе и работает в разы быстрее, так как весь процесс происходит непосредственно внутри рабочего процесса 1С.
Если вам требуется быстро прочитать огромный объем данных из существующего файла Excel, но вы по каким-то причинам не можете использовать стандартные методы 1С (например, если работаете на старых версиях платформы 1С 8.2), отличным решением станет использование библиотеки ActiveX Data Objects (ADO).
Этот способ позволяет подключиться к файлу Excel как к стандартной базе данных SQL и выполнить быстрый запрос на получение данных. Проанализируем пример кода:
ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + ПутьКФайлу + ";Extended Properties=""Excel 12.0 Xml;HDR=YES;IMEX=1"";";
Connection = Новый COMОбъект("ADODB.Connection");
Попытка
Connection.Open(ConnectionString);
// Создаем набор записей (Recordset)
Recordset = Новый COMОбъект("ADODB.Recordset");
// Выполняем SQL-запрос к первому листу книги Excel
Recordset.Open("SELECT * FROM [Лист1$]", Connection);
Пока НЕ Recordset.EOF Цикл
// Читаем значение первой колонки
ПерваяКолонка = Recordset.Fields.Item(0).Value;
// Переходим к следующей строке файла
Recordset.MoveNext();
КонецЦикла;
Recordset.Close();
Connection.Close();
Исключение
ЗаписьЖурналаРегистрации("ADO.ЧтениеExcel",
УровеньЖурналаРегистрации.Ошибка,,,
"Ошибка чтения данных через ADO: " + ОписаниеОшибки());
// Обязательно освобождаем COM-объекты при ошибке
Recordset = Неопределено;
Connection = Неопределено;
КонецПопытки;
Использование ADO позволяет избежать запуска тяжеловесного графического интерфейса Excel.exe на сервере. Чтение данных происходит на низком уровне через системные провайдеры базы данных, что минимизирует нагрузку на оперативную память сервера.