Почему 1С не читает некоторые Excel файлы формата .xls и как это исправить?

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

При работе с файлами Excel в системе 1С:Предприятие разработчики часто сталкиваются с ситуацией, когда метод ТабДокумент.Прочитать(ИмяФайла) не может открыть некоторые файлы формата .xls, выдавая ошибку вида "Ошибка при выполнении файловой операции 'e:\путь\к\файлу.xls'. Доступ к файлу не может быть получен." При этом другие файлы с тем же расширением .xls читаются без проблем. Эта ситуация вызывает закономерное недоумение, особенно когда на сервере точно установлены необходимые права доступа к папке, а MS Excel как офисное приложение отсутствует — есть универсальная загрузка из XLSX без Office.

Давайте подробно разберем, почему возникает такая проблема, какие существуют методы диагностики и какие решения можно применить для успешного чтения файлов Excel различных форматов в 1С — поможет универсальная загрузка из Excel с проверкой ошибок.

Разбираемся в форматах файлов Excel: .xls, .xlsx и Excel 2003 XML

Ключ к пониманию этой проблемы кроется в разнообразии форматов файлов Excel, скрывающихся под привычными расширениями. Нам предстоит выяснить, что на самом деле представляет собой каждый файл.

  1. Истинный .xls (бинарный формат Excel 97-2003):

    Это старый, проприетарный бинарный формат файлов Excel. Для его чтения платформе 1С, как правило, требуется наличие установленного пакета Microsoft Office (или хотя бы компонентов COM) на сервере или клиентской машине, в зависимости от места выполнения кода. Без этих компонентов 1С не может нативно интерпретировать бинарную структуру такого файла, что часто приводит к ошибкам при попытке чтения.

  2. .xlsx (открытый формат Office Open XML):

    Современный формат, который появился с Microsoft Office 2007. Файл .xlsx на самом деле является ZIP-архивом, внутри которого содержится набор XML-файлов, описывающих структуру таблицы, данные, стили и т.д. Благодаря своей структуре, .xlsx файлы могут быть прочитаны платформой 1С нативно, без установки MS Office, используя встроенные механизмы для работы с ZIP-архивами и XML-документами.

  3. Excel 2003 XML (XML-таблица с расширением .xls):

    Это очень интересный случай, который часто вводит в заблуждение. Microsoft Excel 2003 имел возможность сохранять таблицы в формате "Таблица XML" (XML Spreadsheet). Иногда такие файлы сохранялись с расширением .xls, несмотря на то, что их внутреннее содержимое было чистым XML, а не бинарным форматом. Именно это объясняет, почему некоторые .xls файлы успешно читаются 1С без установленного Office: платформа воспринимает их как XML-документ, который она умеет парсить нативно. Если же вы попытаетесь прочитать такой файл, используя COM-объект Excel, это также сработает, но он будет обрабатываться как обычный Excel-файл.

Понимание этих различий критически важно, так как подход к чтению файла напрямую зависит от его реального внутреннего формата.

Диагностика типа файла: как определить истинный формат

