К статье
Практический материал

Разработка и Конфигурация · 12 мин

Как обновить форму из другой формы в 1С

Как обновить форму из другой формы в 1С: Оповестить, ОповеститьОбИзменении, ОбработкаОповещения, обновление списков и форм объектов. Примеры кода на встроенном языке.

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

Выбор способа зависит от того, как связаны формы: открыта ли вторая форма из первой, редактируется ли объект базы данных или просто нужно передать произвольное событие. Неправильный выбор приводит либо к лишним серверным вызовам, либо к ситуации, когда форма вообще не реагирует на изменения.

Ниже разобраны все основные механизмы с примерами кода на встроенном языке, условиями их применения и типичными ошибками, которые встречаются при реализации.

Какие механизмы обновления форм существуют в 1С

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

Дополнительно существует механизм обработчика ОбработкаЗаписиНового, который срабатывает в форме списка, когда из него открыли форму нового элемента и тот был записан. Это частный случай, но он часто решает задачу без единой строки дополнительного кода.

Сравнение способов обновления

Оповестить()

Универсальный механизм для произвольных событий. Требует явного обработчика ОбработкаОповещения в целевой форме.

ОповеститьОбИзменении()

Подходит, когда изменён объект БД. Платформа сама обновляет связанные формы и стандартные списки.

Обращение через ВладелецФормы

Прямой вызов экспортной процедуры формы-источника. Работает только если форма открыта из целевой.

ОбработкаЗаписиНового

Встроенное событие формы списка при записи нового элемента. Не требует кода в форме элемента.

Обновление через Оповестить и ОбработкаОповещения

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

Пример кода в форме-источнике (например, после записи данных):

&НаКлиенте

Процедура ПослеЗаписи(ПараметрыЗаписи)

Оповестить("ИзмененыДанныеКонтрагента", Объект.Ссылка, ЭтотОбъект);

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

Пример обработчика в целевой форме:

&НаКлиенте

Процедура ОбработкаОповещения(ИмяСобытия, Параметр, Источник)

Если ИмяСобытия = "ИзмененыДанныеКонтрагента" Тогда

Элементы.Список.Обновить();

КонецЕсли;

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

Обратите внимание на параметр Источник: если передать туда саму форму (ЭтотОбъект), то в обработчике можно отфильтровать собственные оповещения, чтобы форма-источник не реагировала на своё же событие. Имя события должно быть уникальным в рамках конфигурации — принято включать в него сущность, например «Запись_Номенклатура».

Порядок настройки оповещения
  1. 1
    В форме-источнике после изменения данных вызовите Оповестить() с уникальным именем события.
  2. 2
    В целевой форме создайте обработчик ОбработкаОповещения.
  3. 3
    Внутри обработчика проверьте ИмяСобытия через Если.
  4. 4
    Выполните обновление: Элементы.Список.Обновить() или Прочитать() для формы объекта.
  5. 5
    Проверьте, что форма-источник не реагирует на собственное оповещение.

Обновление через ОповеститьОбИзменении

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

&НаКлиенте

Процедура КомандаИзменитьСтатус(Команда)

ИзменитьСтатусНаСервере(Объект.Ссылка);

ОповеститьОбИзменении(Объект.Ссылка);

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

Важное ограничение: ОповеститьОбИзменении работает с типами ссылок и ключами записей регистров. Если вам нужно передать произвольные данные (структуру, строку, несколько параметров), этот метод не подходит — используйте Оповестить. Также учтите, что автоматическое обновление формы объекта при этом событии означает перечитывание данных из базы: несохранённые изменения, введённые пользователем в другой открытой форме того же объекта, могут быть потеряны или вызвать конфликт блокировок.

Обновление формы-владельца при закрытии подчинённой

Частый сценарий: из формы списка открывается форма подбора или вспомогательная форма, и после её закрытия список должен обновиться или получить выбранные данные. Здесь вместо широковещательных оповещений правильнее использовать ОписаниеОповещения — механизм обратного вызова при открытии формы.

&НаКлиенте

Процедура ОткрытьПодбор(Команда)

Оповещение = Новый ОписаниеОповещения("ПослеЗакрытияПодбора", ЭтотОбъект);

ОткрытьФорму("Справочник.Номенклатура.Форма.ФормаПодбора", , ЭтотОбъект, , , , Оповещение);

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

&НаКлиенте

Процедура ПослеЗакрытияПодбора(Результат, ДопПараметры) Экспорт

Если Результат <> Неопределено Тогда

// обработка результата и обновление данных формы

КонецЕсли;

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

Этот подход точечный: обновляется только та форма, которая открыла подчинённую, и только когда та реально закрылась с результатом. Лишних серверных вызовов и обновлений чужих форм не происходит. Если же подчинённая форма должна обновлять владельца многократно в процессе работы, используйте ОповеститьОВыборе или обращение к экспортным процедурам через свойство ВладелецФормы.

