Как передать несколько массивов файлов с клиента на сервер в 1С:Предприятие 8.3

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

В процессе разработки на платформе 1С:Предприятие 8.3 часто возникает задача передачи файлов (например, фотографий или документов) с локального компьютера пользователя на сервер для дальнейшей обработки. Особую сложность для начинающих разработчиков представляет ситуация, когда файлы распределены по разным категориям (массивам) и на сервере важно сохранить эту идентификацию. В данной статье мы подробно разберем, как правильно организовать этот процесс, рассмотрим работу с временным хранилищем и современные асинхронные методы платформы.

Постановка задачи и анализ проблемы

Рассмотрим ситуацию: на стороне клиента у нас есть два списка файлов (например, «Основные фото» и «Фото брака»). Нам необходимо передать их в одну серверную процедуру так, чтобы сервер понимал, какой файл к какой категории относится. Обычная передача путей к файлам (строк вида "C:\MyPhotos\img1.jpg") не сработает, так как серверный код исполняется в контексте сервера, у которого нет доступа к файловой системе клиентского компьютера.

Для решения этой задачи в 1С используется механизм Временного хранилища. Основная логика заключается в следующем: мы считываем файл в объект ДвоичныеДанные на клиенте, помещаем его в специальное хранилище на сервере, получаем уникальный адрес и передаем этот адрес (строку) в серверную процедуру.

Реализация через временное хранилище (классический метод)

Проанализируем наиболее понятный и надежный способ реализации этой задачи, который подходит для тонкого и толстого клиента. Разберем код по шагам.

Шаг 1. Подготовка данных на клиенте

Нам необходимо обойти наши массивы (или таблицы значений), прочитать каждый файл и сохранить его адрес. Рассмотрим пример кода:


&НаКлиенте
Процедура ПередатьФайлыНаСервер()
    
    // Создаем массивы для хранения адресов во временном хранилище
    МассивАдресовФото = Новый Массив;
    МассивАдресовБрак = Новый Массив;
    
    // Обрабатываем первую категорию (например, из таблицы Объект.тФото)
    Для Каждого Стр Из Объект.тФото Цикл
        ПутьКФайлу = Стр.Путь;
        // Читаем файл в двоичные данные
        ДД = Новый ДвоичныеДанные(ПутьКФайлу);
        // Помещаем во временное хранилище. 
        // Использование УникальныйИдентификатор формы гарантирует, 
        // что данные будут жить, пока открыта форма.
        Адрес = ПоместитьВоВременноеХранилище(ДД, ЭтаФорма.УникальныйИдентификатор);
        МассивАдресовФото.Добавить(Адрес);
    КонецЦикла;
    
    // Обрабатываем вторую категорию (например, из таблицы Объект.тФотоБрак)
    Для Каждого Стр Из Объект.тФотоБрак Цикл
        ПутьКФайлу = Стр.Путь;
        ДД = Новый ДвоичныеДанные(ПутьКФайлу);
        Адрес = ПоместитьВоВременноеХранилище(ДД, ЭтаФорма.УникальныйИдентификатор);
        МассивАдресовБрак.Добавить(Адрес);
    КонецЦикла;
    
    // Вызываем серверную процедуру, передавая массивы строк-адресов
    ОбработатьФайлыНаСервере(МассивАдресовФото, МассивАдресовБрак);
    
КонецПроцедуры

Шаг 2. Обработка данных на сервере

На сервере мы получаем массивы, содержащие адреса. Теперь нам нужно извлечь двоичные данные и, например, сохранить их во временные файлы для обработки внешними средствами (например, для вставки в Word или обработки картинки).


&НаСервере
Процедура ОбработатьФайлыНаСервере(МассивФото, МассивБрак)
    
    // Обработка первой группы
    Для Каждого Адрес Из МассивФото Цикл
        // Извлекаем двоичные данные из хранилища
        ДанныеФайла = ПолучитьИзВременногоХранилища(Адрес);
        Если ДанныеФайла <> Неопределено Тогда
            // Создаем путь для временного файла на сервере
            ИмяФайла = ПолучитьИмяВременногоФайла("jpg");
            // Записываем данные на диск сервера
            ДанныеФайла.Записать(ИмяФайла);
            
            // Здесь выполняем нужные действия с файлом ИмяФайла...
        КонецЕсли;
    КонецЦикла;
    
    // Аналогично обрабатываем вторую группу (МассивБрак)
    // ...
    
