Глобальный контекст.Оповестить

Методы · Notify

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

Синтаксис

Оповестить(<ИмяСобытия>, <Параметр>, <Источник>)

Примеры платформы

Оповестить("ЗакрытьФорму");
Полное описание, параметры и ограничения

Глобальный контекст.Оповестить (Global context.Notify)

Глобальный контекст (Global context)

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

Доступен, начиная с версии 8.0.

Синтаксис:
Оповестить(<ИмяСобытия>, <Параметр>, <Источник>)
Параметры:

<ИмяСобытия> (необязательный)
Тип: Строка.
Имя события. Может быть использовано для идентификации сообщений принимающими их формами.

<Параметр> (необязательный)
Тип: Произвольный.
Параметр сообщения. Могут быть переданы любые необходимые данные.

<Источник> (необязательный)
Тип: Произвольный.
Источник события. Например, в качестве источника может быть указана другая форма.
Описание:

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

Доступность:

Тонкий клиент, веб-клиент, мобильный клиент, толстый клиент, мобильное приложение (клиент).

Пример:

Оповестить("ЗакрытьФорму");

См. также:
Форма, событие ОбработкаОповещения
Глобальный контекст, метод ПодключитьОбработчикОповещения
Глобальный контекст, метод ОтключитьОбработчикОповещения

Использование в версии:

Доступен, начиная с версии 8.0.

Методическая информация

Практические примеры

Собственный подбор: выбрать строку и уведомить владельца

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

Где и как запускать

Полный модуль собственной обычной формы Подбор обработки УчебныйПодбор85. Только толстый клиент с обычными формами; не запускался.

Подготовка

  1. Создайте НОВУЮ пустую учебную конфигурацию УчебныеФормы85 на платформе 8.5.1.1343. Бизнес-объектов, расширений, подписок и регламентных заданий нет. Для уроков подбора добавьте только собственную обработку УчебныйПодбор85 и две обычные формы Пульт/Подбор. Другие уроки используют отдельные новые внешние обработки. Рабочие УТ, КА, УНФ и БП не изменяйте. Здесь никакие формы или базы не создавались и код не запускался: runtimeVerifiedScenarios=0.

  2. Создайте общий модуль УчебныеФормы85: Клиент (обычное приложение)=Да, Сервер=Да, Глобальный=Нет, Вызов сервера=Нет. Вставьте целиком отдельный модуль проверки стенда ниже. Обычная форма вызывает его в толстом клиенте; управляемая — только из серверного события создания.

  3. В своей конфигурации создайте только обработку УчебныйПодбор85 с обычными формами Пульт и Подбор. Пульт: реквизит ВыбранныйКод (Строка,10), поле отображения и кнопки ОткрытьПодбор/МодальныйПодбор/ЗакрытьПодбор. Подбор: реквизит Товары типа ТаблицаЗначений, табличное поле ТаблицаТоваров с Данные=Товары и кнопки Выбрать/Отмена. Рабочий справочник не нужен.

  4. В Пульт назначьте одноимённые действия кнопок и события ПриОткрытии, ОбработкаВыбора, ОбработкаОповещения. В Подбор назначьте Выбрать/Отмена; обработчик ПриОткрытии программно устанавливает Пульт. Процедура ПриОткрытии в Подбор содержит Экспорт и не имеет параметров — этого требует УстановитьДействие.

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

Процедура ПриОткрытии() Экспорт
    УчебныеФормы85.ПроверитьСвойПустойСтенд();
    Товары = Новый ТаблицаЗначений;
    Товары.Колонки.Добавить("Код", Новый ОписаниеТипов("Строка"));
    Товары.Колонки.Добавить("Наименование", Новый ОписаниеТипов("Строка"));
    Товары.Колонки.Добавить("Количество", Новый ОписаниеТипов("Число"));
    Товары.Колонки.Добавить("Выбран", Новый ОписаниеТипов("Булево"));
    Книга = Товары.Добавить();
    Книга.Код = "A-01";
    Книга.Наименование = "Книга";
    Книга.Количество = 3;
    Книга.Выбран = Ложь;
    Ручка = Товары.Добавить();
    Ручка.Код = "B-02";
    Ручка.Наименование = "Ручка";
    Ручка.Количество = 1;
    Ручка.Выбран = Ложь;
    Таблица = ЭтаФорма.ЭлементыФормы.ТаблицаТоваров;
    Таблица.СоздатьКолонки();
    Таблица.АвтоВводНовойСтроки = Ложь;
    Если Товары.Количество() <> 2 Тогда
        ВызватьИсключение "Ожидались два собственных учебных товара";
    КонецЕсли;
    Таблица.ТекущаяСтрока = Товары[0];
    Если Не ЭтаФорма.РежимВыбора Или ЭтаФорма.МножественныйВыбор
        Или ТипЗнч(ЭтаФорма.ВладелецФормы) <> Тип("Форма") Тогда
        ВызватьИсключение "Откройте собственный одиночный подбор только из Пульта";
    КонецЕсли;
    Начальная = Товары.Найти(ЭтаФорма.НачальноеЗначениеВыбора, "Код");
    Если Начальная = Неопределено Тогда
        ВызватьИсключение "Начальный код не принадлежит своей таблице";
    КонецЕсли;
    Таблица.ТекущаяСтрока = Начальная;
    Таблица.ТолькоПросмотр = Истина;
