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

Программист 1С v8.3 (Управляемые формы)
← На главную

При разработке интерфейсов в 1С:Предприятии 8 нередко возникает задача динамического обновления информации, отображаемой на форме, в зависимости от изменения других данных или реквизитов. В частности, пользователь столкнулся с необходимостью "постоянно отслеживать" изменение реквизитов на управляемой форме и обновлять надпись без явного вызова функции каким-либо действием, проводя параллели с опытом работы в 1С 7.7. Однако архитектура управляемых форм 1С 8 существенно отличается от обычной формы 7.7, и прямого аналога "постоянного отслеживания" в том виде, как это могло быть реализовано ранее, не существует. Вместо этого, управляемые формы используют событийную модель и механизмы, позволяющие реагировать на изменения данных. Рассмотрим подробнее, как мы можем достичь желаемого результата.

1. Привязка элемента "Поле надписи" к реквизиту формы

Самый простой и "нативный" способ отображения динамической информации на управляемой форме — это привязка элемента "Поле надписи" к реквизиту формы. Если надпись должна отображать простое значение одного из реквизитов формы, этот метод будет наиболее эффективным.

  1. Добавьте реквизит на форму: Нам необходимо создать реквизит формы, тип которого соответствует данным, которые мы хотим отображать в надписи (например, Строка, Число, Дата). Этот реквизит будет хранить актуальный текст для надписи.
  2. Разместите элемент "Поле надписи" на форме: Перетащите элемент "Поле надписи" из палитры элементов на форму.
  3. Привяжите надпись к реквизиту: В свойствах элемента "Поле надписи" найдите свойство ПутьКДанным и укажите путь к созданному нами реквизиту формы.

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

Пример:

Допустим, у нас есть реквизит формы с именем ТекстНадписи типа Строка.


&НаКлиенте
ПеременнаяФормы.ТекстНадписи = "Начальное значение";

// Где-то в логике формы при изменении других данных
&НаКлиенте
Процедура РеквизитФормы1ПриИзменении(Элемент)
    ЭтотОбъект.ТекстНадписи = "Новое значение после изменения РеквизитаФормы1: " + РеквизитФормы1;
КонецПроцедуры

В этом случае, как только мы присвоим новое значение реквизиту ТекстНадписи, элемент "Поле надписи", привязанный к нему, обновится автоматически.

2. Использование обработчика события ПриИзменении для реквизитов

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

  1. Определите зависимые реквизиты: Выясним, какие реквизиты формы влияют на текст нашей надписи.
  2. Создайте обработчики ПриИзменении: Для каждого из этих реквизитов создадим обработчик события ПриИзменении.
  3. Реализуйте процедуру обновления надписи: Создадим отдельную клиентскую процедуру (например, ОбновитьТекстНадписи()), которая будет собирать данные из всех зависимых реквизитов, выполнять необходимые вычисления и присваивать полученный текст реквизиту формы, к которому привязана наша надпись.
  4. Вызывайте процедуру обновления: Из каждого обработчика ПриИзменении вызывайте процедуру ОбновитьТекстНадписи().

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

Пример:

Предположим, у нас есть реквизиты формы Количество (Число) и Цена (Число), и мы хотим отображать их произведение в надписи, привязанной к реквизиту формы СуммаТекст (Строка).


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

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

&НаКлиенте
Процедура ОбновитьСуммуНадписи()
    ПеременнаяФормы.СуммаТекст = "Сумма: " + (ЭтотОбъект.Количество * ЭтотОбъект.Цена);
КонецПроцедуры

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

Таким образом, при изменении полей "Количество" или "Цена" на форме, надпись с суммой будет автоматически обновляться.

3. Обновление надписи при изменении данных объектов вне формы (ОповеститьОбИзменении и ОбработкаОповещения)

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

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

Как это работает: Мы не "постоянно отслеживаем", а реактивно слушаем события изменения данных. Это значительно снижает нагрузку, так как обновление происходит только при фактическом изменении.

Пример (вызов оповещения):

Предположим, у нас есть документ "ЗаказКлиента", и после его записи мы хотим, чтобы все открытые формы, отображающие информацию по этому заказу, обновились.


