При адаптации внешних обработок и расширений для работы в облачном сервисе 1С:Предприятие 8 через Интернет (1С:Фреш) разработчики часто сталкиваются с ошибкой при попытке создания COM-соединения с Microsoft Excel. В локальной файловой или клиент-серверной базе под управлением тонкого клиента Windows код выполняется штатно, но в браузере при выполнении команды возникает исключение.
Рассмотрим типовой фрагмент кода, приводящий к ошибке:
&НаКлиенте
Процедура ВвестиДокументы(Команда)
Попытка
Excel = Новый COMОбъект("Excel.Application");
Исключение
Сообщить("Не удалось инициализировать Excel");
Возврат;
КонецПопытки;
КонецПроцедуры
Выясним причину такого поведения платформы и разберем архитектурно правильные способы загрузки данных из таблиц Excel, полностью совместимые с требованиями облачного сервиса.
Проанализируем технические ограничения, из-за которых классическая инициализация COMОбъект("Excel.Application") не может быть выполнена:
БезопасныйРежим = Истина. В безопасном режиме платформой принудительно заблокированы обращения к COM-объектам, запуск внешних исполняемых файлов через ЗапуститьПриложение и прямой доступ к системным ресурсам.Таким образом, прямое чтение файлов через COM в веб-клиенте невозможно. Для работы в облаке необходимо перестроить логику: передавать файл с клиентского компьютера на сервер через временное хранилище и разбирать его кроссплатформенными средствами платформы 1С.
Начиная с версии 8.3.6 платформа 1С:Предприятие обладает встроенной поддержкой чтения файлов форматов .xls и .xlsx напрямую в объект ТабличныйДокумент. Этот механизм не требует установленного офисного пакета, работает на серверах под управлением Linux и полностью совместим с безопасным режимом 1С:Фреш.
Разберем по шагам реализацию загрузки файла:
ТабличныйДокумент с помощью метода Прочитать().Посмотрим на пример клиентского кода для интерактивного выбора и передачи файла:
&НаКлиенте
Процедура ЗагрузитьФайлExcel(Команда)
ПараметрыДиалога = Новый ПараметрыДиалогаПомещенияФайлов;
ПараметрыДиалога.Заголовок = "Выберите файл Excel для загрузки";
ПараметрыДиалога.Фильтр = "Файлы Excel (*.xlsx; *.xls)|*.xlsx;*.xls";
Оповещение = Новый ОписаниеОповещения("ПослеВыбораФайла", ЭтотОбъект);
НачатьПомещениеФайлаНаСервер(Оповещение, , , ПараметрыДиалога, УникальныйИдентификатор);
КонецПроцедуры
&НаКлиенте
Процедура ПослеВыбораФайла(Результат, ДополнительныеПараметры) Экспорт
Если Результат = Неопределено Тогда
Возврат;
КонецЕсли;
ПрочитатьФайлНаСервере(Результат.Адрес);
ПоказатьОповещениеПользователя("Загрузка", , "Данные успешно загружены!");
КонецПроцедуры
Теперь рассмотрим серверную процедуру, которая принимает адрес временного хранилища и считывает данные:
&НаСервере
Процедура ПрочитатьФайлНаСервере(АдресВХранилище)
ДвоичныеДанные = ПолучитьИзВременногоХранилища(АдресВХранилище);
ИмяВременногоФайла = ПолучитьИмяВременногоФайла("xlsx");
Попытка
ДвоичныеДанные.Записать(ИмяВременногоФайла);
ТабДок = Новый ТабличныйДокумент;
// Чтение файла средствами платформы без COM-объектов
ТабДок.Прочитать(ИмяВременногоФайла, СпособЧтенияЗначенийТабличногоДокумента.Значение);
УдалитьФайлы(ИмяВременногоФайла);
Исключение
УдалитьФайлы(ИмяВременногоФайла);
ВызватьИсключение "Ошибка при обработке файла: " + ОписаниеОшибки();
КонецПопытки;
// Обход полученных данных
ВсегоСтрок = ТабДок.ВысотаТаблицы;
ВсегоКолонок = ТабДок.ШиринаТаблицы;
Для НомерСтроки = 2 По ВсегоСтрок Цикл
Артикул = ТабДок.ПолучитьОбласть(НомерСтроки, 1).Текст;
Количество = ТабДок.ПолучитьОбласть(НомерСтроки, 2).ТекущаяОбласть.Значение;
// Обработка полученных строк и запись в базу
КонецЦикла;
УдалитьИзВременногоХранилища(АдресВХранилище);
КонецПроцедуры
Параметр СпособЧтенияЗначенийТабличногоДокумента.Значение позволяет получать в ячейках исходные типы (числа, даты), а не только строковые представления, что упрощает дальнейшую валидацию данных.
В зависимости от архитектуры задачи и формата исходных документов можно использовать и другие подходы, поддерживаемые в 1С:Фреш:
.xlsx является стандартным ZIP-архивом, содержащим XML-структуры. Платформа 1С позволяет открыть его с помощью объектов ЧтениеZipФайла и ЧтениеXML, после чего прочитать узлы xl/sharedStrings.xml и данные листов. Этот метод требует написания собственного парсера, но работает максимально быстро при больших объемах данных и не потребляет лишнюю оперативную память.ЧтениеТекста, который гарантирует максимальную производительность без необходимости разбора бинарных таблиц.Важный вывод: отказ от технологии COM в пользу платформенных методов (ТабличныйДокумент.Прочитать или механизмов БСП) обеспечивает полную универсальность кода: обработка будет одинаково стабильно работать в веб-клиенте, тонком клиенте Windows, macOS и Linux, а также успешно пройдет аудит для публикации в сервисе 1С:Фреш.