Как обновить отображение поля подчиненного справочника на форме после его изменения в 1С?

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

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

Проанализируем причины такого поведения платформы 1С:Предприятие и разберем эффективные способы автоматического обновления отображения данных.

Выясним причину: почему не срабатывают стандартные события

Чтобы правильно устранить проблему, выясним, как платформа обрабатывает действия пользователя:

  1. Разделение выбора и открытия: Событие ОбработкаВыбора у элемента управления вызывается только тогда, когда значение получено из формы списка или формы выбора через метод ОповеститьОВыборе(). При переходе в уже выбранный элемент через кнопку открытия (лупу) выбора не происходит — открывается форма редактирования объекта, поэтому обработчик ОбработкаВыбора не срабатывает.
  2. Кэширование строкового представления: В клиентском приложении текстовое представление ссылки кэшируется. Изменение наименования объекта в отдельном окне не инвалидирует автоматически кэш в уже открытых родительских формах без соответствующего сигнала.
  3. Ограничения метода Обновить(): Вызов ЭтаФорма.Обновить() выполняет перерисовку элементов интерфейса, но не обращается повторно к базе данных для перечитывания кэшированных представлений ссылок.

Способ 1. Использование механизма оповещений и переприсваивания значения

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

В модуле формы подчиненного справочника в обработчике события записи отправляем оповещение:


Процедура ПослеЗаписи(Отказ)
    Оповестить("ОбновитьГражданство", ЭтотОбъект.Ссылка, ЭтотОбъект);
КонецПроцедуры

В форме владельца (например, справочника физических лиц) определяем процедуру обработки оповещения. Для сброса кэша представления и обновления текста в поле ввода присваиваем реквизиту его же собственное значение:


Процедура ОбработкаОповещения(ИмяСобытия, Параметр, Источник)
    Если ИмяСобытия = "ОбновитьГражданство" Тогда
        Гражданство = Гражданство;
    ИначеЕсли ИмяСобытия = "ОбновитьУдостоверение" Тогда
        Удостоверение = Удостоверение;
    КонецЕсли;
КонецПроцедуры

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

Способ 2. Штатное оповещение об изменении данных через ОповеститьОбИзменении

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

В модуле формы подчиненного элемента в событии ПослеЗаписи вызываем следующий код:


Процедура ПослеЗаписи(Отказ)
    ОповеститьОбИзменении(Ссылка);
КонецПроцедуры

При использовании этого метода нет необходимости вручную перехватывать оповещения в форме владельца и переприсваивать переменные — платформа выполнит сброс кэша представления ссылки автоматически.

Способ 3. Перехват события Открытие элемента формы

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

Для поля ввода назначаем обработчик события Открытие, отключаем стандартную обработку и открываем форму программно:


Процедура ГражданствоОткрытие(Элемент, СтандартнаяОбработка)
    СтандартнаяОбработка = Ложь;
    
    Если ЗначениеЗаполнено(Гражданство) Тогда
        ФормаПодчиненного = Гражданство.ПолучитьФорму();
        ФормаПодчиненного.ОткрытьМодально();
        
        // После закрытия модальной формы принудительно обновляем значение
        Гражданство = Гражданство;
    КонецЕсли;
КонецПроцедуры

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

Способ 4. Оповещение о создании нового подчиненного объекта

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

В модуле подчиненной формы вызываем метод после создания объекта:


Процедура ПослеЗаписи(Отказ)
    Если ЭтоНовый() Тогда
        ОповеститьОЗаписиНовогоОбъекта(Ссылка);
    КонецЕсли;
КонецПроцедуры

В форме владельца перехватываем стандартное событие ОбработкаЗаписиНовогоОбъекта:


Процедура ОбработкаЗаписиНовогоОбъекта(Объект)
    Если ТипЗнч(Объект) = Тип("СправочникСсылка.Гражданство") Тогда
        Гражданство = Объект;
    КонецЕсли;
КонецПроцедуры

Таким образом, мы рассмотрели различные механизмы синхронизации данных между формами. Для типовых задач редактирования существующих данных наиболее лаконичным решением является метод ОповеститьОбИзменении() либо механизм Оповестить() с переприсваиванием реквизита в ОбработкаОповещения.

← На главную