Нередко разработчики сталкиваются с ситуацией: обработка загрузки данных из файлов 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).
Здесь вступают в силу две ключевые причины сбоя:
rphost.exe — 64-разрядный. Драйверы Microsoft.Jet.OLEDB.4.0 и Microsoft.ACE.OLEDB.12.0 являются внутрипроцессными серверами (InProcServer32 DLL). 64-битный процесс физически не может загрузить в свое адресное пространство 32-битную библиотеку.Разберем, почему вызов Новый COMОбъект("Excel.Application") в фоновом задании отрабатывает штатно, в то время как подключение по OLEDB падает с ошибкой инициализации провайдера:
Excel.Application является внешним сервером COM (LocalServer32). Он запускается в операционной системе как отдельный процесс excel.exe. Механизм COM автоматически выполняет маршалинг и межпроцессное взаимодействие (IPC) между 64-разрядным сервером rphost.exe и 32-разрядным excel.exe.rphost.exe как библиотеки DLL. Драйвер Microsoft.Jet.OLEDB.4.0 вообще не имеет 64-разрядной версии в природе, а провайдер Microsoft.ACE.OLEDB.12.0 часто установлен в системе только в 32-битной редакции (вместе с 32-битным пакетом Microsoft Office).Если сервер 1С работает под управлением 64-разрядной платформы, для фоновых заданий требуется наличие 64-битного провайдера Microsoft.ACE.OLEDB.12.0 (или более поздней версии 16.0). Провайдер Jet 4.0 использовать на 64-разрядном сервере нельзя ни при каких условиях.
Рассмотрим, как правильно установить 64-разрядный драйвер на сервер:
AccessDatabaseEngine_X64.exe выдаст ошибку о невозможности совместной установки 32- и 64-битных компонентов.AccessDatabaseEngine_X64.exe /passive или AccessDatabaseEngine_X64.exe /quiet.rphost.exe в коде фоновых заданий.Если 64-битный драйвер зарегистрирован, но фоновое задание по-прежнему выдает ошибку, проанализируем настройки прав доступа служебной учетной записи:
.ldb или .laccdb) строго в том же каталоге, где расположен исходный файл Excel. Даже если в строке соединения указано открытие только для чтения, учетная запись службы USR1CV8 обязана иметь права на запись и на изменение в каталоге расположения файла.Z:\). Путь к файлу в коде должен быть строго в формате UNC: \\server\share\file.xlsx. Если служба запущена под локальным пользователем, у нее не будет доступа к сетевым папкам на других серверах. В таком случае службу необходимо перевести на доменную учетную запись.%TEMP% и %TMP% для учетной записи службы сервера 1С указывают на существующую папку, к которой у пользователя службы есть полный доступ.Если установить 64-разрядный драйвер на сервер невозможно или политика компании запрещает установку сторонних драйверов, настроим запуск 32-разрядного OLEDB через системный суррогатный процесс Windows:
dcomcnfg).dllhost.exe, выполняющемуся в 32-битном адресном пространстве, успешно минуя ограничение разрядности.Наиболее надежный подход, исключающий зависимость от драйверов OLEDB, версий Office и разрядности процессов — прямое чтение файла XLSX через штатные механизмы платформы 1С.
Файл с расширением .xlsx представляет собой ZIP-контейнер с файлами XML. Разберем пример распаковки и чтения содержимого штатными объектами ЧтениеZipФайла и ЧтениеXML:
КаталогРаспаковки = КаталогВременныхФайлов() + "ExcelUnpack_" + Строка(Новый УникальныйИдентификатор) + "\";
Архив = Новый ЧтениеZipФайла(ИмяФайла);
Архив.ИзвлечьВсе(КаталогРаспаковки);
Архив.Закрыть();
// Чтение общей таблицы строк из файла sharedStrings.xml
ПутьКСтрокам = КаталогРаспаковки + "xl/sharedStrings.xml";
Если ФайлСуществует(ПутьКСтрокам) Тогда
Чтение = Новый ЧтениеXML;
Чтение.ОткрытьФайл(ПутьКСтрокам);
Пока Чтение.Прочитать() Цикл
// Обработка текстовых узлов XML
КонецЦикла;
Чтение.Закрыть();
КонецЕсли;
// Очистка временного каталога
УдалитьФайлы(КаталогРаспаковки);
Такой программный разбор одинаково быстро и стабильно работает на клиенте, в серверных процедурах и в фоновых заданиях любой разрядности без необходимости конфигурирования прав DCOM и регистрации системных провайдеров.