Как исправить ошибку «Невозможно получить свойство Add класса Workbooks» при работе с Excel из 1С

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

При автоматизации работы с Microsoft Office из среды 1С:Предприятие разработчики часто сталкиваются с непредвиденными ошибками на этапе создания новых файлов. Одной из наиболее коварных является ошибка: «Произошла исключительная ситуация (Microsoft Excel): Невозможно получить свойство Add класса Workbooks». Эта проблема парализует выгрузку отчетов, отправку заказов поставщикам и другие критически важные бизнес-процессы.

В этой статье мы подробно разберем по шагам, почему возникает эта ошибка, проанализируем исходный код, выявим скрытые инфраструктурные причины и рассмотрим несколько способов решения — от правильной настройки операционной системы до полного отказа от ненадежной технологии COM в пользу нативных механизмов платформы 1С.

Анализ проблемного кода и симптомов

Рассмотрим типичный фрагмент кода, в котором происходит сбой. Разработчик пытается подключиться к Excel, открыть существующий файл во временном каталоге, а если его нет — создать новый пустой документ с помощью метода Add():


НаименованиеФайла = "Заказ " + СокрЛП(ПоставщикДляОтбора.Наименование);
ИмяФайла = КаталогВременныхФайлов() + НаименованиеФайла + ".xls";
ФайлДанных = ИмяФайла;

// Подключаемся к MS Excel
Попытка
    Excel = Новый COMОбъект("Excel.Application");
Исключение
    Сообщить(ОписаниеОшибки());
КонецПопытки;

Попытка                          
    Книга = Excel.Workbooks.Open(ФайлДанных);
Исключение
    // Если файл не найден, создаем новую книгу
    Книга = Excel.Workbooks.Add();
    Книга.SaveAs(ФайлДанных);
КонецПопытки;

В этой схеме заложена логическая ловушка. Если файла во временном каталоге еще нет (что абсолютно естественно при первом запуске), метод Open() гарантированно вызывает исключение. Управление передается в блок Исключение, где вызывается Excel.Workbooks.Add(). И именно здесь программа аварийно завершает работу.

При этом сам COM-объект Excel.Application успешно создается, проверка на заполненность (например, сравнение с Неопределено) возвращает Истина, но при попытке вызвать любое свойство или метод объекта Workbooks происходит сбой маршалинга интерфейсов COM.


Причина №1: Конфликт разрядности (64-битная 1С и 32-битный Office)

Выясним главную причину этого поведения. В подавляющем большинстве случаев сервер 1С:Предприятия (или клиентское приложение) работает в 64-разрядном режиме, тогда как пакет Microsoft Office (включая Excel) установлен в 32-разрядной версии.

Когда 64-битный процесс 1С пытается инициализировать COM-объект 32-битного приложения, операционная система Windows запускает Excel в отдельном адресном пространстве через суррогатный процесс. На этапе создания самого объекта Excel.Application ошибки не возникает. Однако при попытке передать сложные типы данных или обратиться к дочерним коллекциям (таким как Workbooks) через границу разрядности (32 <-> 64 бит), механизмы COM/OLE Windows не справляются с трансляцией вызовов (маршалингом). Это приводит к потере связи с объектом и генерации ошибки.

Решение А: Настройка DCOM для работы 32-битного Excel на 64-битной ОС

Если у вас нет возможности переустановить Microsoft Office на 64-разрядную версию, необходимо вручную настроить службу DCOM в Windows, чтобы предоставить серверу 1С корректный доступ к компонентам Excel. Выполним следующие шаги:

  1. Запустите редактор реестра (regedit) и перейдите в ветку HKEY_CLASSES_ROOT\AppID. Проверьте, существует ли раздел EXCEL.EXE. Если он отсутствует, создайте его. Внутри раздела добавьте строковый параметр с именем AppID и значением {00020812-0000-0000-C000-000000000046} (это глобальный идентификатор приложения Microsoft Excel).
  2. Поскольку нам нужно настроить 32-компонент в 64-битной операционной системе, стандартная консоль настройки DCOM не подойдет. Откройте специальную 32-разрядную версию консоли. Для этого нажмите Win + R, введите команду:

    mmc comexp.msc /32

    и нажмите Enter.
  3. В открывшемся окне перейдите по пути: Службы компонентов -> Компьютеры -> Мой компьютер -> Настройка DCOM.
  4. Найдите в списке компонент Microsoft Excel Application (или «Приложение Microsoft Excel»), нажмите на него правой кнопкой мыши и выберите «Свойства».
  5. На вкладке Безопасность в разделах «Права на запуск и активацию» и «Права доступа» выберите вариант «Настроить» и добавьте пользователя, под которым запущена служба сервера 1С (обычно это USR1CV8 или SYSTEM), предоставив ему полные права.
  6. На вкладке Удостоверение установите переключатель в положение «Интерактивный пользователь» или укажите учетную запись локального администратора сервера, под которой гарантированно создан и настроен профиль Windows.

