Как исправить ошибку «Недопустимая строка с указанием класса» при создании COM-объекта Excel на сервере 1С?

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

При разработке регламентных заданий или переносе выполнения кода на сторону сервера разработчики часто сталкиваются со следующей проблемой: код, который идеально работал на клиенте, на сервере завершается аварийно. Типичный пример — инициализация Microsoft Excel для программного формирования отчетов или загрузки прайс-листов.

При вызове конструктора Новый COMОбъект("Excel.Application") в серверном контексте система возвращает критическую ошибку:

«Ошибка при вызове конструктора (COMОбъект): Недопустимая строка с указанием класса» (код ошибки 0x800401F3).

Давайте подробно разберем, почему возникает эта ошибка, почему стандартные попытки её решения (например, регистрация библиотеки comcntr.dll) не приносят результата, и как пошагово настроить сервер операционной системы для стабильной работы с COM-объектами.

Анализ неверных действий: почему regsvr32 comcntr.dll не помогает

Очень часто системные администраторы и разработчики пытаются решить эту проблему регистрацией библиотеки 1С через утилиту командной строки regsvr32. Они регистрируют файл comcntr.dll, расположенный в каталоге установленной платформы 1С. Проанализируем, почему это действие бесполезно в данном случае.

Компонент comcntr.dll отвечает исключительно за работу внешнего COM-соединителя самой платформы 1С:Предприятие (он инициализирует объекты вида V83.COMConnector или V82.COMConnector). Эта библиотека позволяет подключаться к базам данных 1С из сторонних приложений или связывать несколько информационных баз 1С между собой. К офисному пакету Microsoft Excel и его программному интерфейсу Excel.Application данная библиотека не имеет никакого отношения. Ошибка указывает на то, что серверная операционная система не может найти или запустить именно COM-класс MS Excel, поэтому регистрировать библиотеки 1С в данном контексте бессмысленно.

Выясняем истинную причину: конфликт разрядностей x64 и x32

Главная причина возникновения ошибки кроется в разнице архитектур серверной платформы 1С и установленного пакета Microsoft Office. Рассмотрим этот механизм подробнее:

  1. Сервер приложений 1С:Предприятие в абсолютном большинстве современных систем разворачивается как 64-битное приложение. Его рабочие процессы (файл rphost.exe) функционируют в 64-разрядном адресном пространстве.
  2. Пакет Microsoft Office на серверах очень часто устанавливается в 32-битной (x86) версии из соображений совместимости со сторонними legacy-системами.
  3. Операционная система Windows строго изолирует адресные пространства. 64-битный рабочий процесс сервера 1С не имеет прямой технической возможности обратиться к 32-битному COM-серверу Excel напрямую через стандартный вызов. Операционная система просто «не видит» нужный класс в 64-битной ветке реестра и выдает ошибку о недопустимой строке класса.

Для решения этой проблемы нам потребуется настроить Windows так, чтобы она могла транслировать вызовы между процессами разной разрядности с помощью системного механизма DCOM (Distributed Component Object Model).

Шаг 1: Настройка DCOM для 32-битного Excel на 64-битной Windows

Если на вашем сервере установлен 32-разрядный пакет Microsoft Office, стандартная консоль настройки службы компонентов DCOM его не отобразит. Чтобы получить доступ к управлению компонентом, выполним следующие шаги:

  1. Запустите специальную 32-битную версию консоли управления компонентами. Для этого нажмите сочетание клавиш Win + R на сервере и введите команду:

    mmc comexp.msc /32

  2. В открывшемся дереве консоли перейдите по пути: Службы компонентов -> Компьютеры -> Мой компьютер -> Настройка DCOM.
  3. Найдите в списке элемент с именем Microsoft Excel Application (или Microsoft Excel Document).

