Разработка расширений для облачных сервисов, таких как 1С:Фреш, накладывает на программиста ряд специфических ограничений. Главное из них — работа в безопасном режиме. В этой статье мы подробно разберем, как реализовать загрузку CSV-файла, не нарушая правил изоляции данных, и как успешно пройти аудит безопасности.
Представим ситуацию: пользователю необходимо загрузить данные из CSV-файла (например, выгрузку из интернет-магазина) в конфигурацию «1С:Бухгалтерия предприятия 3.0», работающую в облаке. Прямой доступ к файловой системе сервера в 1С:Фреш запрещен. Мы не можем использовать Excel.Application или сторонние библиотеки (DLL). Нам предстоит реализовать механизм, который работает исключительно средствами встроенного языка 1С и механизмов БСП (Библиотеки стандартных подсистем).
Поскольку сервер не имеет доступа к локальному диску пользователя, первым делом нам нужно поместить файл во временное хранилище. Для этого в современных управляемых формах рекомендуется использовать асинхронные методы. Разберем по шагам, как это сделать.
На стороне клиента мы вызываем диалог выбора файла и помещаем его в хранилище. Рассмотрим пример кода:
&НаКлиенте
Асинхрон Процедура ЗагрузитьФайл(Команда)
ПараметрыЗагрузки = Новый ПараметрыПомещенияФайла;
Результат = Ждать НачатьПомещениеФайлаНаСервер(,,, ПараметрыЗагрузки, УникальныйИдентификатор);
Если Результат <> Неопределено Тогда
ОбработатьФайлНаСервере(Результат.Адрес);
КонецЕсли;
КонецПроцедуры
В данном фрагменте мы используем метод НачатьПомещениеФайлаНаСервер, который возвращает структуру с адресом во временном хранилище. Это легитимный и безопасный способ передачи данных в облачную инфраструктуру.
После того как файл оказался на сервере в виде двоичных данных, нам нужно его прочитать. Однако объект ЧтениеТекста чаще всего требует наличия физического файла на диске сервера. Здесь кроется важный нюанс: аудиторы 1С:Фреш крайне строго следят за чистотой временных папок. Если ваше расширение оставляет «мусор» на сервере, оно не пройдет проверку.
Проанализируем правильную структуру серверного метода с использованием конструкции Попытка...Исключение...КонецПопытки. Это гарантирует удаление файла даже в случае возникновения ошибки при парсинге.
&НаСервере
Процедура ОбработатьФайлНаСервере(АдресХранилища)
// Получаем двоичные данные из хранилища
ДвоичныеДанные = ПолучитьИзВременногоХранилища(АдресХранилища);
// Создаем временное имя файла на сервере
ИмяВременногоФайла = ПолучитьИмяВременногоФайла("csv");
Попытка
// Записываем данные во временный файл для чтения
ДвоичныеДанные.Записать(ИмяВременногоФайла);
// Открываем файл для чтения. Важно указать кодировку!
Чтение = Новый ЧтениеТекста(ИмяВременногоФайла, КодировкаТекста.UTF8);
СтрокаФайла = Чтение.ПрочитатьСтроку();
Пока СтрокаФайла <> Неопределено Цикл
// Логика разбора строки CSV
ОбработатьСтрокуCSV(СтрокаФайла);
СтрокаФайла = Чтение.ПрочитатьСтроку();
КонецЦикла;
Чтение.Закрыть();
Исключение
// В случае ошибки записываем лог или информируем пользователя
ЗаписьЖурналаРегистрации("ЗагрузкаCSV", УровеньЖурналаРегистрации.Ошибка,,, ОписаниеОшибки());
ВызватьИсключение;
КонецПопытки;
// Обязательная очистка временных файлов!
Попытка
УдалитьФайлы(ИмяВременногоФайла);
Исключение
// Если файл занят, логируем, но не прерываем работу
КонецПопытки;
КонецПроцедуры
Разберем ситуацию с разделителями. Формат CSV коварен тем, что в русской локализации в качестве разделителя часто используется точка с запятой (;), а в международной — запятая (,). Кроме того, значения могут быть заключены в кавычки, внутри которых могут находиться сами разделители.
Для простых файлов можно использовать метод БСП СтрРазделить, но для надежного решения лучше использовать построчное чтение через объект ЧтениеТекста. Выясним причину популярности ЧтениеТекста: этот объект позволяет работать с файлом в потоковом режиме, что критически важно для облака, так как потребление оперативной памяти сеансом во Фреше ограничено.
Рассмотрим пример функции разбора строки с учетом кавычек:
&НаСервере
Функция РазобратьСтрокуCSV(Знач СтрокаТекста, Разделитель = ";")
Результат = Новый Массив;
// Используем встроенную функцию БСП, если она доступна в конфигурации
Результат = ОбщегоНазначенияКлиентСервер.РазложитьСтрокуВМассивСубстрок(СтрокаТекста, Разделитель);
Возврат Результат;
КонецФункции
Если же данные содержат сложные переносы строк внутри ячеек, рекомендуется использовать специализированные алгоритмы перебора символов, чтобы корректно определять границы полей.
ЧтениеТекста всегда явно указывайте кодировку. Часто файлы в формате UTF-8 содержат метку BOM (Byte Order Mark) в самом начале. Платформа 1С обычно корректно обрабатывает BOM автоматически, но если вы видите странные символы в первой колонке первой строки — проверьте именно этот момент.Чтение.Прочитать(). Если пользователь загрузит файл объемом 50 Мб, ваш сеанс во Фреше может быть принудительно завершен из-за превышения лимитов памяти. Используйте только ПрочитатьСтроку().Истина. При загрузке в "Магазин расширений" Фреша код будет проходить автоматизированный и ручной аудит. Наличие прямых обращений к путям типа C:\Temp гарантированно приведет к отклонению публикации.Таким образом, мы выяснили, что загрузка CSV во Фреш — это задача, требующая дисциплины в работе с ресурсами сервера. Использование временного хранилища, потокового чтения и гарантированного удаления временных файлов через блок Попытка позволяет создать надежное и безопасное расширение.