Книга знаний

AdBlock убивает бесплатный контент
1С:Предприятие / v8 / Приемы программирования / Формы

v8: Метод обработки событий изменения формы

Альтернативная схема построения обработчика событий формы.Автор статьи: Гений 1С | Редакторы:
Последняя редакция №5 от 21.04.06 | История
URL: http://kb.mista.ru/article.php?id=127

Ключевые слова: события,форма,схема


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

Рассмотрим простейший пример: пусть у документа есть реквизиты "Валюта","Курс","Кратность","Контрагент","Договор","Дата".

При изменении реквизита "Валюта" нужно установить курс и кратность валюты на дату "Дата".
При изменении реквизита "Контрагент" нужно установить в реквизит "Договор" основной договор контрагента.

Классическая схема написания обработчиков событий формы будет такая:
Процедура Реквизит_Валюта_ПриИзменении()
  Курс=ПолучитьКурсПоВалюте(Валюта);
  Кратность=ПолучитьКратностьПоВалюте(Валюта);
КонецПроцедуры
Процедура Реквизит_Контрагент_ПриИзменении()
  Договор=ПолучитьОсновнойДоговорПоКонтрагенту(Контрагент);
КонецПроцедуры


Однако у приведенной схемы есть недостаток.
Допустим, пользователь создал новый документ и в него подставился контрагент по умолчанию.
По идее мы должны смоделировать в этой ситуации интерактивный выбор контрагента, чтобы проставился договор или скопировать код процедуры Реквизит_Контрагент_ПриИзменении.
Это можно сделать так:
Выполнить(""+ПолучитьДействие(ЭлементыФормы.Контрагент,"ПриИзменении")+"(ЭлементыФормы.Контрагент)");

Или так:
Реквизит_Контрагент_ПриИзменении();


Но хочется большей универсальности чтобы не приходилось дублировать код.
Добиться этого можно другой схемой:

Процедура ПриОткрытии()
    …
        
    //Назначаем всем данным формы обработчик ИзменениеДанных
    Для Каждого Эл из ЭлементыФормы Цикл 
        Попытка
            ПодключитьОбработчикИзмененияДанных(Эл.Данные, "ИзменениеДанных");
        Исключение
        КонецПопытки;
    КонецЦикла;

    ИзменениеДанных("*");

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

Процедура ОтображениеДанных(Реквизит)
    Если Реквизит="Договор" ИЛИ Реквизит="Контрагент" ИЛИ Реквизит="*" Тогда
        ЭлементыФормы.кнВзаиморасчеты.Доступность=Пусто(Договор) Или Пусто(Контрагент);
    КонецЕсли;
КонецПроцедуры

Процедура ИзменениеДанных(Реквизит)
    Если Реквизит="Контрагент" Тогда
        Договор=ПолучитьОсновнойДоговорПоКонтрагенту(Контрагент);
    ИначеЕсли Реквизит="Валюта" Тогда
        Курс=ПолучитьКурсПоВалюте(Валюта);
        Кратность=ПолучитьКратностьПоВалюте(Валюта);
    КонецЕсли;
    ОтображениеДанных(Реквизит);
КонецПроцедуры


Конечно, было бы идеально, если подобные цепочки событий можно было описывать в модуле объекта, аналогично Delpy с их Property Get, Property Set (события по установке/чтению свойств объекта) но пока еще это не реализовано в 80.

А зачем нужен вызов с реквизитом "*"?
Этот вызов происходит при открытии формы и предназначен для правильного отображения статуса объектов.
Например, по задаче требуется, чтобы если был выбран договор и контрагент, то была доступна кнопка "кнВзаиморасчеты". Понятно, что контролировать доступность (отображение) этой кнопки нужно только при открытии формы и при изменении контрагента или договора. При открытии формы вызывается изменение данных всей формы (Реквизит "*"), в остальных случаях вызывается изменение каждого конкретного реквизита.

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

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


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

Архив обсуждений:
v8: Как отловить добавление строки в табличную часть в форме?







Закладка

Описание | Рубрикатор | Поиск | ТелепатБот | Захваченные статьи | Установки | Форум
© Станислав Митичкин (Волшебник), 2005-2011 | Mista.ru

Яндекс.Метрика