Как отследить закрытие формы элемента из формы списка и обновить данные?

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

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

Рассмотрим по шагам, как настроить такую взаимосвязь между формой списка и формой элемента.

Решение через механизм оповещений

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

Разберем процесс по шагам.

  1. Перехват стандартного открытия формы элемента

    Сначала нам нужно отменить стандартное поведение платформы при выборе элемента в списке (по двойному клику или нажатию Enter). Для этого в форме списка найдем основной элемент-список (обычно он так и называется "Список") и создадим для него обработчик события Выбор. Если в вашей задаче также требуется реализация флажка в динамическом списке, это потребует отдельной настройки, но в данном контексте мы сосредоточимся на перехвате открытия.

    В коде обработчика мы установим параметр СтандартнаяОбработка в значение Ложь. Это говорит платформе, что мы сами позаботимся об открытии формы.

  2. Создание процедуры-обработчика оповещения

    В модуле формы списка нужно создать процедуру, которая будет вызвана после закрытия формы элемента. У этой процедуры есть несколько требований:

    • Она должна быть клиентской (&НаКлиенте).
    • Она должна быть экспортной (Экспорт).
    • Она может принимать параметры, которые передаст закрываемая форма.

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

    
    &НаКлиенте
    Процедура ПриЗакрытииЭлементаСправочника(Результат, ДопПараметры) Экспорт
        // Здесь будет
     код, который выполнится после закрытия формы элемента.
        // Например, можно принудительно обновить список:
        Элементы.Список.Обновить();
        
        // Или выполнить более сложную логику, например, обновить условное оформление
        // на сервере, если это необходимо.
    КонецПроцедуры
    
  3. Открытие формы с передачей оповещения

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

Посмотрим на итоговый код в модуле формы списка:


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

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

Важный момент: Конструктор Новый ОписаниеОповещения("ИмяПроцедуры") без указания второго параметра (контекста) может не работать на некоторых версиях платформы. Поэтому всегда рекомендуется явно указывать ЭтотОбъект в качестве второго параметра, чтобы платформа точно знала, где искать процедуру-обработчик.

Дополнительные вопросы: обновление списка (аналог F5)

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

В управляемых формах нет прямого аналога ОбновлениеОтображения(), так как платформа автоматически обновляет интерфейс при изменении данных формы. Однако, если нужно принудительно перезапросить данные для динамического списка (что и делает клавиша F5), используется метод Обновить() самого элемента формы.

Пример принудительного обновления:


&НаКлиенте
Процедура ОбновитьСписокНажатиемКнопки(Команда)
    Элементы.Список.Обновить();
КонецПроцедуры

При вызове этого метода (или при нажатии F5) платформа инициирует повторное получение данных для списка на сервере. Это, в свою очередь, вызывает серверные события динамического списка, такие как ПриПолученииДанныхНаСервере, где можно дополнительно обработать данные или модифицировать запрос.

Как передать данные из дочерней формы в родительской?

Механизм оповещений позволяет не просто отловить факт закрытия, но и передать из дочерней формы какой-либо результат. Для этого в форме элемента перед закрытием нужно вызвать метод ОповеститьОЗакрытии().

Пример в модуле формы элемента:


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

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

← На главную