При разработке обработок загрузки данных из табличных документов разработчики часто используют встроенный метод ТабличныйДокумент.Прочитать(). Нередко возникает ситуация, когда на локальном компьютере или в файловой базе код отрабатывает штатно, но при переносе на сервер или в клиент-серверный режим выполнения возникает исключение: Ошибка при выполнении файловой операции. Разберем по шагам причины такого поведения платформы и рассмотрим надежные способы решения проблемы.
Первая и самая распространенная причина ошибки — разрыв контекста между клиентом и сервером. Проанализируем типичную ситуацию:
D:\Files\import.xlsx).D:\Files\import.xlsx, однако на физическом диске сервера такой файл отсутствует либо путь указывает на локальный диск рабочей станции пользователя.Если файл открыт в другой программе в монопольном режиме, платформа также не сможет получить к нему доступ на чтение, что приведет к аналогичной файловой ошибке.
Чтобы исключить проблему с путями и сетевой доступностью, организуем чтение файла по надежной схеме: поместим файл во временное хранилище на клиенте и прочитаем его из временного файла на стороне сервера.
Рассмотрим пример кода:
// Клиентский вызов
&НаКлиенте
Процедура ЗагрузитьФайлНаКлиенте()
Диалог = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);
Диалог.Фильтр = "Файлы Excel (*.xlsx;*.xls)|*.xlsx;*.xls";
Диалог.Заголовок = "Выберите файл для загрузки";
Если Диалог.Выбрать() Тогда
ВыбранныйПуть = Диалог.ПолноеИмяФайла;
ДвоичныеДанныеФайла = Новый ДвоичныеДанные(ВыбранныйПуть);
АдресХранилища = ПоместитьВоВременноеХранилище(ДвоичныеДанныеФайла, Новый УникальныйИдентификатор);
ПрочитатьФайлНаСервере(АдресХранилища);
КонецЕсли;
КонецПроцедуры
// Серверная обработка
&НаСервере
Процедура ПрочитатьФайлНаСервере(АдресХранилища)
ДвоичныеДанныеФайла = ПолучитьИзВременногоХранилища(АдресХранилища);
Если ДвоичныеДанныеФайла = Неопределено Тогда
ВызватьИсключение "Не удалось получить данные файла из хранилища.";
КонецЕсли;
ВременныйПуть = ПолучитьИмяВременногоФайла("xlsx");
ДвоичныеДанныеФайла.Записать(ВременныйПуть);
ТабДок = Новый ТабличныйДокумент;
Попытка
ТабДок.Прочитать(ВременныйПуть, СпособЧтенияЗначенийТабличногоДокумента.Текст);
Исключение
УдалитьФайлы(ВременныйПуть);
ВызватьИсключение "Ошибка при чтении табличного документа: " + ОписаниеОшибки();
КонецПопытки;
УдалитьФайлы(ВременныйПуть);
// Дальнейшая обработка строк ТабДок
КонецПроцедуры
Метод ТабличныйДокумент.Прочитать() крайне чувствителен к содержимому файла. Выясним частые проблемы с исходными данными:
.xls. Excel открывает такие файлы без предупреждений, но парсер 1С выдает ошибку файловой операции. Проверить это можно, открыв файл в обычном текстовом редакторе (наличие тегов <html> или <?xml подтверждает подмену формата).СпособЧтенияЗначенийТабличногоДокумента.Текст.Проанализируем системные факторы, влияющие на операцию чтения:
8.3.5.1383) присутствовали зарегистрированные ошибки работы встроенного парсера табличных документов при чтении определенных структур XLSX. В таких случаях решением является обновление технологической платформы 1С до актуального стабильного релиза.%TEMP%. Учетная запись, от имени которой запущена служба сервера 1С (обычно USR1CV8), должна обладать полными правами на чтение, запись и удаление файлов в каталоге временных файлов.Если платформенный метод чтения не подходит из-за особенностей формата файла или ограничений среды, рассмотрим альтернативные варианты реализации:
ADODB.Connection с использованием SQL-запросов к листам книги. Требует наличия установленного драйвера Microsoft ACE OLEDB нужной разрядности на сервере или клиенте.ЧтениеZipФайла и ЧтениеXML можно напрямую распаковать и последовательно прочитать файлы xl/worksheets/sheet1.xml и xl/sharedStrings.xml. Этот метод работает быстро, не требует установленного MS Office и корректно выполняется как на Windows, так и на Linux-серверах.