КонецПроцедуры

Процедура Выбрать(Кнопка)
    Таблица = ЭтаФорма.ЭлементыФормы.ТаблицаТоваров;
    Строка = Таблица.ТекущаяСтрока;
    Если Строка = Неопределено Тогда
        Сообщить("Выберите собственную строку");
        Возврат;
    КонецЕсли;
    Если Товары.Количество() <> 2 Или (Строка.Код <> "A-01" И Строка.Код <> "B-02") Тогда
        ВызватьИсключение "Изменился собственный источник подбора";
    КонецЕсли;
    Пакет = Новый Структура("Ключ,Код", ЭтаФорма.КлючУникальности, Строка.Код);
    Оповестить("УчебныйПодбор85.ПозицияВыбрана", Пакет, ЭтаФорма);
    Если ЭтаФорма.МодальныйРежим Тогда
        ЭтаФорма.Закрыть(Строка.Код);
    Иначе
        ЭтаФорма.ОповеститьОВыборе(Строка.Код);
    КонецЕсли;
КонецПроцедуры

Процедура Отмена(Кнопка)
    ЭтаФорма.Закрыть();
КонецПроцедуры
УчебныйПодбор85.Пульт

Своя обработка УчебныйПодбор85 → Формы → Пульт → Модуль

Полный отдельный модуль второй обычной формы; не вставлять в основной модуль этого урока. Не выполнялся.

Перем Подбор;
Перем КлючПодбора;

Процедура ПриОткрытии()
    УчебныеФормы85.ПроверитьСвойПустойСтенд();
    Если Метаданные.Обработки.Количество() <> 1 Или Метаданные.Обработки[0].Имя <> "УчебныйПодбор85" Тогда
        ВызватьИсключение "Подготовьте только собственную обработку УчебныйПодбор85";
    КонецЕсли;
    КлючПодбора = Новый УникальныйИдентификатор;
    Подбор = Неопределено;
    ВыбранныйКод = "";
КонецПроцедуры

Функция ПодготовитьПодбор()
    Если Подбор <> Неопределено И Подбор.Открыта() Тогда
        Если Подбор.МодальныйРежим Тогда
            ВызватьИсключение "Сначала завершите свой модальный выбор";
        КонецЕсли;
        Возврат Подбор;
    КонецЕсли;
    Подбор = Обработки.УчебныйПодбор85.ПолучитьФорму("Подбор", ЭтаФорма.ЭтаФорма, КлючПодбора);
    Если ТипЗнч(Подбор) <> Тип("Форма") Тогда
        ВызватьИсключение "Не получена собственная обычная форма Подбор";
    КонецЕсли;
    Подбор.ВладелецФормы = ЭтаФорма;
    Подбор.КлючУникальности = КлючПодбора;
    Подбор.ЗакрыватьПриЗакрытииВладельца = Истина;
    Подбор.РежимВыбора = Истина;
    Подбор.МножественныйВыбор = Ложь;
    Подбор.ЗакрыватьПриВыборе = Истина;
    Подбор.НачальноеЗначениеВыбора = "B-02";
    Подбор.АвтоЗаголовок = Ложь;
    Подбор.Заголовок = "Выберите собственную книгу или ручку";
    Подбор.УстановитьДействие("ПриОткрытии", Новый Действие("ПриОткрытии"));
    Если ТипЗнч(Подбор.ВладелецФормы) <> Тип("Форма") Или Подбор.КлючУникальности <> КлючПодбора
        Или ТипЗнч(Подбор.ПолучитьДействие("ПриОткрытии")) <> Тип("Действие") Тогда
        ВызватьИсключение "Не совпал владелец, ключ или обработчик собственной формы";
    КонецЕсли;
    Если Не Подбор.ЗакрыватьПриЗакрытииВладельца Или Не Подбор.РежимВыбора
        Или Подбор.МножественныйВыбор Или Не Подбор.ЗакрыватьПриВыборе
        Или Подбор.НачальноеЗначениеВыбора <> "B-02" Или Подбор.АвтоЗаголовок
        Или Подбор.Заголовок <> "Выберите собственную книгу или ручку" Тогда
        ВызватьИсключение "Не совпал собственный профиль одиночного подбора";
    КонецЕсли;
    Возврат Подбор;
КонецФункции

Процедура ОткрытьПодбор(Кнопка)
    ФормаПодбора = ПодготовитьПодбор();
    Если Не ФормаПодбора.Открыта() Тогда
        ФормаПодбора.Открыть();
    Иначе
        ФормаПодбора.Активизировать();
    КонецЕсли;
    Сообщить("Доступность ввода в своём подборе: " + Строка(ФормаПодбора.ВводДоступен()));
КонецПроцедуры

