Почему возникает ошибка «Внешняя таблица не имеет предполагаемый формат» при чтении XLSX через ADO в 1С и как её исправить?

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

При интеграции 1С с внешними веб-сервисами и сторонними приложениями одной из частых задач является чтение выгруженных файлов Excel. Популярный способ программного чтения без необходимости устанавливать Microsoft Excel на сервере — использование COM-объекта ADODB.Connection с провайдером Microsoft.ACE.OLEDB.12.0.

Однако при попытке открыть такой файл разработчики нередко сталкиваются с ошибкой: «Произошла исключительная ситуация (Microsoft Access Database Engine): Внешняя таблица не имеет предполагаемый формат» (или в англоязычной версии: «External table is not in the expected format»). При этом если открыть проблемный файл вручную в Microsoft Excel и просто пересохранить его, он начинает без ошибок считываться и через ADO, и штатными средствами платформы 1С. Рассмотрим причины такого поведения и разберем способы решения задачи.

Посмотрим на типовой пример кода, вызывающий исключение:


еБаза = Новый COMОбъект("ADODB.Connection");
СтрокаПодключения = "
|Provider=Microsoft.ACE.OLEDB.12.0;
|Data Source=C:\Users\cd\AppData\Local\Temp\v8_7537_12b.xlsx;
|Extended Properties=""Excel 12.0 XML;IMEX=1;HDR=Yes;"";
";
еБаза.Open(СтрокаПодключения);

Почему Microsoft Access Database Engine отклоняет файл

Драйвер Microsoft.ACE.OLEDB.12.0 предъявляет очень строгие требования к структуре OpenXML-контейнера. Microsoft Excel при ручном открытии файла автоматически корректирует мелкие недочеты структуры прямо в оперативной памяти, а вот системный OLEDB-провайдер при любом несоответствии спецификации сразу прерывает работу с ошибкой. Проанализируем основные причины сбоя:

  1. Отсутствие тега диапазона листа. В XML-файле страницы (xl/worksheets/sheet*.xml) сторонние библиотеки часто забывают сформировать узел <dimension ref="A1:N..." />. Без явного указания размерности OLEDB-драйвер не может определить границы таблицы.
  2. Использование стандарта OpenXML Strict. Драйвер ACE OLEDB корректно работает со стандартом OpenXML Transitional, но не поддерживает более строгий диалект Strict, который иногда генерируют веб-библиотеки.
  3. Некорректная регистрация связей. Нарушение структуры связей в файлах _rels/.rels, xl/_rels/workbook.xml.rels или типов содержимого в [Content_Types].xml.
  4. Нестандартная обработка строк. Строки могут быть записаны инлайново через тег inlineStr вместо использования общей таблицы строк xl/sharedStrings.xml.

Что передать разработчикам внешнего сервиса для исправления

Если генерацией файлов занимается сторонняя сторона (например, веб-сервис на базе библиотек OpenXML), порекомендуем им выполнить следующие доработки:

  1. Проверить формируемый документ официальным валидатором схемы (Open XML SDK Productivity Tool или встроенными методами валидации библиотеки).
  2. Убедиться, что файл экспортируется в формате OpenXML Transitional.
  3. Обязательно добавлять в XML-разметку каждого листа узел <dimension> с реальными координатами заполненных строк и колонок.
  4. Проверить регистрацию всех листов в файле книги workbook.xml и связанных файлах связей (.rels).

Корректировка параметров строки подключения ADO

Иногда драйвер дает сбой из-за особенностей синтаксиса параметра Extended Properties. Попробуем скорректировать строку подключения, убрав суффикс XML и проверив экранирование параметров:


СтрокаПодключения = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + ИмяФайла + ";Extended Properties=""Excel 12.0;HDR=YES;IMEX=1;"";";

Альтернативные способы чтения файлов Excel в 1С без MS Office

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

1. Использование штатного метода ТабличныйДокумент.Прочитать

Начиная с платформы 8.3, объект ТабличныйДокумент умеет читать файлы .xlsx напрямую:


ТабДок = Новый ТабличныйДокумент;
Попытка
    ТабДок.Прочитать(ИмяФайла);
    // Далее выполняем обход ячеек ТабДок.ПолучитьОбласть(...)
Исключение
    Сообщить("Не удалось прочитать файл стандартным методом: " + ОписаниеОшибки());
КонецПопытки;

Однако если файл сильно поврежден или сформирован с грубыми нарушениями стандарта, данный метод также может вернуть ошибку выполнения файловой операции. В этом случае перейдем к прямому чтению структуры.

2. Прямой парсинг XLSX через ЧтениеZipФайла и ЧтениеXML

Файл формата .xlsx представляет собой стандартный ZIP-архив с XML-документами внутри. Платформа 1С содержит все необходимые объекты для его разбора без внешних драйверов:

  1. Распаковываем .xlsx во временный каталог с помощью объекта ЧтениеZipФайла.
  2. С помощью объекта ЧтениеXML считываем файл xl/sharedStrings.xml и сохраняем строки в массив или соответствие.
  3. Последовательно читаем файл листа xl/worksheets/sheet1.xml, извлекая строки (теги <row>) и ячейки (теги <c>).

Этот метод работает максимально быстро, полностью кроссплатформенен (работает как под Windows, так и под Linux) и абсолютно не зависит от строгости драйверов OLEDB.

3. Использование системного ODBC-драйвера

В ряде ситуаций драйвер ODBC оказывается более устойчивым к нестандартной структуре файла, чем OLEDB. Подключение через ADODB в этом случае выглядит следующим образом:


Соединение = Новый COMОбъект("ADODB.Connection");
СтрокаПодключения = "Driver={Microsoft Excel Driver (*.xls, *.xlsx, *.xlsm, *.xlsb)};DBQ=" + ИмяФайла + ";ReadOnly=1;";
Соединение.Open(СтрокаПодключения);

4. Использование внешних компонент и консольных утилит

Если требуется регулярная обработка больших объемов нестандартных файлов, можно применить внешние библиотеки (.NET-компоненты на базе ExcelDataReader или ClosedXML) либо вызвать легковесную консольную утилиту через метод ЗапуститьПриложение() для предварительной конвертации файла в формат .csv.

← На главную