Как передать массив структур или таблицу значений между формами через временное хранилище в 1С

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

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

Разберем подробно, как правильно помещать коллекции во временное хранилище, управлять временем их жизни и асинхронно передавать адрес между формами без использования устаревших модальных вызовов.

Обязательно ли преобразовывать таблицу значений в массив структур

Рассмотрим распространенное заблуждение начинающих разработчиков. Часто таблицу значений пытаются вручную свернуть в массив структур, полагая, что временное хранилище не поддерживает таблицы.

Посмотрим на пример такого ручного преобразования:


// Избыточное преобразование перед сохранением во временное хранилище
рМассив = Новый Массив;
Для Каждого Строка Из мТаблица Цикл
    Запись = Новый Структура;
    Запись.Вставить("Реквизиты", Строка.Реквизиты);
    Запись.Вставить("Номер", Строка.Номер);
    рМассив.Добавить(Запись);
КонецЦикла;

Важно понимать: ограничение на использование типа ТаблицаЗначений действует исключительно на стороне тонкого и веб-клиента. В контексте сервера во временное хранилище можно напрямую передавать полноценную таблицу значений: ПоместитьВоВременноеХранилище(мТаблица, УникальныйИдентификатор). Преобразовывать её в массив структур не требуется, если сама таблица не возвращается непосредственно в клиентский контекст.

Управление временем жизни данных во временном хранилище

Проанализируем работу функции ПоместитьВоВременноеХранилище(). У нее есть два варианта вызова:

  1. Без указания второго параметра: Адрес = ПоместитьВоВременноеХранилище(Данные); — в этом случае данные привязываются к текущему серверному контексту и удаляются сразу после завершения текущего вызова с клиента. Передать такой адрес в другую форму или использовать в следующем серверном вызове не удастся.
  2. С указанием уникального идентификатора формы: Адрес = ПоместитьВоВременноеХранилище(Данные, УникальныйИдентификатор); — данные связываются с сеансом жизни конкретной формы и будут доступны до тех пор, пока эта форма остается открытой, либо пока данные не будут удалены принудительно.

После считывания и обработки данных на сервере хорошей практикой является освобождение оперативной памяти вызовом УдалитьИзВременногоХранилища(Адрес).

Пошаговая схема передачи данных из вспомогательной формы в основную

Разберем по шагам типовой асинхронный сценарий: из основной формы открывается форма отчета/подбора, формирует данные на сервере, помещает их во временное хранилище и возвращает только короткую строку адреса в основную форму.

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

Альтернативный вариант: передача данных в открываемую форму

Если задача противоположная — передать готовую таблицу значений из текущей формы во вновь создаваемую форму:

  1. В текущей форме на сервере вызываем ПоместитьВоВременноеХранилище(Таблица, ЭтаФорма.УникальныйИдентификатор).
  2. Полученный адрес передаем через структуру параметров функции ОткрытьФорму(): ПараметрыОткрытия.Вставить("АдресДанных", Адрес).
  3. В открываемой форме в обработчике ПриСозданииНаСервере(Отказ, СтандартнаяОбработка) извлекаем данные: Таблица = ПолучитьИзВременногоХранилища(Параметры.АдресДанных).

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

← На главную