Процедура МодальныйПодбор(Кнопка)
    ФормаПодбора = ПодготовитьПодбор();
    Если ФормаПодбора.Открыта() Тогда
        Сообщить("Закройте свой немодальный подбор перед отдельным модальным опытом");
        Возврат;
    КонецЕсли;
    Код = ФормаПодбора.ОткрытьМодально(120);
    Если Код = Неопределено Тогда
        Сообщить("Отмена или таймаут; прежний код сохранён");
        Возврат;
    КонецЕсли;
    ПринятьКод(Код);
КонецПроцедуры

Процедура ЗакрытьПодбор(Кнопка)
    Если Подбор <> Неопределено И Подбор.Открыта() Тогда
        Подбор.Закрыть();
    КонецЕсли;
КонецПроцедуры

Процедура ОбработкаВыбора(ЗначениеВыбора, Источник)
    Если ТипЗнч(Источник) <> Тип("Форма") Или Источник.КлючУникальности <> КлючПодбора Тогда
        Возврат;
    КонецЕсли;
    ПринятьКод(ЗначениеВыбора);
КонецПроцедуры

Процедура ОбработкаОповещения(ИмяСобытия, Параметр, Источник)
    Если ИмяСобытия <> "УчебныйПодбор85.ПозицияВыбрана" Или ТипЗнч(Параметр) <> Тип("Структура") Тогда
        Возврат;
    КонецЕсли;
    Если Не Параметр.Свойство("Ключ", Ключ) Или Ключ <> КлючПодбора
        Или Не Параметр.Свойство("Код", Код) Или ТипЗнч(Источник) <> Тип("Форма")
        Или Источник.КлючУникальности <> КлючПодбора Тогда
        Возврат;
    КонецЕсли;
    Если ТипЗнч(Код) = Тип("Строка") И (Код = "A-01" Или Код = "B-02") Тогда
        Сообщить("Общее оповещение о своей позиции: " + Код);
    КонецЕсли;
КонецПроцедуры

Процедура ПринятьКод(Код)
    Если ТипЗнч(Код) <> Тип("Строка") Или (Код <> "A-01" И Код <> "B-02") Тогда
        ВызватьИсключение "Подбор должен вернуть только собственный A-01 или B-02";
    КонецЕсли;
    ВыбранныйКод = Код;
    Сообщить("Принят код: " + ВыбранныйКод);
КонецПроцедуры
УчебныеФормы85.ПроверкаСтенда

Своя пустая конфигурация УчебныеФормы85 → Общие → Общие модули → УчебныеФормы85

Полный общий модуль: обычный клиент и сервер, без глобального доступа и вызова сервера. Не выполнялся.

Процедура ПроверитьСвойПустойСтенд() Экспорт
    Если Метаданные.Справочники.Количество() <> 0 Или Метаданные.Документы.Количество() <> 0 Или Метаданные.Перечисления.Количество() <> 0 Или Метаданные.РегистрыСведений.Количество() <> 0 Или Метаданные.РегистрыНакопления.Количество() <> 0 Или Метаданные.РегистрыБухгалтерии.Количество() <> 0 Или Метаданные.РегистрыРасчета.Количество() <> 0 Или Метаданные.ПланыВидовХарактеристик.Количество() <> 0 Или Метаданные.ПланыВидовРасчета.Количество() <> 0 Или Метаданные.ПланыСчетов.Количество() <> 0 Или Метаданные.ПланыОбмена.Количество() <> 0 Или Метаданные.Последовательности.Количество() <> 0 Или Метаданные.БизнесПроцессы.Количество() <> 0 Или Метаданные.Задачи.Количество() <> 0 Или Метаданные.ОбщиеРеквизиты.Количество() <> 0 Или Метаданные.ПодпискиНаСобытия.Количество() <> 0 Или Метаданные.РегламентныеЗадания.Количество() <> 0 Или Метаданные.ВнешниеИсточникиДанных.Количество() <> 0 Тогда
        ВызватьИсключение "Нужен только свой новый пустой учебный стенд";
    КонецЕсли;
    Если Метаданные.ЕстьИзмененияРасширениямиКонфигурации() Тогда
        ВызватьИсключение "Свой сеанс не должен изменяться расширениями";
    КонецЕсли;
    Источники = Новый Массив;
    Источники.Добавить(ИсточникРасширенийКонфигурации.БазаДанных);
    Источники.Добавить(ИсточникРасширенийКонфигурации.СеансАктивные);
    Источники.Добавить(ИсточникРасширенийКонфигурации.СеансОтключенные);
    Для Каждого Источник Из Источники Цикл
        Расширения = РасширенияКонфигурации.Получить(, Источник);
        Если ТипЗнч(Расширения) <> Тип("Массив") Тогда
            ВызватьИсключение "Native список расширений должен иметь тип Массив";
        КонецЕсли;
        Если Расширения.Количество() <> 0 Тогда
            ВызватьИсключение "В своём новом стенде нет расширений базы или сеанса";
        КонецЕсли;
    КонецЦикла;
    Если ТранзакцияАктивна() Тогда
        ВызватьИсключение "Чужая или вложенная активная транзакция не допускается";
    КонецЕсли;
КонецПроцедуры