Причина №2: Отсутствие папки Desktop для системного профиля

Проанализируем еще одну скрытую проблему. Когда код выполняется в фоновом задании на стороне сервера 1С, служба сервера работает от имени системной учетной записи. Excel при создании новой книги (метод Add()) или при ее сохранении обращается к каталогу «Рабочий стол» (Desktop) текущего пользователя.

У системных учетных записей (таких как SYSTEM, NetworkService или локальных сервисных пользователей без загрузки профиля) папка «Рабочий стол» в структуре каталогов Windows по умолчанию отсутствует. Из-за этого Excel не может инициализировать буферные файлы и завершает вызов Add() ошибкой.

Решение Б: Создание папок Desktop вручную

Рассмотрим процедуру создания необходимых директорий. Вам нужно зайти на сервер под учетной записью администратора и вручную создать пустые папки по следующим путям:

После создания папок обязательно нажмите на каждую из них правой кнопкой мыши, перейдите в «Свойства» -> «Безопасность» и предоставьте пользователю службы 1С (например, USR1CV8) полные права на чтение, запись и изменение этих папок.


Причина №3: Некорректная обработка отсутствия файла в 1С

Вернемся к исходному коду автора. Попытка открыть заведомо отсутствующий файл и последующий перехват ошибки через Попытка...Исключение — это крайне неэффективный подход, который перегружает систему лишними вызовами внешних COM-библиотек. Посмотрим, как можно улучшить этот алгоритм средствами встроенного языка 1С:


// Проверяем существование файла средствами самой платформы 1С
ФайлНаДиске = Новый Файл(ФайлДанных);

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

Если ФайлНаДиске.Существует() Тогда
    // Если файл есть, просто открываем его
    Книга = Excel.Workbooks.Open(ФайлДанных);
Иначе
    // Если файла нет, сначала создаем чистую книгу и сохраняем её
    Книга = Excel.Workbooks.Add();
    Книга.SaveAs(ФайлДанных);
КонецЕсли;

Такой подход избавляет от необходимости генерировать системные исключения Windows при стандартном сценарии работы системы и делает код более стабильным и читаемым.


Лучшая альтернатива: Отказ от использования COM-объекта Excel

Использование Microsoft Excel через COM-соединение на стороне сервера официально не рекомендуется самой корпорацией Microsoft. Десктопные офисные приложения не рассчитаны на работу в многопоточных фоновых процессах: они утекают по памяти, плодят зависшие процессы EXCEL.EXE в диспетчере задач и требуют интерактивного взаимодействия с пользователем при возникновении любых микроошибок.

Платформа 1С:Предприятие обладает мощным набором встроенных инструментов, которые позволяют формировать полноценные файлы Excel формата .xlsx или .xls без установленного MS Office на сервере и вне зависимости от разрядности операционной системы.

Решение В: Использование Табличного Документа 1С

Рассмотрим пример создания файла для отправки контрагенту силами платформы 1С. Мы можем сформировать обычный табличный документ, заполнить его данными и сохранить в нужном формате одной строчкой кода:


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

// Заполняем документ (выводим макеты, области, параметры)
// Например, выведем шапку заказа
Макет = ПолучитьМакет("МакетЗаказа");
ОбластьШапка = Макет.ПолучитьОбласть("Шапка");
ОбластьШапка.Параметры.Поставщик = ПоставщикДляОтбора;
ТабДок.Вывести(ОбластьШапка);

// Сохраняем готовый документ в формате XLSX напрямую на диск
ИмяФайла = КаталогВременныхФайлов() + "Заказ_" + СокрЛП(ПоставщикДляОтбора.Код) + ".xlsx";
ТабДок.Записать(ИмяФайла, ТипФайлаТабличногоДокумента.XLSX);

Преимущества этого метода неоспоримы:

Резюме

Если вам обязательно нужно использовать COM-объект Excel (например, при заполнении сложного готового шаблона с макросами), настройте 32-битную консоль DCOM и создайте системные папки Desktop в каталоге профиля. Если же перед вами стоит стандартная задача выгрузки данных, воспользуйтесь нативным методом ТабличныйДокумент.Записать() — это сэкономит ваше время и обеспечит бесперебойную работу информационной базы.

← На главную