При переходе на 64-разрядную платформу 1С:Предприятие разработчики часто сталкиваются с ошибками при попытке открыть файлы Excel через привычные механизмы ODBC или Jet OLEDB. Код, который годами стабильно работал в 32-разрядном клиенте или на сервере x86, начинает вызывать исключения вида «Заглушке переданы неправильные данные», «Не удается найти указанный поставщик» или сообщения о блокировке файла ядром Microsoft Jet.
Разберем детально, почему это происходит, как корректно настроить подключение через ADODB на 64-битной платформе и какие более простые и надежные альтернативы предоставляет встроенный язык 1С.
Проанализируем природу проблемы, с которой сталкивается 64-разрядный процесс 1С:
Microsoft Excel Driver (*.xls) и провайдер Microsoft.Jet.OLEDB.4.0 существуют исключительно в 32-битной реализации. Процесс 1cv8.exe или ragent.exe разрядности x64 физически не может загрузить 32-битные DLL-библиотеки в свое адресное пространство.dllhost.exe нередко приводит к ошибке «Заглушке переданы неправильные данные». Низкоуровневые интерфейсы OLE DB сложно поддаются стандартной сериализации RPC между разрядностями.Для прямого доступа к файлам Excel через ADODB в 64-битной системе необходимо использовать современный движок Microsoft Access Database Engine (ACE). Посмотрим, как выглядит универсальный код инициализации подключения:
Об_Конект = Новый COMОбъект("ADODB.Connection");
Стр_Подключения = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + ПутьКФайлу + ";Extended Properties=""Excel 12.0 Xml;HDR=Yes;IMEX=1;"";";
Попытка
Об_Конект.Open(Стр_Подключения);
Выборка = Новый COMОбъект("ADODB.Recordset");
Выборка.Open("SELECT * FROM [Лист1$]", Об_Конект);
Пока НЕ Выборка.EOF Цикл
// Обработка данных строки
Выборка.MoveNext();
КонецЦикла;
Выборка.Close();
Об_Конект.Close();
Исключение
Сообщить("Ошибка подключения к файлу Excel: " + ОписаниеОшибки());
КонецПопытки;
Разберем ключевые параметры строки подключения:
Microsoft.ACE.OLEDB.12.0 (или Microsoft.ACE.OLEDB.16.0 для свежих версий Access Database Engine)..xls (Excel 97–2003): Extended Properties="Excel 8.0;HDR=Yes;IMEX=1;".xlsx (OpenXML): Extended Properties="Excel 12.0 Xml;HDR=Yes;IMEX=1;".xlsm (с макросами): Extended Properties="Excel 12.0 Macro;HDR=Yes;IMEX=1;".xlsb (двоичный формат): Extended Properties="Excel 12.0;HDR=Yes;IMEX=1;"Важный нюанс установки драйвера: Если на рабочем месте уже установлен 32-разрядный пакет Microsoft Office, стандартный инсталлятор 64-битного ACE OLEDB выдаст ошибку несовместимости. Чтобы обойти это ограничение, выполним установку драйвера через командную строку в тихом режиме:
AccessDatabaseEngine_X64.exe /quiet
Если на сервере или клиентской машине установлен пакет Microsoft Office соответствующей разрядности, мы можем использовать прямое обращение к объектной модели Excel. Этот способ более ресурсоемкий, но не требует составления SQL-запросов к листам книги.
Рассмотрим пример чтения книги через OLE-автоматизацию:
Попытка
Excel = Новый COMОбъект("Excel.Application");
Excel.DisplayAlerts = Ложь;
Excel.Visible = Ложь;
Исключение
Сообщить("Не удалось инициализировать приложение Microsoft Excel: " + ОписаниеОшибки());
Возврат;
КонецПопытки;
Попытка
Книга = Excel.Workbooks.Open(ПутьКФайлу);
Лист = Книга.Worksheets(1);
// Получаем используемый диапазон данных
ВсегоСтрок = Лист.UsedRange.Rows.Count;
ВсегоКолонок = Лист.UsedRange.Columns.Count;
Для НомерСтроки = 1 По ВсегоСтрок Цикл
ЗначениеЯчейки = Лист.Cells(НомерСтроки, 1).Value;
// Обработка данных
КонецЦикла;
Книга.Close(Ложь);
Excel.Quit();
Исключение
Сообщить("Ошибка при обработке книги Excel: " + ОписаниеОшибки());
Если Excel <> Неопределено Тогда
Excel.Quit();
КонецЕсли;
КонецПопытки;
Начиная с платформы 8.3.6, в 1С появился нативный механизм чтения файлов Excel форматов .xls и .xlsx напрямую через объект ТабличныйДокумент. Это полностью платформенное решение, которое одинаково быстро и стабильно работает в 32- и 64-битных клиентах, на сервере 1С под Windows и Linux, а также не требует установки Microsoft Office или сторонних OLE DB драйверов.
Посмотрим на реализацию загрузки файла через табличный документ:
ТабДок = Новый ТабличныйДокумент;
Попытка
ТабДок.Прочитать(ПутьКФайлу);
Исключение
Сообщить("Не удалось прочитать файл Excel: " + ОписаниеОшибки());
Возврат;
КонецПопытки;
ВсегоСтрок = ТабДок.ВысотаТаблицы;
ВсегоКолонок = ТабДок.ШиринаТаблицы;
Для НомерСтроки = 1 По ВсегоСтрок Цикл
// Читаем значения из нужных колонок
КодТовара = ТабДок.Область(НомерСтроки, 1).Текст;
Количество = ТабДок.Область(НомерСтроки, 2).Текст;
// Выполняем бизнес-логику заполнения
КонецЦикла;
Проанализировав все способы взаимодействия с Excel в 64-битной среде, сформулируем практические рекомендации:
ТабличныйДокумент.Прочитать() — он исключает зависимость от сторонних библиотек и COM-технологий.Microsoft.ACE.OLEDB в тихом режиме и настроим подключение через ADODB.Connection.Excel.Application целесообразно оставлять только для сценариев со сложным форматированием, вызовом макросов VBA или специфической обработкой защищенных книг.