Разбор по шагам

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

  2. ВладелецФормы, КлючУникальности и ЗакрыватьПриЗакрытииВладельца задают связь двух своих окон. ЭтаФорма.ЭтаФорма в аргументе владельца показывает документированное свойство, возвращающее саму обычную форму; обычно достаточно контекстного ЭтаФорма.

  3. Пульт задаёт одиночный режим, авто-закрытие после выбора и НачальноеЗначениеВыбора=B-02. Подбор вручную находит этот код в собственной таблице и выбирает Ручку: автоматическое позиционирование главного списка здесь не обещается.

  4. РежимВыбора проверяется собственным обработчиком; фактический результат передаёт отдельная кнопка. Сам по себе флаг не превращает произвольную таблицу в стандартный главный список выбора. МножественныйВыбор=Ложь оставляет одиночный опыт.

  5. УстановитьДействие связывает событие ПриОткрытии с экспортной процедурой именно модуля Подбор. ПолучитьДействие проверяет тип назначенного действия, но не выдумывает недокументированное поле с именем обработчика.

  6. Немодальный результат поступает в ОбработкаВыбора владельца через ОповеститьОВыборе; форма закрывается по ЗакрыватьПриВыборе. Модальный опыт возвращает код через Закрыть(Код) → ОткрытьМодально(120), поэтому тот же код не посылается вторично через событие выбора.

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

  8. Общее Оповестить отправляется всем созданным формам. Пульт фильтрует имя события, тип пакета, ключ своего подбора, источник и допустимый код. Это дополнительное диагностическое сообщение, а не второй способ повторно записать результат выбора.

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

  1. В будущем ручном опыте ОткрытьПодбор показывает две собственные строки, начальная — Ручка. Выберите Книгу: Пульт получает A-01, Подбор закрывается. Повторное нажатие при открытом подборе должно активизировать это окно, не создать лишнее.

  2. МодальныйПодбор открывается только после закрытия немодального окна. Выбор возвращает код; Отмена, крестик и таймаут 120 секунд должны сохранить прежний код. Не ждите таймаут в рабочей базе.

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

  4. Закройте свой Пульт при немодальном Подбор: дочернее окно должно закрыться по своему флагу. Владельца открытой модальной формы нельзя закрыть до окончания дочернего выбора; не подменяйте этот запрет успешной проверкой.

  5. Здесь формы, таймаут, активация, события и закрытие не запускались; это проверки для будущего ручного протокола, не утверждение о runtime.

Ожидаемый результат

Подготовлены два полных модуля Пульт/Подбор и проверка собственного стенда. Ожидается одиночный выбор, сохранение кода при отмене и корректный жизненный цикл собственных окон. runtimeVerifiedScenarios=0.

На что обратить внимание

  1. Обычная Форма не равна ФормаКлиентскогоПриложения. Метод менеджера ПолучитьФорму из этого урока относится к толстому клиенту, не к тонкому/веб-клиенту.

  2. UUID используется только для своих экземпляров в данном опыте, не для поиска или закрытия произвольных чужих окон.

  3. Модальный и немодальный результат идут разными путями. Не посылайте один результат одновременно через Закрыть(Код) и ОповеститьОВыборе.

  4. Оповестить — широковещательное сообщение, не адресное и не граница безопасности. Наш фильтр предназначен для собственного пустого стенда; произвольным внешним данным нельзя доверять.

  5. ЗакрыватьПриЗакрытииВладельца влияет на окна, не записывает бизнес-объекты. Урок не обещает отсутствия внутренних операций интерфейса или сохранения его положения.

Пример не запускался в вашей базе. Перед применением проверьте его в указанном учебном контексте.

Подключить получателя: настоящие события до отключения и видимый контроль после него

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

Где и как запускать

Клиент; полный модуль собственной управляемой формы ПодпискаОповещений85. Шесть настоящих команд подключают и отключают экспортную процедуру глобального клиентского модуля; серверных вызовов нет.

