Почему чтение Excel через OLEDB работает в клиентском сеансе, но падает в фоновом задании?

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

Нередко разработчики сталкиваются с ситуацией: обработка загрузки данных из файлов Excel прекрасно открывает документ на сервере в режиме «1С:Предприятие», однако при переносе этой же логики в фоновое или регламентное задание подключение через строку OLEDB стабильно завершается ошибкой. При этом запуск через COM-объект Excel.Application в том же фоновом задании может успешно выполняться. Разберем по шагам, почему возникает эта разница, выясним фундаментальные причины и рассмотрим способы решения проблемы.

Анализ проблемы: почему в клиенте работает, а в фоне нет?

Проанализируем исходные условия. Код подключения к файлам Excel использует типичные строки инициализации провайдеров:


СтрокаСоединения = "
| Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + СокрЛП(ИмяФайла) + ";
| Extended Properties=""Excel 12.0 Xml;HDR=NO""";

СтрокаСоединения = "
|Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + СокрЛП(ИмяФайла) + ";
|Extended Properties=""Excel 8.0;IMEX=1;HDR=No;""";

Когда разработчик запускает сеанс «1С:Предприятие» непосредственно на самом сервере, код выполняется в контексте 32-разрядного клиентского приложения (процесс 1cv8.exe) и под учетной записью вошедшего интерактивного пользователя. Фоновое задание запускается на стороне сервера 1С — внутри рабочего процесса rphost.exe под служебной учетной записью службы (по умолчанию USR1CV8).

Здесь вступают в силу две ключевые причины сбоя:

  1. Несовместимость разрядности процессов (Architecture Mismatch): клиент 1С чаще всего 32-разрядный, а рабочий процесс сервера rphost.exe — 64-разрядный. Драйверы Microsoft.Jet.OLEDB.4.0 и Microsoft.ACE.OLEDB.12.0 являются внутрипроцессными серверами (InProcServer32 DLL). 64-битный процесс физически не может загрузить в свое адресное пространство 32-битную библиотеку.
  2. Специфика контекста службы Windows и права доступа: фоновое задание выполняется в изолированной служебной сессии (Session 0) без загруженного профиля пользователя и с ограниченными правами доступа к каталогам и сетевым ресурсам.

Почему Excel.Application работает, а OLEDB — нет?

Разберем, почему вызов Новый COMОбъект("Excel.Application") в фоновом задании отрабатывает штатно, в то время как подключение по OLEDB падает с ошибкой инициализации провайдера:

  1. Объект Excel.Application является внешним сервером COM (LocalServer32). Он запускается в операционной системе как отдельный процесс excel.exe. Механизм COM автоматически выполняет маршалинг и межпроцессное взаимодействие (IPC) между 64-разрядным сервером rphost.exe и 32-разрядным excel.exe.
  2. Провайдеры OLEDB (Jet 4.0 и ACE) загружаются непосредственно внутрь самого процесса rphost.exe как библиотеки DLL. Драйвер Microsoft.Jet.OLEDB.4.0 вообще не имеет 64-разрядной версии в природе, а провайдер Microsoft.ACE.OLEDB.12.0 часто установлен в системе только в 32-битной редакции (вместе с 32-битным пакетом Microsoft Office).

Решение 1. Установка 64-разрядного провайдера Microsoft Access Database Engine

Если сервер 1С работает под управлением 64-разрядной платформы, для фоновых заданий требуется наличие 64-битного провайдера Microsoft.ACE.OLEDB.12.0 (или более поздней версии 16.0). Провайдер Jet 4.0 использовать на 64-разрядном сервере нельзя ни при каких условиях.

Рассмотрим, как правильно установить 64-разрядный драйвер на сервер:

  1. Если на сервере уже установлен 32-разрядный Microsoft Office, штатный установщик AccessDatabaseEngine_X64.exe выдаст ошибку о невозможности совместной установки 32- и 64-битных компонентов.
  2. Для обхода этого ограничения запустим инсталлятор из командной строки Windows (cmd) с правами администратора в тихом режиме: AccessDatabaseEngine_X64.exe /passive или AccessDatabaseEngine_X64.exe /quiet.
  3. После завершения установки 64-битный провайдер ACE OLEDB корректно зарегистрируется в системном реестре и станет доступен для вызова из 64-битного rphost.exe в коде фоновых заданий.

Решение 2. Проверка прав доступа и окружения службы USR1CV8

Если 64-битный драйвер зарегистрирован, но фоновое задание по-прежнему выдает ошибку, проанализируем настройки прав доступа служебной учетной записи:

  1. Права на запись в каталог с файлом: движок OLEDB (как Jet, так и ACE) при обращении к файлу книги пытается создать временный lock-файл блокировки (.ldb или .laccdb) строго в том же каталоге, где расположен исходный файл Excel. Даже если в строке соединения указано открытие только для чтения, учетная запись службы USR1CV8 обязана иметь права на запись и на изменение в каталоге расположения файла.
  2. Сетевые диски и пути: служба Windows не видит подключенные буквы сетевых дисков (такие как Z:\). Путь к файлу в коде должен быть строго в формате UNC: \\server\share\file.xlsx. Если служба запущена под локальным пользователем, у нее не будет доступа к сетевым папкам на других серверах. В таком случае службу необходимо перевести на доменную учетную запись.
  3. Каталог временных файлов: убедимся, что переменные среды %TEMP% и %TMP% для учетной записи службы сервера 1С указывают на существующую папку, к которой у пользователя службы есть полный доступ.

Решение 3. Использование промежуточного COM+ приложения (dllhost.exe)

Если установить 64-разрядный драйвер на сервер невозможно или политика компании запрещает установку сторонних драйверов, настроим запуск 32-разрядного OLEDB через системный суррогатный процесс Windows:

  1. Откроем оснастку «Службы компонентов» (команда dcomcnfg).
  2. Создадим новое COM+ приложение типа «Приложение-сервер».
  3. На вкладке свойств пула укажем выполнение в 32-разрядном режиме.
  4. Добавим необходимый компонент доступа к данным. В этом случае 64-битный процесс сервера 1С будет обращаться к внешнему процессу dllhost.exe, выполняющемуся в 32-битном адресном пространстве, успешно минуя ограничение разрядности.

Решение 4. Чтение файла средствами платформы без внешних драйверов

Наиболее надежный подход, исключающий зависимость от драйверов OLEDB, версий Office и разрядности процессов — прямое чтение файла XLSX через штатные механизмы платформы 1С.

Файл с расширением .xlsx представляет собой ZIP-контейнер с файлами XML. Разберем пример распаковки и чтения содержимого штатными объектами ЧтениеZipФайла и ЧтениеXML:


КаталогРаспаковки = КаталогВременныхФайлов() + "ExcelUnpack_" + Строка(Новый УникальныйИдентификатор) + "\";
Архив = Новый ЧтениеZipФайла(ИмяФайла);
Архив.ИзвлечьВсе(КаталогРаспаковки);
Архив.Закрыть();

// Чтение общей таблицы строк из файла sharedStrings.xml
ПутьКСтрокам = КаталогРаспаковки + "xl/sharedStrings.xml";
Если ФайлСуществует(ПутьКСтрокам) Тогда
    Чтение = Новый ЧтениеXML;
    Чтение.ОткрытьФайл(ПутьКСтрокам);
    Пока Чтение.Прочитать() Цикл
        // Обработка текстовых узлов XML
    КонецЦикла;
    Чтение.Закрыть();
КонецЕсли;

// Очистка временного каталога
УдалитьФайлы(КаталогРаспаковки);

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

← На главную