Если этого элемента в списке нет, операционной системе требуется явно указать связь исполняемого файла Excel с его уникальным идентификатором AppID в системном реестре. Разберем, как это сделать:

  1. Запустите редактор реестра через команду regedit (от имени Администратора).
  2. Перейдите в ветку реестра: HKEY_CLASSES_ROOT\AppID.
  3. Найдите подраздел с именем EXCEL.EXE. Если он отсутствует, создайте новый раздел с именем EXCEL.EXE.
  4. Внутри этого раздела создайте строковый параметр (тип REG_SZ) с именем AppID.
  5. В качестве значения этого параметра укажите стандартный GUID для Excel:

    {00020812-0000-0000-C000-000000000046}

  6. После выполнения этих манипуляций закройте редактор реестра и перезапустите консоль mmc comexp.msc /32. Проверьте список — компонент Microsoft Excel теперь должен гарантированно отображаться.

Шаг 2: Настройка прав доступа для пользователя службы 1С

По умолчанию служба сервера 1С:Предприятие функционирует в контексте безопасности специального локального пользователя (чаще всего это USR1CV8 или системная учетная запись NetworkService). Эти учетные записи сильно ограничены в правах и не могут по умолчанию запускать интерактивные оконные приложения, к которым относится Excel.

Давайте настроим необходимые права в свойствах DCOM компонента Excel:

  1. Кликните правой кнопкой мыши по элементу Microsoft Excel Application в списке настройки DCOM и выберите Свойства.
  2. Перейдите на вкладку Безопасность (Security).
  3. В группе Разрешения на запуск и активацию (Launch and Activation Permissions) выберите вариант Настроить и нажмите кнопку Изменить.
  4. Добавьте в список пользователя, под которым запускается служба вашего сервера 1С (например, USR1CV8).
  5. Установите для этого пользователя флажки разрешений:
    • Локальный запуск (Local Launch)
    • Локальная активация (Local Activation)
    Нажмите кнопку ОК для сохранения настроек.
  6. В группе Разрешения на доступ (Access Permissions) также выберите вариант Настроить, нажмите Изменить, добавьте пользователя сервера 1С и предоставьте ему флажок разрешения Локальный доступ (Local Access).
  7. Перейдите на вкладку Удостоверение (Identity). По умолчанию там может быть активен пункт «Текущий пользователь» или «Запускающий пользователь». На серверных системах это часто приводит к ошибкам, если в системе никто интерактивно не авторизован. Надежнее всего выбрать пункт Указанный пользователь (This User) и прописать учетные данные локального администратора сервера или специально созданной учетной записи с административными правами.

Шаг 3: Создание системных папок Desktop для профиля пользователя

Это неочевидная, но критически важная деталь. При инициализации через COM-соединение Microsoft Excel обращается к механизмам Windows, которые требуют наличия физической папки рабочего стола в профиле пользователя, от имени которого работает процесс. Так как служба 1С работает под системной учетной записью, этой папки в ее профиле физически не существует. Excel пытается создать временные файлы в несуществующей директории и аварийно завершает работу.

Решим эту проблему созданием необходимых каталогов вручную:

  1. Если на сервере установлена 64-битная операционная система Windows, перейдите в проводнике по следующему пути:

    C:\Windows\SysWOW64\config\systemprofile\

    Создайте в этой папке новую директорию с именем Desktop. Полный путь должен выглядеть так:

    C:\Windows\SysWOW64\config\systemprofile\Desktop

  2. Дополнительно перейдите по пути для 32-битных профилей:

    C:\Windows\System32\config\systemprofile\

    И создайте аналогичную папку там:

    C:\Windows\System32\config\systemprofile\Desktop

  3. Кликните правой кнопкой мыши по каждой из созданных папок Desktop, откройте их Свойства -> вкладку Безопасность. Нажмите кнопку Изменить, добавьте пользователя службы сервера 1С (например, USR1CV8) и предоставьте ему полные права на эту папку (как минимум права на чтение, запись и изменение содержимого).

Иногда Excel дополнительно требует папку системного кэша. Если ошибки продолжаются, создайте также папку:

C:\Windows\System32\config\systemprofile\AppData\Local\Microsoft\Windows\INetCache

И аналогично выдайте на неё права пользователю сервера 1С.

Шаг 4: Безопасный вызов COM-объекта в коде 1С