Подготовка

  1. Будущий опыт — только в своей НОВОЙ пустой учебной конфигурации 8.5.1.1343. Начните НОВЫЙ сеанс толстого управляемого клиента, откройте ровно одну собственную форму. Не используйте рабочую УТ, КА, УНФ или БП, чужие обработчики, расширения или другие открытые формы.

  2. Общие → Общие модули → создать УчебныеГлобальныеОповещения85. Глобальный=Да; Клиент (управляемое приложение)=Да; Сервер=Нет; Клиент (обычное приложение)=Нет; Внешнее соединение=Нет; Привилегированный=Нет; Вызов сервера=Нет; Повторное использование возвращаемых значений=Не использовать. Блок глобального получателя ниже вставить ЦЕЛИКОМ в пустой модуль. Здесь глобальный клиентский модуль нужен именно для регистрации экспортной процедуры по её имени.

  3. Общие → Общие формы → создать управляемую форму ПодпискаОповещений85. Реквизиты Принято85 и Сумма85: Число длиной 15, точность 0. Этап85: Строка длиной 50. Остановлено85: Булево. Результат85: Строка неограниченной длины. Вывести все пять полей только для просмотра. До подключения в своей новой форме реально наблюдайте типизированные Принято85=0, Сумма85=0, Остановлено85=Ложь и пустой Этап85. Код проверяет эти фактические значения, не присваивает их; неподготовленная форма означает остановку.

  4. В свойствах формы отключить сохранение: АвтоматическоеСохранениеДанныхВНастройках=АвтоматическоеСохранениеДанныхФормыВНастройках.НеИспользовать; СохранениеДанныхВНастройках=СохранениеДанныхФормыВНастройках.НеИспользовать. Это два разных перечисления, не Булево. Событие формы ОбработкаОповещения НЕ назначать: числа меняет только подключённый глобальный получатель.

  5. Создать шесть команд формы и кнопки: Подключить85, Передать30085, Передать25085, Отключить85, Передать900После85, ПроверитьПосле85. Действие каждой команды — одноимённая процедура. Основной блок вставить ЦЕЛИКОМ в пустой модуль формы. Не вызывайте обработчики вручную.

  6. Общие → Общие команды → создать ОткрытьПодпискуОповещений85 без параметра, включить в интерфейс своей учебной подсистемы. Третий блок вставить ЦЕЛИКОМ в пустой модуль команды. ОбработкаКоманды получает оба настоящих штатных параметра.

  7. Вручную обновить только свою учебную конфигурацию, проверить компиляцию, запустить НОВЫЙ клиентский сеанс и открыть одну форму общей командой. Здесь ничего не создавалось и не запускалось в 1С; успешные реальные события остаются будущей ручной проверкой.

  8. Не закрывать/не открывать вторую форму и не подключать повторно в этом сеансе. Неизвестный исход или прерванный опыт означает остановку: завершите только собственный учебный клиентский сеанс и начните новый. Нет автоматической очистки, повторной регистрации или отключения чужих процедур.

  9. Вся цепочка клиентская. Нет обращений к серверу, документов, регистров, файлов, Интернету или записи настроек. Отдельная виртуальная машина, пользователь и проверка всех метаданных этому ограниченному опыту не нужны; собственная новая конфигурация и свежий сеанс всё равно обязательны.

&НаКлиенте
Процедура ПроверитьПоля85()
    Если ТипЗнч(ЭтотОбъект) <> Тип("ФормаКлиентскогоПриложения")
        Или ИмяФормы <> "ОбщаяФорма.ПодпискаОповещений85"
        Или АвтоматическоеСохранениеДанныхВНастройках <> АвтоматическоеСохранениеДанныхФормыВНастройках.НеИспользовать
        Или СохранениеДанныхВНастройках <> СохранениеДанныхФормыВНастройках.НеИспользовать Тогда
        ВызватьИсключение "Нужна собственная форма с отключённым сохранением данных";
    КонецЕсли;
    Если ТипЗнч(Принято85) <> Тип("Число") Или ТипЗнч(Сумма85) <> Тип("Число")
        Или ТипЗнч(Этап85) <> Тип("Строка") Или ТипЗнч(Остановлено85) <> Тип("Булево")
        Или ТипЗнч(Результат85) <> Тип("Строка") Тогда
        ВызватьИсключение "Проверьте настоящие типы всех пяти собственных реквизитов";
    КонецЕсли;
    Если Принято85 < 0 Или Цел(Принято85) <> Принято85 Или Сумма85 < 0 Или Цел(Сумма85) <> Сумма85 Тогда
        ВызватьИсключение "Собственные числовые реквизиты должны быть целыми неотрицательными";
    КонецЕсли;
КонецПроцедуры

&НаКлиенте
Процедура ПроверитьКоманду85(Команда, ИмяКоманды, Этап, Принято, Сумма)
    ПроверитьПоля85();
    Если ТипЗнч(Команда) <> Тип("КомандаФормы") Или Команда.Имя <> ИмяКоманды Тогда
        ВызватьИсключение "Нужна настоящая одноимённая собственная команда";
    КонецЕсли;
    Если Остановлено85 Тогда
        ВызватьИсключение "Исход неизвестен или опыт остановлен; не повторяйте операции в этом сеансе";
    КонецЕсли;
    Если Этап85 <> Этап Или Принято85 <> Принято Или Сумма85 <> Сумма Тогда
        ВызватьИсключение "Предыдущий шаг ещё не подтверждён фактическим счётчиком; не повторяйте отправку";
    КонецЕсли;
КонецПроцедуры

&НаКлиенте
Процедура Подключить85(Команда)
    ПроверитьКоманду85(Команда, "Подключить85", "", 0, 0);
    Остановлено85 = Истина;
    Этап85 = "Подключение неизвестно";
    Результат85 = "Выполняется единственное подключение своего получателя.";
    Попытка
        ПодключитьОбработчикОповещения("УчебныйГлобальныйПолучатель85");
        ПроверитьПоля85();
        Если Принято85 <> 0 Или Сумма85 <> 0 Тогда
            ВызватьИсключение "Счётчик изменился до собственных отправок";
        КонецЕсли;
        Этап85 = "Подключение выполнено";
        Остановлено85 = Ложь;
        Результат85 = "Вызов подключения завершён; фактический приём событий ещё не проверен.";
    Исключение
        Остановлено85 = Истина;
        Этап85 = "Остановлено";
        Результат85 = "Исход подключения неизвестен. Не повторяйте и не выполняйте автоматическую очистку.";
        ВызватьИсключение;
    КонецПопытки;
