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

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

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

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

Почему нельзя передать ТаблицуЗначений напрямую на клиенте

В управляемом приложении клиентский контекст работает с данными формы через специальные типы, такие как ДанныеФормыКоллекция. Сам объект ТаблицаЗначений недоступен в клиентских процедурах. Попытка передать таблицу напрямую между формами на клиенте приводит к ошибке или невозврату данных. Чтобы обойти это ограничение, используем два основных подхода:

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

Передача и возврат таблицы через временное хранилище

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

  1. В вызывающей форме на сервере выгружаем данные или формируем объект ТаблицаЗначений.
  2. Помещаем таблицу во временное хранилище методом ПоместитьВоВременноеХранилище() и получаем адрес.
  3. Передаем этот адрес в параметрах при открытии формы с помощью функции ОткрытьФорму().
  4. В открытой форме считываем данные из хранилища и заполняем реквизит формы типа ДанныеФормыКоллекция методом ЗначениеВДанныеФормы().
  5. После редактирования помещаем измененную коллекцию обратно в хранилище через ДанныеФормыВЗначение() и ПоместитьВоВременноеХранилище().
  6. Передаем оповещение о закрытии и забираем обновленные данные в основной форме.

Посмотрим на пример кода в вызывающей форме:


&НаКлиенте
Процедура ОткрытьФормуРедактирования(Команда)
    
    // Помещаем ТЗ во временное хранилище на сервере
    АдресХранилища = ПоместитьТЗВХранилище();
    
    // Формируем параметры для открытия формы
    ПараметрыОткрытия = Новый Структура;
    ПараметрыОткрытия.Вставить("АдресТаблицы", АдресХранилища);
    
    // Описание оповещения для асинхронной обработки результата
    ОповещениеЗавершения = Новый ОписаниеОповещения("ПослеЗакрытияФормы", ЭтаФорма);
    
    ОткрытьФорму("ОбщаяФорма.ФормаПечатиРаспоряжений", ПараметрыОткрытия, ЭтаФорма, , , , ОповещениеЗавершения);

КонецПроцедуры

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

При закрытии общей формы или выборе значения вызывается обработчик оповещения в исходной форме:


&НаКлиенте
Процедура ПослеЗакрытияФормы(РезультатЗакрытия, ДополнительныеПараметры) ОбработкаОповещения
    
    Если РезультатЗакрытия <> Неопределено Тогда
        // Считываем обновленные данные из хранилища на сервере
        ПрочитатьТЗИзХранилища(РезультатЗакрытия);
    КонецЕсли;

КонецПроцедуры

Отказ от модальности и работа с событием ОповеститьОВыборе

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

Для возврата результата из открытой формы без использования модальности применяется метод ОповеститьОВыборе() или закрытие формы с передачей параметра в метод Закрыть().

Пример кода в открываемой общей форме:


&НаКлиенте
Процедура ЗавершитьВыбор(Команда)
    
    // Сохраняем измененные данные формы в хранилище на сервере
    АдресРезультата = СохранитьТЗВХранилище();
    
    // Закрываем форму с передачей адреса хранилища обратно
    Закрыть(АдресРезультата);

КонецПроцедуры

Паттерн вызова формы проверки перед записью объекта

Распространенная задача — открыть форму (например, для проверки дублей контрагента) в событии ПередЗаписью на клиенте. В асинхронном режиме работы мы не можем приостановить выполнение события ПередЗаписью и дождаться ответа пользователя, так как модальность отключена.

Проанализируем стандартный паттерн решения этой проблемы с использованием флага-переменной:

  1. Объявляем переменную модуля формы на клиенте ПроверкаПроведена со значением Ложь.
  2. В обработчике ПередЗаписью проверяем значение этой переменной.
  3. Если проверка не проходила, отменяем запись (Отказ = Истина) и открываем форму проверки с передачей ОписаниеОповещения.
  4. В процедуре обработки результата после согласия пользователя устанавливаем ПроверкаПроведена = Истина и программно вызываем метод Записать().
  5. При повторном входе в ПередЗаписью флаг равен Истина, запись успешно завершается.

Рассмотрим программную реализацию данного паттерна:


&НаКлиенте
Перем ПроверкаПроведена;

&НаКлиенте
Процедура ПередЗаписью(Отказ, ПараметрыЗаписи)
    
    Если Не ПроверкаПроведена Тогда
        
        // Отменяем текущее сохранение
        Отказ = Истина;
        
        // Открываем форму проверки дублей
        Оповещение = Новый ОписаниеОповещения("ПослеПроверкиДублей", ЭтаФорма, ПараметрыЗаписи);
        ОткрытьФорму("ОбщаяФорма.ПроверкаДублей", , ЭтаФорма, , , , Оповещение);
        
    КонецЕсли;

КонецПроцедуры

&НаКлиенте
Процедура ПослеПроверкиДублей(Результат, ПараметрыЗаписи) ОбработкаОповещения
    
    Если Результат = КодВозвратаДиалога.Да Тогда
        // Фиксируем выполнение проверки и заново запускаем запись
        ПроверкаПроведена = Истина;
        Записать(ПараметрыЗаписи);
    КонецЕсли;

КонецПроцедуры

Использование временного хранилища для передачи сложных структур данных и асинхронный подход с объявлением ОписаниеОповещения позволяют полностью отказаться от модальных окон, обеспечивая стабильную работу конфигурации во всех типах клиентов 1С.

← На главную