Прежде чем приступать к выбору метода чтения, нам необходимо точно определить, с каким типом файла мы имеем дело. Рассмотрим несколько шагов для диагностики.

  1. Визуальный осмотр содержимого файла (ручной способ):

    Попробуйте открыть проблемный файл с помощью обычного текстового редактора (например, Блокнота или Notepad++). Мы увидим следующее:

    • Если файл начинается с хаотичного набора символов, похожих на "кракозябры", и не содержит читаемого текста или XML-тегов, скорее всего, это истинный бинарный .xls.
    • Если файл начинается со строки, похожей на "PK" (заголовок ZIP-архива), и содержит много нечитаемых, но структурированных данных, это указывает на то, что файл является .xlsx, даже если у него расширение .xls.
    • Если файл начинается с XML-декларации (например, <?xml version="1.0"?>) и содержит читаемые XML-теги, это Excel 2003 XML.

    Один из участников обсуждения, после такого осмотра, воскликнул: "Лучше бы не смотрел.....в общем, поставить офис, видимо, придется...." Это как раз свидетельство обнаружения бинарного .xls файла.

  2. Попытка открыть файл как ZIP-архив (ручной способ):

    Если вы подозреваете, что файл с расширением .xls на самом деле является .xlsx (или просто хотите проверить), попробуйте переименовать его расширение на .zip, а затем открыть любым архиватором (например, встроенным в Windows или Total Commander). Если архиватор успешно откроет файл и покажет его внутреннюю структуру (например, папки "_rels", "xl", файлы вроде "workbook.xml"), значит, это .xlsx. Если же вы получите ошибку, это скорее всего бинарный .xls или Excel 2003 XML.

  3. Программная проверка на .xlsx в 1С:

    Для автоматизации проверки на .xlsx формат вы можете использовать встроенные средства 1С для работы с ZIP-архивами. Этот подход позволяет определить, является ли файл ZIP-архивом, содержащим структуру Excel Open XML. Рассмотрим пример кода:

    
    // Предполагаем, что "ВыбФайл" содержит полный путь к проверяемому файлу Excel
    ВременнаяПапка = КаталогВременныхФайлов + "TempXLSX_Check\";
    СоздатьКаталог(ВременнаяПапка);
    
    Попытка
        Архиватор = Новый ЧтениеZipФайла(ВыбФайл); // Пытаемся открыть как ZIP
        Режим = РежимВосстановленияПутейФайловZIP.НеВосстанавливать;
        
        // Проверяем наличие ключевых файлов XLSX структуры
        ЕстьWorkbookXML = Ложь;
        Для Каждого ЭлементАрхива Из Архиватор.Элементы Цикл
            Если СтрНайти(ЭлементАрхива.Имя, "workbook.xml") > 0 Тогда
                ЕстьWorkbookXML = Истина;
                Прервать;
            КонецЕсли;
        КонецЦикла;
        
        Если ЕстьWorkbookXML Тогда
            Сообщить("Файл '" + ВыбФайл + "' является, вероятно, XLSX форматом.");
            // Можно дополнительно распаковать и работать с XML
            // Архиватор.Извлечь(..., ВременнаяПапка, Режим);
        Иначе
            Сообщить("Файл '" + ВыбФайл + "' не является XLSX форматом (нет workbook.xml).");
        КонецЕсли;
        
    Исключение
        // Ошибка при открытии как ZIP, вероятно это не XLSX
        Сообщить("Ошибка при попытке открыть файл как ZIP-архив. Вероятно, это бинарный XLS или Excel 2003 XML.");
    КонецПопытки;
    
    // Очистка временной папки
    УдалитьФайлы(ВременнаяПапка + "*", Истина);
    УдалитьКаталог(ВременнаяПапка);
    

    Этот код пытается открыть файл как ZIP. Если это успешно, мы проверяем наличие файла workbook.xml, который является ключевым для формата .xlsx. Если такой файл найден, то, скорее всего, перед нами .xlsx.

Варианты решения проблемы чтения Excel файлов в 1С