КонецПроцедуры

&НаКлиенте
Процедура Передать30085(Команда)
    ПроверитьКоманду85(Команда, "Передать30085", "Подключение выполнено", 0, 0);
    Этап85 = "Первое отправлено";
    Результат85 = "Передаётся 300; дождитесь настоящего отчёта получателя и счётчика 1.";
    Попытка
        Оповестить("УчебнаяПодписка85.Сумма", 300, ЭтотОбъект);
    Исключение
        Остановлено85 = Истина;
        Этап85 = "Остановлено";
        Результат85 = "Отправка 300 завершилась ошибкой. Исход неизвестен; повтор запрещён.";
        ВызватьИсключение;
    КонецПопытки;
КонецПроцедуры

&НаКлиенте
Процедура Передать25085(Команда)
    ПроверитьКоманду85(Команда, "Передать25085", "Первое отправлено", 1, 300);
    Этап85 = "Второе отправлено";
    Результат85 = "Передаётся 250; дождитесь настоящего отчёта получателя и счётчика 2.";
    Попытка
        Оповестить("УчебнаяПодписка85.Сумма", 250, ЭтотОбъект);
    Исключение
        Остановлено85 = Истина;
        Этап85 = "Остановлено";
        Результат85 = "Отправка 250 завершилась ошибкой. Исход неизвестен; повтор запрещён.";
        ВызватьИсключение;
    КонецПопытки;
КонецПроцедуры

&НаКлиенте
Процедура Отключить85(Команда)
    ПроверитьКоманду85(Команда, "Отключить85", "Второе отправлено", 2, 550);
    Остановлено85 = Истина;
    Этап85 = "Отключение неизвестно";
    Результат85 = "Выполняется отключение именно своего подключённого получателя.";
    Попытка
        ОтключитьОбработчикОповещения("УчебныйГлобальныйПолучатель85");
        ПроверитьПоля85();
        Если Принято85 <> 2 Или Сумма85 <> 550 Тогда
            ВызватьИсключение "Фактические результаты изменились во время отключения";
        КонецЕсли;
        Этап85 = "Отключение выполнено";
        Остановлено85 = Ложь;
        Результат85 = "Вызов отключения завершён. Проверка следующего события ещё не выполнена.";
    Исключение
        Остановлено85 = Истина;
        Этап85 = "Остановлено";
        Результат85 = "Исход отключения неизвестен. Не повторяйте, не отправляйте дальше и не очищайте автоматически.";
        ВызватьИсключение;
    КонецПопытки;
КонецПроцедуры

&НаКлиенте
Процедура Передать900После85(Команда)
    ПроверитьКоманду85(Команда, "Передать900После85", "Отключение выполнено", 2, 550);
    Этап85 = "После отключения отправлено";
    Результат85 = "Передаётся контрольное 900. Итог пока не проверен; затем отдельно нажмите ПроверитьПосле85.";
    Попытка
        Оповестить("УчебнаяПодписка85.Сумма", 900, ЭтотОбъект);
    Исключение
        Остановлено85 = Истина;
        Этап85 = "Остановлено";
        Результат85 = "Контрольная отправка завершилась ошибкой. Исход неизвестен; повтор запрещён.";
        ВызватьИсключение;
    КонецПопытки;
КонецПроцедуры

&НаКлиенте
Процедура ПроверитьПосле85(Команда)
    ПроверитьКоманду85(Команда, "ПроверитьПосле85", "После отключения отправлено", 2, 550);
    Результат85 = "На момент этой отдельной проверки реально принято: " + Строка(Принято85)
        + "; сумма: " + Строка(Сумма85) + ". Контрольное 900 не учтено."
        + " Любой поздний вызов получателя останется видимым нарушением.";
    Этап85 = "Проверено";
КонецПроцедуры
Целый глобальный клиентский модуль УчебныеГлобальныеОповещения85: настоящий получатель

Общие → Общие модули → УчебныеГлобальныеОповещения85 → пустой модуль. Вставить ЦЕЛИКОМ; Глобальный=Да, Клиент (управляемое приложение)=Да, Сервер=Нет. Не модуль формы.

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