// В модуле объекта или форме документа "ЗаказКлиента" после записи
&НаСервереБезКонтекста
Процедура ПослеЗаписиНаСервере(Отказ, ДополнительныеСвойства)
    // ... логика записи
    ОповеститьОбИзменении(ДополнительныеСвойства.Ссылка); // ДополнительныеСвойства.Ссылка содержит ссылку на записанный объект
    // Также можно использовать Оповестить() с произвольным именем события
    Оповестить("ЗаказОбновлен", ДополнительныеСвойства.Ссылка);
КонецПроцедуры

Пример (прием оповещения на форме с надписью):

В форме, где нам нужно обновить надпись (например, отображающую статус заказа), мы реализуем обработчик:


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

    Если ИмяСобытия = "ЗаказОбновлен" Тогда
        Если ТипЗнч(Параметр) = Тип("ДокументСсылка.ЗаказКлиента") Тогда
            // Предположим, наша форма отображает данные конкретного заказа
            Если ЭтотОбъект.ЗаказТекущейФормы = Параметр Тогда
                // Заказ, который нас интересует, был обновлен.
                // Теперь нам нужно перечитать данные и обновить надпись.
                ОбновитьСтатусЗаказаНадписиНаСервере();
            КонецЕсли;
        КонецЕсли;
    ИначеЕсли ИмяСобытия = "ЗаказКлиента" И ТипЗнч(Параметр) = Тип("УникальныйИдентификатор") Тогда
        // Оповещение через ОповеститьОбИзменении по УИД
        // Если наша форма также работает с этим объектом, обновляем
        Если ЭтотОбъект.ЗаказТекущейФормы.УникальныйИдентификатор = Параметр Тогда
            ОбновитьСтатусЗаказаНадписиНаСервере();
        КонецЕсли;
    КонецЕсли;

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

// Процедура для обновления данных и надписи на сервере
&НаСервере
Процедура ОбновитьСтатусЗаказаНадписиНаСервере()
    // Прочитаем актуальные данные по заказу из базы
    СсылкаНаЗаказ = ЭтотОбъект.ЗаказТекущейФормы;
    Если ЗначениеЗаполнено(СсылкаНаЗаказ) Тогда
        ОбъектЗаказ = СсылкаНаЗаказ.ПолучитьОбъект();
        Если ОбъектЗаказ <> Неопределено Тогда
            ЭтотОбъект.ТекстНадписиСтатуса = "Статус заказа: " + ОбъектЗаказ.Статус;
        КонецЕсли;
    КонецЕсли;
КонецПроцедуры

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

4. Принудительное обновление отображения формы (ОбновитьОтображениеДанных, Элементы.ИмяЭлемента.Обновить())

Методы ЭтаФорма.ОбновитьОтображениеДанных() и Элементы.ИмяЭлемента.Обновить() используются для принудительного обновления содержимого элементов управления на форме. Хотя для простой надписи, привязанной к реквизиту, автоматическое обновление обычно достаточно, эти методы могут быть полезны в более сложных сценариях:

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

Пример:


&НаКлиенте
Процедура ПересчитатьИОбновитьВсе(Команда)
    // Изменяем несколько реквизитов формы
    ЭтотОбъект.РеквизитДляНадписи1 = "Новое значение 1";
    ЭтотОбъект.РеквизитДляНадписи2 = "Новое значение 2";
    // Если надпись не привязана напрямую к реквизиту, а ее текст формируется вручную,
    // или если есть другие элементы, требующие обновления.
    ЭтаФорма.ОбновитьОтображениеДанных();
    // Надпись, привязанная к РеквизитДляНадписи1, обновится автоматически,
    // но если есть другие вычисляемые элементы, это может быть полезно.
КонецПроцедуры

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

Заключение

Мы выяснили, что в управляемых формах 1С 8 подход к динамическому обновлению надписей отличается от "постоянного отслеживания" в 1С 7.7. Вместо постоянного опроса, мы используем событийную модель, которая является более производительной и соответствует архитектуре клиент-серверного взаимодействия.

Мы рассмотрели несколько эффективных методов:

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

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

← На главную