После того как мы выяснили, с каким форматом файла мы имеем дело, мы можем выбрать наиболее подходящий способ для его чтения.

  1. Устранение ошибки "Доступ к файлу не может быть получен"

    Прежде чем погружаться в специфику форматов, важно исключить базовые причины ошибки "Доступ к файлу не может быть получен". Мы должны убедиться, что:

    • Права доступа: У пользователя, под которым работает сервер 1С (или клиент, если код выполняется на клиенте), есть полные права на чтение и запись в папку, где находится файл Excel, а также в папку для временных файлов.
    • Занятость файла: Файл не открыт другим пользователем или процессом в момент попытки чтения 1С.
    • Целостность файла: Файл не поврежден. Попробуйте открыть его вручную в MS Excel или LibreOffice.

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

  2. Установка MS Office (Excel) на сервере

    Это самое простое и надежное решение для истинных бинарных .xls файлов.

    Мы установим Microsoft Excel на сервер, где выполняется код 1С. Платформа 1С использует COM-объекты MS Excel для работы с файлами этого формата. Это позволяет 1С делегировать задачу чтения и записи файла самому Excel, что обеспечивает полную совместимость. Автор в итоге пришел к этому решению, хотя изначально и не хотел устанавливать Office на сервер.

    Преимущества: Простота реализации (стандартные методы 1С), полная совместимость со всеми возможностями Excel (формулы, форматирование, несколько листов).

    Недостатки: Необходимость лицензии на MS Office, нагрузка на сервер, возможность возникновения проблем с безопасностью или стабильностью COM-соединений.

  3. Нативное чтение с помощью ТабличныйДокумент.Прочитать()

    Платформа 1С обладает встроенными возможностями для чтения табличных документов — для этого подойдёт автоматизация загрузки в 1С из внешних источников.

    • Для файлов формата .xlsx: Метод ТабличныйДокумент.Прочитать() прекрасно справляется с чтением .xlsx файлов без необходимости установки MS Office (поможет загрузка номенклатуры из Excel без сторонних программ). 1С нативно умеет работать с этим форматом, поскольку он основан на XML и ZIP-архивах.

    • Для файлов формата Excel 2003 XML (с расширением .xls): Удивительно, но ТабличныйДокумент.Прочитать() также может успешно читать такие файлы, поскольку они по своей сути являются XML-документами, которые 1С умеет парсить. Это объясняет, почему автор видел, что "какие-то xls читаются".

    Важно: Для истинных бинарных .xls файлов этот метод, скорее всего, не сработает без установленного MS Office (или его COM-компонентов).

  4. Программный парсинг XML для .xlsx и Excel 2003 XML

    Если мы не хотим устанавливать MS Office, но имеем дело с файлами форматов .xlsx или Excel 2003 XML, мы можем разобрать их содержимое программно — для этого есть загрузка документов из Excel с распознаванием структуры.

    • Для .xlsx:

      Поскольку .xlsx это ZIP-архив, мы можем использовать объекты ЧтениеZipФайла и ЧтениеXML (или ПостроительDOM/ДокументDOM) для извлечения и анализа XML-файлов, составляющих структуру Excel-книги.

      Шаги:

      1. Используем ЧтениеZipФайла для распаковки содержимого .xlsx файла во временную папку (как показано в примере диагностики выше).
      2. Получаем доступ к ключевым XML-файлам, таким как xl/workbook.xml (описывает структуру книги), xl/worksheets/sheetX.xml (содержит данные каждого листа), xl/sharedStrings.xml (содержит уникальные строковые значения, используемые в ячейках).
      3. Используем ЧтениеXML или ДокументDOM для парсинга этих XML-файлов и извлечения необходимых данных.

      Этот подход дает нам полный контроль над процессом чтения и не требует Office, но является более сложным в реализации.

    • Для Excel 2003 XML:

      Если файл .xls оказался XML-таблицей Excel 2003, мы можем читать его напрямую как XML-документ, используя ЧтениеXML или ДокументDOM. Этот способ также не требует установки MS Office.

    Автор обсуждения в итоге пришел к комбинированному решению: "Пришлось дополнительно к екселю писать разбор XML, но все взлетело". Это означает, что для бинарных .xls он, вероятно, использовал установленный Office, а для XML-подобных файлов (будь то .xlsx или Excel 2003 XML) написал собственный парсер.

  5. Использование ADODB (ActiveX Data Objects)

    Это мощная альтернатива, позволяющая работать с файлами Excel как с источником данных, используя SQL-запросы.

    Мы можем создать объект ADODB.Connection и подключиться к файлу Excel, а затем выполнять SELECT-запросы для извлечения данных из листов, как если бы они были таблицами базы данных. Для этого, как правило, требуется наличие установленного драйвера Microsoft Excel Driver (часто поставляется с MS Office или MDAC/ACE Redistributable). В отличие от прямого использования COM-объектов Excel, ADODB не открывает видимый экземпляр Excel и может быть более "легким" решением.

    Преимущества: Не требует запущенного Excel, мощный механизм запросов.

    Недостатки: Требует специфического драйвера, код для чтения придется полностью переписывать по сравнению со стандартными методами 1С.

  6. Внешние компоненты или OpenOffice/LibreOffice

    В качестве дополнительных вариантов можно рассмотреть:

    • Внешние компоненты: Существуют готовые внешние компоненты для 1С, разработанные сторонними разработчиками, которые предоставляют функциональность чтения .xls и .xlsx файлов без установки MS Office. Некоторые из них являются "native"-компонентами и не требуют регистрации в реестре, что упрощает их использование.
    • OpenOffice/LibreOffice: Если MS Office нежелателен, можно установить LibreOffice Calc на сервер и использовать его COM-объекты для работы с Excel-файлами, если это возможно в вашей среде. Этот путь, как правило, сложнее в настройке и поддержке, чем использование MS Office.

Работа с несколькими листами в прочитанном табличном документе 1С

После того как мы успешно прочитали файл Excel в объект ТабличныйДокумент с помощью ТабДокумент.Прочитать(), часто возникает вопрос, как получить доступ к отдельным листам, если в исходном файле их было несколько. Автор также столкнулся с этим вопросом после решения основной проблемы.

Объект ТабличныйДокумент в 1С представляет собой единую структуру. Когда мы читаем файл Excel с несколькими листами, 1С обычно импортирует каждый лист в отдельную область или страницу внутри этого же объекта ТабличныйДокумент, сохраняя при этом информацию об именах листов.