Процедура УчебныйГлобальныйПолучатель85(ИмяСобытия, Параметр, Источник) Экспорт
    Если ТипЗнч(ИмяСобытия) <> Тип("Строка") Или ИмяСобытия <> "УчебнаяПодписка85.Сумма" Тогда
        Возврат;
    КонецЕсли;
    Если ТипЗнч(Источник) <> Тип("ФормаКлиентскогоПриложения") Тогда
        ВызватьИсключение "У собственного события нет настоящей формы-источника";
    КонецЕсли;
    Если Источник.ИмяФормы <> "ОбщаяФорма.ПодпискаОповещений85"
        Или Источник.АвтоматическоеСохранениеДанныхВНастройках <> АвтоматическоеСохранениеДанныхФормыВНастройках.НеИспользовать
        Или Источник.СохранениеДанныхВНастройках <> СохранениеДанныхФормыВНастройках.НеИспользовать Тогда
        ВызватьИсключение "Событие должно принадлежать собственной подготовленной форме";
    КонецЕсли;
    Если ТипЗнч(Параметр) <> Тип("Число") Тогда
        ВызватьИсключение "Собственное событие должно передать настоящее число";
    КонецЕсли;
    Если Параметр <> 300 И Параметр <> 250 И Параметр <> 900 Тогда
        ВызватьИсключение "Допустимы только три собственных учебных числа";
    КонецЕсли;
    До = Источник.Принято85;
    СуммаДо = Источник.Сумма85;
    Если ТипЗнч(До) <> Тип("Число") Или ТипЗнч(СуммаДо) <> Тип("Число") Тогда
        ВызватьИсключение "Собственные счётчик и сумма должны быть настоящими числами";
    КонецЕсли;
    Если До < 0 Или Цел(До) <> До Или СуммаДо < 0 Или Цел(СуммаДо) <> СуммаДо Тогда
        ВызватьИсключение "Собственные счётчик и сумма должны быть целыми неотрицательными";
    КонецЕсли;
    Источник.Принято85 = До + 1;
    Источник.Сумма85 = СуммаДо + Параметр;
    После = Источник.Принято85;
    СуммаПосле = Источник.Сумма85;
    Если ТипЗнч(После) <> Тип("Число") Или ТипЗнч(СуммаПосле) <> Тип("Число")
        Или После <> До + 1 Или СуммаПосле <> СуммаДо + Параметр Тогда
        ВызватьИсключение "Реальный учёт собственного события не подтверждён";
    КонецЕсли;
    Отчет = "Получатель действительно вызван. Принято: " + Строка(После) + "; сумма: " + Строка(СуммаПосле) + ".";
    Если После > 2 Тогда
        Источник.Остановлено85 = Истина;
        Отчет = "ЛИШНЕЕ событие: " + Строка(После) + "; сумма: " + Строка(СуммаПосле)
            + ". Проверка отключения НЕ пройдена; опыт остановлен.";
    КонецЕсли;
    Источник.Результат85 = Отчет;
    Если ТипЗнч(Источник.Результат85) <> Тип("Строка") Или Источник.Результат85 <> Отчет Тогда
        ВызватьИсключение "Не подтверждён видимый отчёт настоящего получателя";
    КонецЕсли;
КонецПроцедуры
Целый модуль своей общей команды ОткрытьПодпискуОповещений85

Общие → Общие команды → ОткрытьПодпискуОповещений85 → пустой модуль команды. Вставить ЦЕЛИКОМ; без параметра, включить в свою подсистему. Открывать ровно одну форму в НОВОМ сеансе.

Толстый управляемый клиент; настоящее ОбработкаКоманды с обоими штатными параметрами. Не вызывает получатель или отправку напрямую.

Процедура ОбработкаКоманды(ПараметрКоманды, ПараметрыВыполненияКоманды)
    #Если ТолстыйКлиентУправляемоеПриложение Тогда
        Если ПараметрКоманды <> Неопределено
            Или ТипЗнч(ПараметрыВыполненияКоманды) <> Тип("ПараметрыВыполненияКоманды") Тогда
            ВызватьИсключение "Откройте одну свою учебную форму штатной общей командой без параметра";
        КонецЕсли;
        ОткрытьФорму("ОбщаяФорма.ПодпискаОповещений85");
    #Иначе
        ВызватьИсключение "Учебный опыт открывается в толстом управляемом клиенте";
    #КонецЕсли
КонецПроцедуры