КонецПроцедуры

Оптимизация: Использование структур для идентификации

Если категорий файлов становится много, передавать большое количество массивов неудобно. Выясним, как сделать код более универсальным. Вместо нескольких массивов мы можем использовать один массив структур. Это позволит передавать не только адрес файла, но и его имя, тип или любые дополнительные метаданные.


// На клиенте
СтруктураФайла = Новый Структура;
СтруктураФайла.Вставить("Адрес", АдресВХранище);
СтруктураФайла.Вставить("Категория", "Брак");
СтруктураФайла.Вставить("Имя", "photo_01.jpg");
ОбщийМассив.Добавить(СтруктураФайла);

Такой подход позволяет в одном цикле на сервере через Если ... Тогда или Выбор Когда распределять файлы по нужным таблицам или алгоритмам обработки.

Современный подход: НачатьПомещениеФайловНаСервер

Начиная с версии платформы 8.3.15, разработчикам доступен более мощный инструмент — метод НачатьПомещениеФайловНаСервер. Рассмотрим подробнее, почему он предпочтительнее для новых разработок:

  1. Асинхронность: Этот метод не блокирует интерфейс пользователя при загрузке больших объемов данных.
  2. Работа в веб-клиенте: В отличие от Новый ДвоичныеДанные(Путь), который требует доступа к файловой системе (что запрещено в браузерах из соображений безопасности), асинхронные методы работы с файлами корректно работают в веб-клиенте через диалоги выбора.
  3. Оптимизация передачи: Платформа сама оптимизирует процесс упаковки и передачи данных на сервер.

При использовании этого метода мы сначала подготавливаем массив объектов типа ОписаниеПередаваемогоФайла, а затем вызываем помещение. Платформа вернет нам массив объектов ОписаниеПомещенногоФайла, в которых уже будут содержаться готовые адреса во временном хранилище.

Важные замечания по безопасности и памяти

Проанализируем критические моменты, которые часто упускают при реализации подобных механизмов:

1. Ограничения веб-клиента. Помните, что прямой доступ к файлу по пути Новый ДвоичныеДанные("C:\File.jpg") в браузере выдаст ошибку. Для веб-клиента используйте только интерактивный выбор файлов пользователем или механизм перетаскивания (Drag-and-drop).

2. Очистка памяти. Объект ДвоичныеДанные занимает объем оперативной памяти, равный размеру файла. Если вы передаете 100 фотографий по 10 Мб каждая, клиентское приложение может потребовать более 1 Гб оперативной памяти. Старайтесь не хранить двоичные данные в переменных долго — сразу после ПоместитьВоВременноеХранилище присваивайте переменной значение Неопределено.

3. Расширения файлов. Метод ПолучитьИмяВременногоФайла() генерирует уникальный путь в системной временной папке. Не забывайте указывать нужное расширение (например, "jpg" или "pdf"), если внешние программы, которыми вы планируете открывать файл на сервере, чувствительны к расширению файла.

4. Жизненный цикл хранилища. Если вы передаете ЭтаФорма.УникальныйИдентификатор в качестве второго параметра функции ПоместитьВоВременноеХранилище, данные будут удалены автоматически при закрытии формы. Если же идентификатор не указать, данные могут удалиться при первом же переходе с сервера на клиент, что приведет к ошибке «Объект не найден» при попытке прочитать их во второй раз.

Резюме

Мы рассмотрели основной механизм передачи данных между контекстами в 1С. Основной принцип — "Файлы на клиенте -> Двоичные данные -> Временное хранилище -> Адрес -> Сервер -> Получение из хранилища". Использование массивов или структур для передачи этих адресов позволяет гибко управлять большими объемами информации и сохранять логическую связь между файлами и данными в информационной базе.

← На главную