При переходе конфигураций в облачный сервис 1С:ГРМ (Готовое рабочее место) разработчики часто сталкиваются с тем, что привычные механизмы интеграции перестают работать. В локальной среде многие привыкли работать через прямое обращение к файловой системе клиента или через COM-соединение с приложением Microsoft Excel. В облаке база, как правило, открывается через браузер (веб-клиент) или тонкий клиент через веб-сервер, а серверная часть функционирует в изолированном окружении, где Microsoft Office отсутствует вовсе.
Рассмотрим, как правильно организовать выбор и загрузку файла Excel из локального каталога пользователя в базу данных 1С:ГРМ без необходимости ручного копирования данных.
Прежде чем перейти к реализации, проанализируем специфику работы в 1С:ГРМ:
COMОбъект("Excel.Application") невозможно на сервере облака (часто работающем под Linux или без установленного пакета MS Office), а также заблокировано политикой безопасности веб-клиента в браузере.Для интерактивной передачи файла с клиентского компьютера на сервер платформы 1С:Предприятие 8.3 в управляемом приложении используется асинхронная процедура НачатьПомещениеФайлаНаСервер. Она одинаково стабильно работает как в тонком, так и в веб-клиенте.
Разберем по шагам реализацию команды формы для выбора файла и его последующей обработки.
На стороне клиента создаем обработчик команды, который открывает диалог выбора файла и сразу помещает его во временное хранилище на сервере:
&НаКлиенте
Процедура ЗагрузитьФайлExcel(Команда)
Оповещение = Новый ОписаниеОповещения("ПослеПомещенияФайла", ЭтотОбъект);
ПараметрыДиалога = Новый ПараметрыДиалогаПомещенияФайлов;
ПараметрыДиалога.Заголовок = "Выберите файл для загрузки";
ПараметрыДиалога.Фильтр = "Файлы Excel (*.xlsx;*.xls)|*.xlsx;*.xls";
ПараметрыДиалога.МножественныйВыбор = Ложь;
НачатьПомещениеФайлаНаСервер(Оповещение, , , ПараметрыДиалога, УникальныйИдентификатор);
КонецПроцедуры
&НаКлиенте
Процедура ПослеПомещенияФайла(Результат, ДополнительныеПараметры) Экспорт
Если Результат = Неопределено Тогда
// Пользователь отменил выбор файла в диалоге
Возврат;
КонецЕсли;
// Передаем адрес во временном хранилище на сервер для обработки
ПрочитатьДанныеНаСервере(Результат.Адрес);
ПоказатьОповещениеПользователя("Загрузка данных", , "Файл успешно обработан!");
КонецПроцедуры
После того как файл оказался во временном хранилище, его необходимо прочитать на стороне сервера. Для этого не требуются COM-объекты или внешние библиотеки: объект платформы ТабличныйДокумент штатно умеет считывать форматы XLS и XLSX как в среде Windows, так и в Linux.
Посмотрим на пример серверной процедуры:
&НаСервере
Процедура ПрочитатьДанныеНаСервере(АдресФайлаВоВременномХранилище)
ДвоичныеДанныеФайла = ПолучитьИзВременногоХранилища(АдресФайлаВоВременномХранилище);
ИмяВременногоФайла = ПолучитьИмяВременногоФайла("xlsx");
ДвоичныеДанныеФайла.Записать(ИмяВременногоФайла);
Попытка
ТабличныйДок = Новый ТабличныйДокумент;
ТабличныйДок.Прочитать(ИмяВременногоФайла);
// Удаляем временный файл сразу после прочтения, чтобы не засорять диск
УдалитьФайлы(ИмяВременногоФайла);
Исключение
УдалитьФайлы(ИмяВременногоФайла);
ВызватьИсключение "Ошибка при чтении файла таблицы: " + ОписаниеОшибки();
КонецПопытки;
// Разбираем строки табличного документа
ВсегоСтрок = ТабличныйДок.ВысотаТаблицы;
ВсегоКолонок = ТабличныйДок.ШиринаТаблицы;
Для НомерСтроки = 2 По ВсегоСтрок Цикл
// Считываем значения конкретных ячеек
ЗначениеКолонки1 = ТабличныйДок.Область(НомерСтроки, 1).Текст;
ЗначениеКолонки2 = ТабличныйДок.Область(НомерСтроки, 2).Текст;
// Выполняем создание или поиск объектов конфигурации
// ...
КонецЦикла;
// Очищаем временное хранилище
УдалитьИзВременногоХранилища(АдресФайлаВоВременномХранилище);
КонецПроцедуры
Для обеспечения надежной работы интеграции в сервисе 1С:ГРМ обратите внимание на следующие нюансы:
ФоновыеЗадания.Выполнить, передав туда адрес файла во временном хранилище, и настройте на клиенте обработчик ожидания для проверки статуса задания.ЧтениеCSV происходит существенно быстрее и потребляет в разы меньше оперативной памяти сервера по сравнению с парсингом структуры ТабличныйДокумент.