После проведения всех настроек на стороне операционной системы Windows, обязательно доработаем программный код в 1С. Любой вызов COM-объекта на сервере должен сопровождаться безопасным перехватом исключений, чтобы не приводить к падению фоновых заданий:


Попытка
    Excel = Новый COMОбъект("Excel.Application");
    // Отключаем интерактивные предупреждения самого Excel
    Excel.DisplayAlerts = Ложь;
    Excel.Visible = Ложь;
Исключение
    Инфо = ИнформацияОбОшибке();
    ТекстОшибки = "Не удалось инициализировать Microsoft Excel на сервере 1С! Подробности: " + КраткоеПредставлениеОшибки(Инфо);
    ЗаписьЖурналаРегистрации("УправлениеExcel.ОшибкаИнициализации",
        УровеньЖурналаРегистрации.Ошибка,,,
        ТекстОшибки);
    ВызватьИсключение ТекстОшибки;
КонецПопытки;

Альтернативные подходы: почему использовать Excel на сервере — плохая практика

Хотя мы подробно разобрали, как настроить сервер для работы с COM-объектом Excel, сама корпорация Microsoft официально заявляет, что пакет MS Office не предназначен для использования на стороне сервера в многопоточном режиме. Это может повлечь за собой серьезные системные проблемы:

Рассмотрим две современные альтернативы, которые позволяют полностью отказаться от использования COM-объектов на сервере.

Альтернатива 1: Использование встроенных средств платформы 1С

Начиная с версии платформы 1С:Предприятие 8.3, разработчикам доступны мощные встроенные инструменты работы с файлами табличных документов. Платформа умеет читать и записывать файлы формата XLSX (Excel) напрямую, без использования установленного в системе MS Office.

Посмотрим на пример записи данных в файл XLSX штатными средствами платформы:


// Создаем или получаем табличный документ с данными
ТабДок = Новый ТабличныйДокумент;

// Заполняем табличный документ макетом или программным выводом...
// Например, выведем простой текст
Область = ТабДок.ПолучитьОбласть("R1C1");
Область.ТекущийРисунок.Картинка = Новый Картинка; // Пример заполнения
ТабДок.Область("R1C1").Текст = "Выгрузка данных без Excel COM";

Попытка
    // Записываем файл напрямую в формат XLSX на сервере
    ТабДок.Записать(ПутьКФайлу, ТипФайлаТабличногоДокумента.XLSX);
Исключение
    ЗаписьЖурналаРегистрации("ЭкспортДанных",
        УровеньЖурналаРегистрации.Ошибка,,,
        "Ошибка записи XLSX: " + ОписаниеОшибки());
КонецПопытки;

Для чтения файлов XLSX на сервере также не требуется вызывать Excel. Достаточно использовать метод Прочитать объекта ТабличныйДокумент:


ТабДок = Новый ТабличныйДокумент;
Попытка
    ТабДок.Прочитать(ПутьКФайлу, СпособЧтенияЗначенийТабличногоДокумента.Значение);
    // Теперь мы можем обходить строки и колонки табличного документа в цикле
    Для Строка = 1 По ТабДок.ВысотаТаблицы Цикл
        ЗначениеЯчейки = ТабДок.Область(Строка, 1).Текст;
        // Обрабатываем полученные данные
    КонецЦикла;
Исключение
    ЗаписьЖурналаРегистрации("ИмпортДанных",
        УровеньЖурналаРегистрации.Ошибка,,,
        "Ошибка чтения XLSX: " + ОписаниеОшибки());
КонецПопытки;

Этот способ полностью решает проблему совместимости разрядностей, прав доступа в операционной системе и работает в разы быстрее, так как весь процесс происходит непосредственно внутри рабочего процесса 1С.

Альтернатива 2: Использование технологии ADO для быстрого чтения данных

Если вам требуется быстро прочитать огромный объем данных из существующего файла 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 на сервере. Чтение данных происходит на низком уровне через системные провайдеры базы данных, что минимизирует нагрузку на оперативную память сервера.

← На главную