Для доступа к информации о листах и работе с ними мы можем использовать следующие подходы:

  1. Доступ к листам через области (если они именованы):

    Если листы в исходном Excel файле имеют стандартные имена (например, "Лист1", "Лист2"), то после чтения в ТабличныйДокумент, эти листы могут быть доступны как именованные области или части документа. Однако, ТабличныйДокумент по своей природе является одностраничным. Метод Прочитать() считывает данные со всех листов, но обычно "объединяет" их в один большой табличный документ, или же требуется переключаться между листами через вспомогательные механизмы.

  2. Чтение каждого листа по отдельности (при использовании COM):

    Если вы используете COM-объект MS Excel (например, Excel.Application), то работа с листами становится очевидной:

    
    // Пример использования COM-объекта Excel для чтения нескольких листов
    Попытка
        ExcelПриложение = Новый COMОбъект("Excel.Application");
        ExcelПриложение.Workbooks.Open(ИмяФайлаExcel);
        
        Для Каждого ЛистЭксель Из ExcelПриложение.ActiveWorkbook.Sheets Цикл
            Сообщить("Обрабатываем лист: " + ЛистЭксель.Name);
            
            ТабДокЛиста = Новый ТабличныйДокумент;
            // Здесь можно скопировать данные с текущего ЛистЭксель в ТабДокЛиста
            // Например, используя ЛистЭксель.UsedRange.Copy() и ТабДокЛиста.Paste()
            // Или считывать ячейки по одной: ЛистЭксель.Cells(Строка, Колонка).Value
            
            // Далее работаем с ТабДокЛиста как с отдельным документом
            // ...
            
        КонецЦикла;
        
        ExcelПриложение.Quit();
    Исключение
        Сообщить("Ошибка при работе с Excel через COM: " + ОписаниеОшибки());
    КонецПопытки;
    

    Этот подход позволяет нам итерировать по всем листам книги Excel и обрабатывать каждый из них по отдельности.

  3. Сохранение нескольких табличных документов в один многостраничный файл Excel:

    Если задача стоит не только в чтении, но и в формировании многостраничного файла Excel из нескольких объектов ТабличныйДокумент в 1С, начиная с версии платформы 8.3.3, вы можете использовать объект ПакетОтображаемыхДокументов.

    
    // Пример сохранения нескольких ТабличныхДокументов в один многостраничный файл Excel
    ПакетДокументов = Новый ПакетОтображаемыхДокументов;
    
    // Добавляем первый ТабличныйДокумент
    ТабДок1 = Новый ТабличныйДокумент;
    // ... заполняем ТабДок1 ...
    ПакетДокументов.Добавить(ТабДок1, "ПервыйЛист");
    
    // Добавляем второй ТабличныйДокумент
    ТабДок2 = Новый ТабличныйДокумент;
    // ... заполняем ТабДок2 ...
    ПакетДокументов.Добавить(ТабДок2, "ВторойЛист");
    
    // Добавляем третий ТабличныйДокумент
    ТабДок3 = Новый ТабличныйДокумент;
    // ... заполняем ТабДок3 ...
    ПакетДокументов.Добавить(ТабДок3, "Итоги");
    
    // Сохраняем пакет в файл Excel
    ИмяФайлаДляСохранения = КаталогВременныхФайлов + "МногостраничныйДокумент.xlsx";
    ПакетДокументов.Записать(ИмяФайлаДляСохранения, ТипФайлаТабличногоДокумента.XLSX);
    
    Сообщить("Многостраничный файл Excel сохранен: " + ИмяФайлаДляСохранения);
    

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

Итоги и рекомендации

Как мы видим, проблема чтения Excel файлов в 1С гораздо глубже, чем кажется на первый взгляд, и часто связана с истинным форматом файла, скрывающимся под расширением.

Чтобы успешно справиться с этой задачей, мы рекомендуем следующий алгоритм:

  1. Начните с диагностики: Всегда выясняйте истинный формат файла (бинарный .xls, .xlsx, Excel 2003 XML) с помощью ручных методов (текстовый редактор, ZIP-архиватор) или программной проверки.
  2. Для .xlsx и Excel 2003 XML: В первую очередь попробуйте использовать нативный метод ТабДокумент.Прочитать(). Он работает хорошо для этих форматов без необходимости установки MS Office. Если требуется более глубокий контроль или специфический парсинг, рассмотрите программный разбор XML-структуры.
  3. Для истинных бинарных .xls: Если файл оказался бинарным .xls, то наиболее надежным решением будет установка Microsoft Office (Excel) на сервер и использование COM-объектов. Альтернативно, рассмотрите ADODB, если готовы переписать логику чтения, или изучите сторонние внешние компоненты.
  4. При возникновении ошибки "Доступ к файлу не может быть получен": Всегда проверяйте права доступа к папкам и убедитесь, что файл не занят другим процессом. Если эти базовые проверки не дают результата, то, скорее всего, причина кроется в неспособности 1С интерпретировать формат файла.

Автор обсуждения успешно решил свою проблему, применив комплексный подход: установив Excel для бинарных файлов и разработав собственный XML-парсер для XML-основанных форматов. Этот опыт показывает, что универсального "серебряного шара" может не быть, и иногда приходится комбинировать несколько методов для достижения желаемого результата.

← На главную