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