При разработке механизмов загрузки данных из внешних файлов разработчики часто используют метод ТабличныйДокумент.Прочитать(). Этот метод удобен тем, что позволяет быстро загрузить данные из файлов форматов .xls и .xlsx во встроенную таблицу 1С без обязательного наличия установленного пакета Microsoft Office. Однако на практике можно столкнуться с ситуацией, когда на локальном компьютере обработка отрабатывает корректно, а при запуске на сервере или в терминальном окружении возникает исключение:
«Ошибка при выполнении файловой операции»
Разберем по шагам, почему возникает эта ошибка, как локализовать ее источник и какие альтернативные способы чтения данных Excel существуют в платформе 1С:Предприятие.
Проанализируем ключевые факторы, приводящие к ошибке файловой операции при чтении документов Excel:
.xls или .xlsx, которые на самом деле являются файлами HTML, CSV или XML (SpreadsheetML). Также возможна ситуация, когда файл современного формата OpenXML (ZIP-архив) сохранен с расширением .xls. Метод ТабличныйДокумент.Прочитать() выполняет строгую проверку сигнатуры файла, и при несовпадении генерирует ошибку..xlsx платформа 1С распаковывает его структуру во временную папку текущего пользователя операционной системы. Если у пользователя или службы сервера 1С нет прав на запись/создание файлов в каталоге Temp, либо если диск переполнен, чтение завершается ошибкой файловой операции.Z:\), которые не видны серверному процессу.Рассмотрим порядок действий для исправления ошибки:
PK — это корректный ZIP-контейнер OpenXML (формат XLSX). Если видны теги <html> или <?xml — файл не является двоичным XLS, и метод Прочитать() для него не подходит (такие файлы следует открывать методами работы с текстом или XML).%TEMP% и %TMP%.
// Клиентский контекст
АдресВХ = ПоместитьВоВременноеХранилище(Новый ДвоичныеДанные(ПутьКФайлуНаКлиенте), УникальныйИдентификатор);
ПрочитатьФайлНаСервере(АдресВХ);
// Серверный контекст
&НаСервере
Процедура ПрочитатьФайлНаСервере(АдресВХ)
ДвоичныеДанныеФайла = ПолучитьИзВременногоХранилища(АдресВХ);
ИмяВременногоФайла = ПолучитьИмяВременногоФайла("xlsx");
ДвоичныеДанныеФайла.Записать(ИмяВременногоФайла);
ТабДок = Новый ТабличныйДокумент;
ТабДок.Прочитать(ИмяВременногоФайла);
УдалитьФайлы(ИмяВременногоФайла);
КонецПроцедуры
Если метод ТабличныйДокумент.Прочитать() по-прежнему вызывает сбои из-за сложного содержимого книги или ограничений платформы, рассмотрим надежные альтернативные варианты:
1. Чтение через COM-объект Excel (Windows)
Подходит для обычных и управляемых форм при работе в среде Windows с установленным пакетом MS Excel:
Попытка
ExcelПриложение = Новый COMОбъект("Excel.Application");
ExcelПриложение.Visible = Ложь;
ExcelПриложение.DisplayAlerts = Ложь;
Книга = ExcelПриложение.Workbooks.Open(ПутьКФайлу);
Лист = Книга.Sheets(1);
// Получение значения ячейки (строка 2, колонка 1)
Значение = Лист.Cells(2, 1).Value;
Книга.Close(Ложь);
ExcelПриложение.Quit();
Исключение
ExcelПриложение = Неопределено;
ВызватьИсключение "Не удалось прочитать файл Excel через COM: " + ОписаниеОшибки();
КонецПопытки;
2. Чтение через технологию ADODB (без необходимости запуска MS Excel)
Позволяет быстро считывать данные из таблиц Excel как из базы данных при наличии установленного драйвера Microsoft ACE OLEDB:
Соединение = Новый COMОбъект("ADODB.Connection");
СтрокаПодключения = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + ПутьКФайлу + ";Extended Properties=""Excel 12.0 Xml;HDR=YES;"";";
Попытка
Соединение.Open(СтрокаПодключения);
Команда = Новый COMОбъект("ADODB.Command");
Команда.ActiveConnection = Соединение;
Команда.CommandText = "SELECT * FROM [Лист1$]";
НаборЗаписей = Команда.Execute();
Пока НаборЗаписей.EOF() = 0 Цикл
ЗначениеКолонки = НаборЗаписей.Fields(0).Value;
НаборЗаписей.MoveNext();
КонецЦикла;
Соединение.Close();
Исключение
Соединение = Неопределено;
ВызватьИсключение "Ошибка подключения через ADODB: " + ОписаниеОшибки();
КонецПопытки;
3. Прямой разбор XLSX через ЧтениеZIPФайла и ЧтениеXML
Файл .xlsx представляет собой стандартный ZIP-архив. Распаковав его средствами объекта ЧтениеZIPФайла, можно программно прочитать файл строк xl/sharedStrings.xml и сам лист xl/worksheets/sheet1.xml с помощью объекта ЧтениеXML. Этот подход работает кроссплатформенно (в том числе под управлением Linux), не зависит от сторонних библиотек и защищен от системных ошибок COM-интерфейсов.