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