При работе с файлами Excel в системе 1С:Предприятие разработчики часто сталкиваются с ситуацией, когда метод ТабДокумент.Прочитать(ИмяФайла) не может открыть некоторые файлы формата .xls, выдавая ошибку вида "Ошибка при выполнении файловой операции 'e:\путь\к\файлу.xls'. Доступ к файлу не может быть получен." При этом другие файлы с тем же расширением .xls читаются без проблем. Эта ситуация вызывает закономерное недоумение, особенно когда на сервере точно установлены необходимые права доступа к папке, а MS Excel как офисное приложение отсутствует — есть универсальная загрузка из XLSX без Office.
Давайте подробно разберем, почему возникает такая проблема, какие существуют методы диагностики и какие решения можно применить для успешного чтения файлов Excel различных форматов в 1С — поможет универсальная загрузка из Excel с проверкой ошибок.
Ключ к пониманию этой проблемы кроется в разнообразии форматов файлов Excel, скрывающихся под привычными расширениями. Нам предстоит выяснить, что на самом деле представляет собой каждый файл.
Истинный .xls (бинарный формат Excel 97-2003):
Это старый, проприетарный бинарный формат файлов Excel. Для его чтения платформе 1С, как правило, требуется наличие установленного пакета Microsoft Office (или хотя бы компонентов COM) на сервере или клиентской машине, в зависимости от места выполнения кода. Без этих компонентов 1С не может нативно интерпретировать бинарную структуру такого файла, что часто приводит к ошибкам при попытке чтения.
.xlsx (открытый формат Office Open XML):
Современный формат, который появился с Microsoft Office 2007. Файл .xlsx на самом деле является ZIP-архивом, внутри которого содержится набор XML-файлов, описывающих структуру таблицы, данные, стили и т.д. Благодаря своей структуре, .xlsx файлы могут быть прочитаны платформой 1С нативно, без установки MS Office, используя встроенные механизмы для работы с ZIP-архивами и XML-документами.
Excel 2003 XML (XML-таблица с расширением .xls):
Это очень интересный случай, который часто вводит в заблуждение. Microsoft Excel 2003 имел возможность сохранять таблицы в формате "Таблица XML" (XML Spreadsheet). Иногда такие файлы сохранялись с расширением .xls, несмотря на то, что их внутреннее содержимое было чистым XML, а не бинарным форматом. Именно это объясняет, почему некоторые .xls файлы успешно читаются 1С без установленного Office: платформа воспринимает их как XML-документ, который она умеет парсить нативно. Если же вы попытаетесь прочитать такой файл, используя COM-объект Excel, это также сработает, но он будет обрабатываться как обычный Excel-файл.
Понимание этих различий критически важно, так как подход к чтению файла напрямую зависит от его реального внутреннего формата.
Прежде чем приступать к выбору метода чтения, нам необходимо точно определить, с каким типом файла мы имеем дело. Рассмотрим несколько шагов для диагностики.
Визуальный осмотр содержимого файла (ручной способ):
Попробуйте открыть проблемный файл с помощью обычного текстового редактора (например, Блокнота или Notepad++). Мы увидим следующее:
<?xml version="1.0"?>) и содержит читаемые XML-теги, это Excel 2003 XML.Один из участников обсуждения, после такого осмотра, воскликнул: "Лучше бы не смотрел.....в общем, поставить офис, видимо, придется...." Это как раз свидетельство обнаружения бинарного .xls файла.
Попытка открыть файл как ZIP-архив (ручной способ):
Если вы подозреваете, что файл с расширением .xls на самом деле является .xlsx (или просто хотите проверить), попробуйте переименовать его расширение на .zip, а затем открыть любым архиватором (например, встроенным в Windows или Total Commander). Если архиватор успешно откроет файл и покажет его внутреннюю структуру (например, папки "_rels", "xl", файлы вроде "workbook.xml"), значит, это .xlsx. Если же вы получите ошибку, это скорее всего бинарный .xls или Excel 2003 XML.
Программная проверка на .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.
После того как мы выяснили, с каким форматом файла мы имеем дело, мы можем выбрать наиболее подходящий способ для его чтения.
Прежде чем погружаться в специфику форматов, важно исключить базовые причины ошибки "Доступ к файлу не может быть получен". Мы должны убедиться, что:
Если эти базовые проверки пройдены, а ошибка все равно появляется только для определенных .xls файлов, тогда причина кроется в неспособности 1С интерпретировать сам формат.
Это самое простое и надежное решение для истинных бинарных .xls файлов.
Мы установим Microsoft Excel на сервер, где выполняется код 1С. Платформа 1С использует COM-объекты MS Excel для работы с файлами этого формата. Это позволяет 1С делегировать задачу чтения и записи файла самому Excel, что обеспечивает полную совместимость. Автор в итоге пришел к этому решению, хотя изначально и не хотел устанавливать Office на сервер.
Преимущества: Простота реализации (стандартные методы 1С), полная совместимость со всеми возможностями Excel (формулы, форматирование, несколько листов).
Недостатки: Необходимость лицензии на MS Office, нагрузка на сервер, возможность возникновения проблем с безопасностью или стабильностью COM-соединений.
ТабличныйДокумент.Прочитать()Платформа 1С обладает встроенными возможностями для чтения табличных документов — для этого подойдёт автоматизация загрузки в 1С из внешних источников.
Для файлов формата .xlsx: Метод ТабличныйДокумент.Прочитать() прекрасно справляется с чтением .xlsx файлов без необходимости установки MS Office (поможет загрузка номенклатуры из Excel без сторонних программ). 1С нативно умеет работать с этим форматом, поскольку он основан на XML и ZIP-архивах.
Для файлов формата Excel 2003 XML (с расширением .xls): Удивительно, но ТабличныйДокумент.Прочитать() также может успешно читать такие файлы, поскольку они по своей сути являются XML-документами, которые 1С умеет парсить. Это объясняет, почему автор видел, что "какие-то xls читаются".
Важно: Для истинных бинарных .xls файлов этот метод, скорее всего, не сработает без установленного MS Office (или его COM-компонентов).
Если мы не хотим устанавливать MS Office, но имеем дело с файлами форматов .xlsx или Excel 2003 XML, мы можем разобрать их содержимое программно — для этого есть загрузка документов из Excel с распознаванием структуры.
Для .xlsx:
Поскольку .xlsx это ZIP-архив, мы можем использовать объекты ЧтениеZipФайла и ЧтениеXML (или ПостроительDOM/ДокументDOM) для извлечения и анализа XML-файлов, составляющих структуру Excel-книги.
Шаги:
ЧтениеZipФайла для распаковки содержимого .xlsx файла во временную папку (как показано в примере диагностики выше).xl/workbook.xml (описывает структуру книги), xl/worksheets/sheetX.xml (содержит данные каждого листа), xl/sharedStrings.xml (содержит уникальные строковые значения, используемые в ячейках).ЧтениеXML или ДокументDOM для парсинга этих XML-файлов и извлечения необходимых данных.Этот подход дает нам полный контроль над процессом чтения и не требует Office, но является более сложным в реализации.
Для Excel 2003 XML:
Если файл .xls оказался XML-таблицей Excel 2003, мы можем читать его напрямую как XML-документ, используя ЧтениеXML или ДокументDOM. Этот способ также не требует установки MS Office.
Автор обсуждения в итоге пришел к комбинированному решению: "Пришлось дополнительно к екселю писать разбор XML, но все взлетело". Это означает, что для бинарных .xls он, вероятно, использовал установленный Office, а для XML-подобных файлов (будь то .xlsx или Excel 2003 XML) написал собственный парсер.
Это мощная альтернатива, позволяющая работать с файлами Excel как с источником данных, используя SQL-запросы.
Мы можем создать объект ADODB.Connection и подключиться к файлу Excel, а затем выполнять SELECT-запросы для извлечения данных из листов, как если бы они были таблицами базы данных. Для этого, как правило, требуется наличие установленного драйвера Microsoft Excel Driver (часто поставляется с MS Office или MDAC/ACE Redistributable). В отличие от прямого использования COM-объектов Excel, ADODB не открывает видимый экземпляр Excel и может быть более "легким" решением.
Преимущества: Не требует запущенного Excel, мощный механизм запросов.
Недостатки: Требует специфического драйвера, код для чтения придется полностью переписывать по сравнению со стандартными методами 1С.
В качестве дополнительных вариантов можно рассмотреть:
После того как мы успешно прочитали файл Excel в объект ТабличныйДокумент с помощью ТабДокумент.Прочитать(), часто возникает вопрос, как получить доступ к отдельным листам, если в исходном файле их было несколько. Автор также столкнулся с этим вопросом после решения основной проблемы.
Объект ТабличныйДокумент в 1С представляет собой единую структуру. Когда мы читаем файл Excel с несколькими листами, 1С обычно импортирует каждый лист в отдельную область или страницу внутри этого же объекта ТабличныйДокумент, сохраняя при этом информацию об именах листов.
Для доступа к информации о листах и работе с ними мы можем использовать следующие подходы:
Доступ к листам через области (если они именованы):
Если листы в исходном Excel файле имеют стандартные имена (например, "Лист1", "Лист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 и обрабатывать каждый из них по отдельности.
Сохранение нескольких табличных документов в один многостраничный файл Excel:
Если задача стоит не только в чтении, но и в формировании многостраничного файла Excel из нескольких объектов ТабличныйДокумент в 1С, начиная с версии платформы 8.3.3, вы можете использовать объект ПакетОтображаемыхДокументов.
// Пример сохранения нескольких ТабличныхДокументов в один многостраничный файл Excel
ПакетДокументов = Новый ПакетОтображаемыхДокументов;
// Добавляем первый ТабличныйДокумент
ТабДок1 = Новый ТабличныйДокумент;
// ... заполняем ТабДок1 ...
ПакетДокументов.Добавить(ТабДок1, "ПервыйЛист");
// Добавляем второй ТабличныйДокумент
ТабДок2 = Новый ТабличныйДокумент;
// ... заполняем ТабДок2 ...
ПакетДокументов.Добавить(ТабДок2, "ВторойЛист");
// Добавляем третий ТабличныйДокумент
ТабДок3 = Новый ТабличныйДокумент;
// ... заполняем ТабДок3 ...
ПакетДокументов.Добавить(ТабДок3, "Итоги");
// Сохраняем пакет в файл Excel
ИмяФайлаДляСохранения = КаталогВременныхФайлов + "МногостраничныйДокумент.xlsx";
ПакетДокументов.Записать(ИмяФайлаДляСохранения, ТипФайлаТабличногоДокумента.XLSX);
Сообщить("Многостраничный файл Excel сохранен: " + ИмяФайлаДляСохранения);
Этот механизм позволяет легко создавать многостраничные Excel-файлы, что является очень удобной функциональностью.
Как мы видим, проблема чтения Excel файлов в 1С гораздо глубже, чем кажется на первый взгляд, и часто связана с истинным форматом файла, скрывающимся под расширением.
Чтобы успешно справиться с этой задачей, мы рекомендуем следующий алгоритм:
ТабДокумент.Прочитать(). Он работает хорошо для этих форматов без необходимости установки MS Office. Если требуется более глубокий контроль или специфический парсинг, рассмотрите программный разбор XML-структуры.
Автор обсуждения успешно решил свою проблему, применив комплексный подход: установив Excel для бинарных файлов и разработав собственный XML-парсер для XML-основанных форматов. Этот опыт показывает, что универсального "серебряного шара" может не быть, и иногда приходится комбинировать несколько методов для достижения желаемого результата.