При выгрузке отчетов или обработке табличных документов через фоновые задания на сервере 1С разработчики нередко сталкиваются с ситуацией, когда инициализация COM-объекта завершается аварийно. В журнале регистрации появляется сообщение:
«Ошибка при вызове конструктора (COMОбъект) по причине: -2147467262(0x80004002): Интерфейс не поддерживается»
Характерная особенность этой проблемы заключается в том, что код успешно отрабатывает первые несколько итераций (например, 10–15 файлов), а затем аварийно завершает работу. Разберем детально, почему возникает данное исключение и как правильно перестроить логику выгрузки.
Проанализируем типовую ошибочную схему: внутри цикла по данным для каждого формируемого файла создается отдельный экземпляр приложения через Новый COMОбъект("Excel.Application"), а закрытие приложений откладывается на конец всей процедуры.
Посмотрим на пример фрагмента кода, приводящего к переполнению пула COM-соединений:
Для Каждого СтрокаТаблицы Из РезультатТаблицей Цикл
// Ошибочный подход: создание нового процесса Excel на каждой итерации
ExcelApp = Новый COMОбъект("Excel.Application");
МассивЕкселей.Добавить(ExcelApp);
Книга = ExcelApp.WorkBooks.Open(ПутьКФайлу);
Лист = Книга.WorkSheets("ЗАЧИСЛЕНИЯ");
// Обработка данных листа...
КонецЦикла;
Каждый вызов конструктора создает в операционной системе полноценный независимый процесс EXCEL.EXE в контексте неинтерактивной службы сервера 1С. При накоплении нескольких параллельно работающих экземпляров система исчерпывает десктопную кучу (Desktop Heap) нулевой сессии (Session 0) и системные ресурсы DCOM. В результате очередной запрос интерфейса через COM завершается ошибкой 0x80004002.
Оптимизируем логику обработки. Вместо схемы «один файл — один процесс Excel» перейдем к схеме «один процесс Excel — последовательное открытие и закрытие книг».
Разберем правильный алгоритм по шагам:
Excel.Application перед началом цикла обработки данных.Close().Quit() для самого приложения Excel и обнуляем переменную.Посмотрим на исправленный пример кода:
// Создаем один COM-объект на всю процедуру выгрузки
ExcelApp = Новый COMОбъект("Excel.Application");
ExcelApp.Visible = Ложь;
ExcelApp.DisplayAlerts = Ложь;
Попытка
Для Каждого СтрокаТаблицы Из РезультатТаблицей Цикл
Если СтрокаТаблицы.Проект = Неопределено ИЛИ СтрокаТаблицы.ЦФО = Неопределено Тогда
Продолжить;
КонецЕсли;
ПутьКФайлу_с_ЦФО = ПолучитьПолноеИмяФайла(СтруктураПараметров, СтрокаТаблицы.Проект, СтрокаТаблицы.ЦФО, Истина);
КопироватьФайл(ИмяФайлШаблона, ПутьКФайлу_с_ЦФО + ".xls");
// Открываем книгу в рамках единого процесса
Книга = ExcelApp.WorkBooks.Open(ПутьКФайлу_с_ЦФО + ".xls");
Лист = Книга.WorkSheets("ЗАЧИСЛЕНИЯ");
// Выполняем модификацию структуры и заполнение
ВсегоСтрок = Лист.Cells(1, 1).SpecialCells(11).Row;
Для к = 0 По ВсегоСтрок - 7 Цикл
ТекСтр = ВсегоСтрок - к;
СтрокаОтчета = Лист.Range(Строка(ТекСтр) + ":" + Строка(ТекСтр));
СтрокаОтчета.EntireRow.Delete();
КонецЦикла;
// Сохраняем и обязательно закрываем книгу
Книга.Save();
Книга.Close();
// Освобождаем ссылки на дочерние объекты
Лист = Неопределено;
Книга = Неопределено;
КонецЦикла;
Исключение
// В случае ошибки гарантированно освобождаем процесс Excel
ExcelApp.Quit();
ExcelApp = Неопределено;
ВызватьИсключение;
КонецПопытки;
// Завершаем работу Excel после успешной обработки всех файлов
ExcelApp.Quit();
ExcelApp = Неопределено;
Если ошибка возникает даже при небольшом количестве обращений к COM, выясним причину на уровне операционной системы. Фоновые задания 1С выполняются в неинтерактивной службе (процессы ragent.exe и rphost.exe). Microsoft Excel официально не предназначен для серверного использования и требует определенного окружения.
Для устранения системных сбоев выполним следующие настройки на сервере:
C:\Windows\System32\config\systemprofile\Desktop и C:\Windows\SysWOW64\config\systemprofile\Desktop. Если они отсутствуют, создадим их вручную и предоставим полные права учетной записи, от имени которой запущена служба сервера 1С.dcomcnfg (Службы компонентов). Перейдем в ветку «Компьютеры -> Мой компьютер -> Настройка DCOM -> Microsoft Excel Application». В свойствах на вкладке «Удостоверение» (Identity) укажем конкретную учетную запись с правами администратора вместо системного пользователя.HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\SubSystems в параметре Windows параметр SharedSection содержит размеры кучи. Увеличение третьего значения (размер для неинтерактивных сессий) предотвращает сбои распределения дескрипторов при нагрузке.Работа через COM-соединение является медленной и потенциально нестабильной для серверных регламентных заданий. Рассмотрим более надежные платформенные механизмы 1С:
ТабличныйДокумент:ТабличныйДокумент.Записать(ПутьКФайлу, ТипФайлаТабличногоДокумента.XLSX);. Этот способ работает без установленного Microsoft Office, выполняется на порядок быстрее и полностью изолирован от системных ограничений COM.Microsoft.ACE.OLEDB, выполняя стандартные SQL-запросы к таблицам без запуска графического ядра EXCEL.EXE.