Разбор по шагам

  1. Подключить85 один раз передаёт строку УчебныйГлобальныйПолучатель85 в ПодключитьОбработчикОповещения. Это имя существующей экспортной процедуры глобального клиентского модуля, не имя метода формы, не вызов с аргументами и не ОписаниеОповещения.

  2. До подключения и отключения форма ставит Остановлено85=Истина и неизвестный этап. Только нормальный возврат и повторная проверка собственных полей разрешают продолжение. Ошибка оставляет остановку; повтор, автоматическая очистка и следующая отправка запрещены.

  3. Передать30085 вызывает настоящий Оповестить с именем своего события, числом 300 и ЭтотОбъект — настоящей формой-источником. Получатель вызывается самой платформой; он проверяет три фактических аргумента и увеличивает собственные числовые реквизиты формы.

  4. Возврат из Оповестить сам по себе не доказывает доставку. Дождитесь видимых Принято85=1 и Сумма85=300. Только затем отдельно нажмите Передать25085. Второй настоящий вызов получателя должен дать 2 и 550; отправители эти числа не подставляют.

  5. Когда реально видны 2 и 550, нажмите Отключить85. Передаётся точно то же имя процедуры, которая была подключена. Завершение вызова отключения ещё не подменяет проверку следующего события.

  6. Нажмите Передать900После85: то же имя события, число 900, та же настоящая форма. Получатель не проверяет подключённость или этап для молчаливого пропуска: если платформа всё-таки вызовет его, счётчик станет 3, сумма 1450 и появится ЛИШНЕЕ событие.

  7. Отдельным настоящим нажатием ПроверитьПосле85 прочитайте фактические числа. Ожидаются 2 и 550; отчёт говорит только о моменте этой проверки. Поздний настоящий вызов получателя всё равно увеличит числа и заменит отчёт видимым нарушением, даже после этапа Проверено.

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

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

  1. Первый будущий опыт: фактические типизированные поля 0, 0, пустой этап, Ложь и строковый отчёт. Не присваивайте исходные числа ради прохождения проверки. После Подключить85 написано только о завершении вызова подключения; счётчик ещё 0, приём не объявлен проверенным.

  2. После Передать30085 наблюдайте настоящие 1 и 300 и сообщение Получатель действительно вызван. Если они отсутствуют, первый положительный результат не подтверждён: не повторяйте отправку и не считайте опыт успешным.

  3. Следующее отдельное нажатие Передать25085 должно привести к настоящим 2 и 550. В своём отладчике убедитесь, что Принято85 и Сумма85 увеличиваются в экспортном получателе, вызванном платформой, а не в командах отправки.

  4. После настоящего Отключить85 и Передать900После85 отдельно нажмите ПроверитьПосле85. Ожидаются фактически прочитанные 2 и 550; нет дополнительного учёта контрольного 900 к этому моменту. Не выдавайте отсутствие изменения за гарантию всех будущих моментов.

  5. Только в отдельной собственной учебной копии уберите вызов отключения, затем начните НОВЫЙ сеанс и весь опыт заново. Не меняйте получатель: настоящий третий вызов должен дать 3 и 1450, ЛИШНЕЕ событие и остановку, а не ложный успех из-за флага Отключён.

  6. При любой поздней фактической доставке после итоговой кнопки получатель тоже должен увеличить числа и показать нарушение. Нельзя прятать такой вызов условием по этапу Проверено или сбрасывать счётчик ради ожидаемых 2 и 550.

  7. Нажатия не по порядку или два подключения не должны выполнить новую регистрацию/отправку. Ошибочный вызов регистрации/отключения оставляет неизвестный исход и запрет повторения; конкретный отказ ещё не воспроизведён в 1С.

  8. Никаких ручных вызовов УчебныйГлобальныйПолучатель85 для проверки счётчика: это подменит платформенное событие. Не назначайте параллельно ОбработкаОповещения формы и не применяйте опыт к рабочему клиентскому сеансу.

Ожидаемый результат

Только после реальных платформенных вызовов: первое своё событие даёт 1/300, второе 2/550. После отключения точно этого получателя и отдельной проверки контрольного 900 ожидаются фактически прочитанные 2/550. Это наблюдение в текущий момент, не гарантия всех будущих моментов; любой настоящий третий вызов показывает 3/1450 и видимое нарушение даже после итоговой проверки.

На что обратить внимание

  1. Установленная страница ПодключитьОбработчикОповещения противоречива: в параметре написано «Процедура не должна содержать параметров», а основное описание требует три параметра и пример показывает экспортную процедуру с тремя. Урок следует явному основному описанию и примеру 8.5.1.1343; это не объявлено доказанной опечаткой или проверенным запуском.

  2. В строке регистрации указывается голое имя экспортной глобальной клиентской процедуры. Объект ОписаниеОповещения и процедура модуля формы относятся к другим механизмам и не заменяют этот контракт.

  3. Методы подключения, отключения и Оповестить не возвращают здесь проверяемый дескриптор или Булево. Отметка завершённого вызова не является наблюдением обработанного события; доказательством служат собственные фактические счётчик и сумма.

  4. Оповестить рассылает уведомление всем созданным формам и подключённым процедурам. Имя и источник ограничивают наш учебный получатель, но не делают рассылку приватной или безопасной границей авторизации.

  5. Нативное описание не обещает синхронность или пустую очередь к возврату. Отдельные действия пользователя и реальные наблюдения не подменяются таймером, задержкой, прямым вызовом получателя или обещанием отсутствия любой поздней доставки.

  6. Получатель никогда не прекращает учёт своего корректного события из-за этапа или флага подключения/остановки. Иначе неотключённая процедура могла бы незаметно пропустить 900 и создать ложный положительный результат.

  7. Подписка относится к клиентскому сеансу, а не к строковому полю формы. Новая форма со сброшенными полями не доказывает новую подписку; после прерывания нужен новый собственный клиентский сеанс, а не автоматический повтор.

  8. Строка(Число) зависит от национальных установок. Проверяются настоящие числовые 1/300, 2/550 и при лишнем событии 3/1450, а не заранее заданное форматирование текста.

  9. Во время написания не запускались компилятор, 1С, форма или события. Подготовка и положительные наблюдения остаются будущей ручной проверкой; отказ или пустой счётчик не считаются успешным примером.

Пример не запускался в вашей базе. Перед применением проверьте его в указанном учебном контексте.

Не хотите разбираться сами?

Адаптируем это решение под вашу базу. Оценка бесплатно.

Оставить задачу

1С, 1С:Предприятие — товарные знаки ООО «1С». Сайт не является официальным представительством фирмы «1С» и не аффилирован с ней.