Как обновить динамический список и форму объекта

Для динамического списка в обработчике оповещения достаточно вызвать Элементы.ИмяСписка.Обновить(). Это клиентский метод, который заставляет список перечитать текущую порцию данных. Если список построен на произвольном запросе с временными таблицами, обновление может не сработать — тогда нужно пересоздать данные на сервере и переустановить параметры запроса.

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

&НаКлиенте

Процедура ОбработкаОповещения(ИмяСобытия, Параметр, Источник)

Если ИмяСобытия = "ПересчитаныИтогиДокумента"

И Параметр = Объект.Ссылка

И Не Модифицированность Тогда

Прочитать();

КонецЕсли;

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

Проверка Модифицированность защищает от потери введённых пользователем данных. Если форма модифицирована, можно показать пользователю вопрос или просто пропустить обновление — он увидит актуальные данные при следующем открытии.

Типичные ошибки и ограничения

Самая распространённая ошибка — обработчик ОбработкаОповещения без проверки имени события. Форма начинает реагировать на все оповещения системы, включая стандартные события записи объектов, что приводит к лишним обновлениям и падению производительности. Всегда начинайте обработчик с проверки ИмяСобытия.

Вторая частая проблема — попытка обратиться к элементам формы, которая уже закрыта, через сохранённую ссылку на неё. В управляемом приложении форма после закрытия недоступна, и обращение вызовет ошибку. Проверяйте открытость формы через Оповестить с обработчиком — закрытая форма просто не получит событие, и ошибки не будет.

Третья ошибка — использование оповещений вместо оптимистичной блокировки. Если две формы редактируют один объект, оповещение не решает проблему конкурентного доступа: нужна управляемая блокировка данных на сервере или стандартный механизм версионирования объектов.

Типичные ошибки
01
ОбработкаОповещения без проверки ИмяСобытия — форма реагирует на все системные события и тормозит.
02
Прочитать() без проверки Модифицированность — теряются несохранённые данные пользователя.
03
Обращение к закрытой форме через сохранённую ссылку — ошибка выполнения на клиенте.
04
Одинаковые имена событий у разных механизмов — формы обновляются от чужих оповещений.
05
Оповещение в цикле при массовой обработке — сотни обновлений списка подряд, интерфейс зависает.

Как проверить, что обновление работает корректно

Проверка выполняется интерактивно: откройте обе формы одновременно, выполните изменение в форме-источнике и убедитесь, что целевая форма отобразила новые данные без переоткрытия. Затем повторите тест с закрытой целевой формой — не должно быть ошибок, а при следующем открытии данные должны быть актуальными за счёт обычного чтения из базы.

Отдельно проверьте сценарий с модифицированной целевой формой: внесите в неё изменения без записи, спровоцируйте оповещение и убедитесь, что данные не сбросились. Для массовых операций замерьте время выполнения — если обновление списка происходит в цикле, перенесите Оповестить за пределы цикла и вызовите один раз после завершения обработки.

Контрольные точки

Как проверить результат

Обновление открытой формы
Норма

Данные в целевой форме меняются сразу после действия в источнике

Тревожный признак

Форма показывает старые данные до переоткрытия

Закрытая целевая форма
Норма

Ошибок нет, при открытии данные актуальны

Тревожный признак

Ошибка обращения к форме или устаревшие данные

Модифицированная форма
Норма

Несохранённые изменения пользователя сохраняются

Тревожный признак

Введённые данные сбрасываются при оповещении

Массовая обработка
Норма

Одно оповещение после цикла, интерфейс отзывчив

Тревожный признак

Список мигает и обновляется на каждой итерации

Ответы на частые вопросы

Чем Оповестить отличается от ОповеститьОбИзменении?

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

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

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

Можно ли обновить форму, открытую другим пользователем?

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

Почему ОбработкаОповещения не срабатывает?

Чаще всего причина в несовпадении имени события: проверьте, что строка в Оповестить и в условии обработчика идентична с точностью до регистра и пробелов. Также убедитесь, что обработчик объявлен с директивой &НаКлиенте, а целевая форма действительно открыта в момент оповещения.

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

Передайте в параметре структуру: Новый Структура("Ссылка, Статус, Комментарий", ...). В обработчике ОбработкаОповещения обратитесь к свойствам структуры через Параметр.Ссылка и так далее. Учитывайте, что структура создаётся на клиенте, поэтому в неё нельзя помещать несериализуемые объекты.

Как обновить форму внешней обработки из формы документа?

Механизм тот же: форма внешней обработки — обычная управляемая форма, она получает оповещения наравне с остальными. Добавьте в неё ОбработкаОповещения с нужным именем события, а из формы документа вызовите Оповестить. Если обработка открыта из формы документа, можно также обратиться к ней через ВладелецФормы.

Итог

Что важно запомнить

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