Разберем распространенную задачу: пользователь загружает файл Excel в справочник «Файлы» (или «Версии файлов») через веб-клиент, а бухгалтер должен с помощью обработки выгрузить эти данные в табличную часть на форме, отредактировать их и сформировать итоговые документы.
При работе в веб-клиенте (особенно в браузерах Chrome, Firefox или Safari) стандартные механизмы работы с MS Excel через COM-объекты (COMОбъект("Excel.Application")) не работают. Кроме того, при публикации базы на веб-сервере у процесса 1С могут быть ограничены права на запись в произвольные каталоги диска. Рассмотрим подробнее, как обойти эти ограничения и корректно организовать работу с файлами.
Выясним главные причины, по которым классические методы загрузки Excel не подходят для веб-клиента:
Начиная с современных версий платформы 1С 8.3, объект ТабличныйДокумент умеет самостоятельно считывать файлы форматов .xlsx, .xls и .ods без установки сторонних программ и MS Office. Это идеальное решение для серверного кода.
Рассмотрим алгоритм действий:
ПолучитьИмяВременногоФайла().ТабличныйДокумент вызовом метода Прочитать().Посмотрим на пример кода, реализующего данный подход:
&НаСервере
Функция ПрочитатьФайлExcelИзСправочника(СсылкаНаФайл)
// Получаем двоичные данные из справочника или хранилища
ДвоичныеДанныеФайла = РаботаСФайлами.ПолучитьДвоичныеДанныеФайла(СсылкаНаФайл);
// Формируем имя временного файла на сервере
ИмяВременногоФайла = ПолучитьИмяВременногоФайла("xlsx");
ДвоичныеДанныеФайла.Записать(ИмяВременногоФайла);
// Читаем файл в ТабличныйДокумент
ТабДок = Новый ТабличныйДокумент;
Попытка
ТабДок.Прочитать(ИмяВременногоФайла);
УдалитьФайлы(ИмяВременногоФайла);
Исключение
УдалитьФайлы(ИмяВременногоФайла);
ВызватьИсключение "Ошибка при чтении файла Excel: " + ОписаниеОшибки();
КонецПопытки;
Возвращать ТабДок;
КонецФункции
Чтобы не перебирать ячейки табличного документа в медленном цикле по строкам и колонкам, проанализируем использование объекта ПостроительЗапроса. Он позволяет мгновенно превратить область табличного документа в ТаблицуЗначений.
Рассмотрим пример такого преобразования:
&НаСервере
Функция ПреобразоватьТабДокВТаблицуЗначений(ТабДокумент)
Построитель = Новый ПостроительЗапроса;
// Указываем весь заполненный диапазон табличного документа
Область = ТабДокумент.Область();
Построитель.ИсточникДанных = Новый ОписаниеИсточникаДанных(Область);
// Заполняем настройки и выполняем выборку
Построитель.ЗаполнитьНастройки();
Результат = Построитель.Выполнить();
// Выгружаем готовые данные в Таблицу Значений
Возврат Результат.Выгрузить();
КонецФункции
Проанализируем архитектурную альтернативу: если Excel-файл загружается в 1С исключительно для того, чтобы стать основой для документов внутри базы, хранить его в исходном виде .xlsx необязательно.
При загрузке файла первым пользователем целесообразно сразу конвертировать его структуру в формат 1С (например, сериализовать в ХранилищеЗначений в виде таблицы значений или массива структур). В этом случае второй пользователь (бухгалтер) откроет готовые данные мгновенно, без необходимости повторно разбирать файл Excel на сервере.
ХранилищеЗначений (или напрямую в структурированный регистр сведений).Если структура загружаемых Excel-файлов постоянно меняется, жестко задать колонки для табличной части формы сложно. В такой ситуации удобнее вывести прочитанный ТабличныйДокумент непосредственно на форму обработки.
Схема работы выглядит следующим образом:
ТабличныйДокумент и выводим его как элемент формы Поле табличного документа.Редактирование и Защита = Ложь.ТабДок.Прочитать() и присваиваем его реквизиту формы.Подводя итог: для успешной обработки файлов Excel в веб-клиенте переносите всю логику чтения на сервер, используйте штатный метод ТабличныйДокумент.Прочитать() и отказывайтесь от вызовов COM-объектов.