При переходе на работу в облачные сервисы или при использовании арендованных серверов 1С многие разработчики сталкиваются с тем, что привычный код Новый COMОбъект("Excel.Application") перестает работать. Тонкий клиент, работающий на локальном компьютере, не всегда может корректно взаимодействовать с сервером, на котором исполняется основной программный код. Разберем подробно, почему возникают ошибки доступа к файлам и как реализовать надежный импорт данных из Excel в современных условиях.
Когда мы работаем в тонком клиенте, код может выполняться либо на стороне клиента, либо на стороне сервера. Проанализируем типичную ситуацию: если ваш код помечен директивой &НаКлиенте, 1С пытается найти установленный Microsoft Excel на вашем локальном ПК. Если же код выполняется &НаСервере, то Excel должен быть установлен на сервере провайдера, что в облачных средах встречается редко из-за лицензионных ограничений.
Основные причины ошибок:
Самый правильный и современный подход — это отделение выбора файла от его обработки. Сначала мы выбираем файл на клиенте и помещаем его в специальную область памяти сервера (временное хранилище), а затем обрабатываем его уже на стороне сервера. Рассмотрим, как это реализовать.
Разберем по шагам алгоритм загрузки:
&НаКлиенте
Процедура ИмпортДанных(Команда)
Перем ВыбранноеИмя;
Перем АдресВременногоХранилища;
// Используем стандартный диалог для выбора файла на локальном диске
Если ПоместитьФайл(АдресВременногоХранилища, "", ВыбранноеИмя, Истина, УникальныйИдентификатор) Тогда
// Файл успешно ушел на сервер в хранилище, теперь вызываем серверный код
ОбработатьФайлНаСервере(АдресВременногоХранилища);
КонецЕсли;
КонецПроцедуры
Теперь проанализируем, что происходит на стороне сервера. Мы должны извлечь двоичные данные из хранилища и записать их во временный файл, с которым сможет работать платформа:
&НаСервере
Процедура ОбработатьФайлНаСервере(АдресВременногоХранилища)
// Получаем уникальное имя для временного файла на сервере
ИмяВременногоФайла = ПолучитьИмяВременногоФайла("xlsx");
// Извлекаем данные из облачного хранилища
ДвоичныеДанные = ПолучитьИзВременногоХранилища(АдресВременногоХранилища);
// Записываем данные в файл на диске сервера
ДвоичныеДанные.Записать(ИмяВременногоФайла);
// Далее вызываем процедуру чтения, например, через ТабличныйДокумент
ПрочитатьДанныеИзФайла(ИмяВременногоФайла);
// Не забываем удалять временные файлы после работы
УдалитьФайлы(ИмяВременногоФайла);
КонецПроцедуры
Если на сервере не установлен Microsoft Excel (что обычно и бывает в арендованной 1С), использование Excel.Application невозможно. Однако платформа 1С версии 8.3 умеет открывать файлы .xlsx напрямую с помощью объекта ТабличныйДокумент. Этот метод работает намного быстрее и стабильнее. Для решения этой задачи в автоматическом режиме можно использовать универсальную обработку для импорта данных из Excel.
Посмотрим на пример кода, который считывает данные из файла без участия Excel:
&НаСервере
Процедура ПрочитатьДанныеИзФайла(ПутьКФайлу)
ТабДок = Новый ТабличныйДокумент;
Попытка
// Читаем файл напрямую. Платформа сама поймет формат XLSX
ТабДок.Прочитать(ПутьКФайлу, СпособЧтенияЗначенийТабличногоДокумента.Текст);
Исключение
Сообщить("Ошибка при чтении файла: " + ОписаниеОшибки());
Возврат;
КонецПопытки;
// Проходим по строкам и колонкам табличного документа
КоличествоСтрок = ТабДок.ВысотаТаблицы;
КоличествоКолонок = ТабДок.ШиринаТаблицы;
Для НомерСтроки = 1 По КоличествоСтрок Цикл
Для НомерКолонки = 1 По КоличествоКолонок Цикл
ЗначениеЯчейки = ТабДок.Область(НомерСтроки, НомерКолонки).Текст;
// Обрабатываем полученные данные...
КонецЦикла;
КонецЦикла;
КонецПроцедуры
Важно помнить, что метод Прочитать() объекта ТабличныйДокумент поддерживает форматы .xls, .xlsx и .csv. Это универсальное решение для тонкого клиента.
В некоторых ситуациях, когда структура данных очень жесткая, проще всего договориться о выгрузке из Excel в формат CSV (текст с разделителями). Это снимает все проблемы с версиями Excel и COM-объектами. Для чтения такого файла на сервере мы используем объект ЧтениеТекста. При необходимости можно воспользоваться готовым инструментом для загрузки файлов Excel и CSV в таблицу значений без использования внешних библиотек.
Рассмотрим пример обработки CSV после того, как мы передали его на сервер через временное хранилище:
&НаСервере
Процедура ЧтениеCSV(ПутьНаСервере)
// Используем системную кодировку или Windows-1251
Текст = Новый ЧтениеТекста(ПутьНаСервере, КодировкаТекста.Системная);
СтрокаФайла = Текст.ПрочитатьСтроку();
Пока СтрокаФайла <> Неопределено Цикл
// Разрезаем строку по разделителю (например, точка с запятой)
МассивЗначений = СтрРазделить(СтрокаФайла, ";");
// Обработка колонок
Если МассивЗначений.Количество() > 0 Тогда
Артикул = МассивЗначений[0];
Цена = МассивЗначений[1];
КонецЕсли;
СтрокаФайла = Текст.ПрочитатьСтроку();
КонецЦикла;
Текст.Закрыть();
КонецПроцедуры
Если ваша обработка зарегистрирована в справочнике "Дополнительные отчеты и обработки" и работает в безопасном режиме, попытка записи временного файла может быть заблокирована. Выясним, как разрешить эту операцию. В модуле объекта обработки, в функции СведенияОВнешнейОбработке, необходимо явно запросить разрешение на использование каталога временных файлов.
Проанализируем фрагмент кода регистрации:
ПараметрыРегистрации = ДополнительныеОтчетыИОбработки.СведенияОВнешнейОбработке();
// ... заполнение других параметров ...
Разрешение = РаботаВБезопасномРежиме.РазрешениеНаИспользованиеКаталогаВременныхФайлов(Истина, Истина, "Чтение данных из Excel");
ПараметрыРегистрации.Разрешения.Добавить(Разрешение);
Подводя итог, можно сказать, что использование COM-объектов для Excel — это устаревший путь, который создает массу проблем в тонком клиенте и облачных инфраструктурах. Рассмотрим основные правила для стабильной работы:
ПоместитьФайл() и ВременноеХранилище. Не пытайтесь заставить сервер увидеть ваш "Рабочий стол".ТабличныйДокумент прекрасно справляется с чтением XLSX-файлов без установленного Office.UTF-8 или явно указывайте windows-1251.ПолучитьИмяВременногоФайла) должны удаляться сразу после завершения обработки, чтобы не забивать дисковое пространство облака.Следуя этим методикам, вы обеспечите работу своей обработки в любом режиме — будь то веб-клиент, тонкий клиент или терминальный доступ.