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