Как программно создать флаг на форме и назначить ему обработчик события ПриИзменении?

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

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

Разберем постановку задачи

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

  1. Подготовка данных (реквизита), к которому будет привязан флаг.
  2. Программное создание визуального элемента на форме.
  3. Связывание события элемента с процедурой-обработчиком.

Шаг 1: Создание реквизита формы

Проанализируем важный нюанс: элемент формы (визуальный объект) не может существовать сам по себе, ему нужен «источник данных». В свойстве ПутьКДанным мы указываем имя реквизита. Если реквизит не создан в конфигураторе заранее, его необходимо добавить программно. Выясним, как это сделать правильно в серверном контексте.

Для добавления реквизита используется метод ИзменитьРеквизиты. Посмотрим на пример кода:


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

Шаг 2: Программное создание элемента формы

Теперь, когда у нас есть реквизит ПрограммныйФлаг, создадим само поле флажка. Рассмотрим процесс добавления элемента в коллекцию Элементы. Важно правильно указать родительскую группу и вид поля.


&НаСервере
Процедура СоздатьЭлементФлагНаФорме()

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

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

Шаг 3: Создание процедуры-обработчика

Одной из самых частых ошибок является неправильное описание процедуры-обработчика. Выясним причины, по которым процедура может «не запускаться», как это было в вопросе автора темы. Проанализируем два критических момента:

  1. Аннотация контекста: События интерфейса (нажатие кнопок, изменение полей) всегда инициируются на стороне клиента. Поэтому процедура обязана иметь аннотацию &НаКлиенте.
  2. Параметры процедуры: Стандартный обработчик ПриИзменении ожидает один входной параметр — Элемент. Если его не указать, платформа выдаст ошибку о несоответствии количества параметров и не выполнит код.

Рассмотрим правильную реализацию обработчика:


&НаКлиенте
Процедура ФлагПриИзменении(Элемент)
    
    // ВАЖНО: Проверяем значение реквизита, а не свойства элемента
    Если ПрограммныйФлаг Тогда
        Сообщить("Флажок был установлен!");
        // Здесь мы можем вызвать серверный метод для дальнейшей обработки
        ВыполнитьЛогикуНаСервере();
    Иначе
        Сообщить("Флажок снят.");
    КонецЕсли;
    
КонецПроцедуры

Почему Элементы.Флаг — это не булево значение?

Проанализируем ситуацию из сообщения №4. Новички часто пишут Если Элементы.ИмяФлага Тогда.... Это в корне неверно. Объект Элементы.ИмяФлага возвращает программный объект типа ПолеФормы. У него есть свойства Видимость, Доступность, ТолькоПросмотр, но он не содержит самого значения (Истина или Ложь).

Значение хранится в реквизите формы, имя которого указано в ПутьКДанным. Поэтому обращаться нужно напрямую к имени реквизита или через ЭтаФорма["ИмяРеквизита"].

Работа с несколькими программными флажками

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

Посмотрим на пример универсального кода:


&НаКлиенте
Процедура УниверсальныйОбработчикФлагов(Элемент)
    
    ИмяЭлемента = Элемент.Имя;
    ЗначениеФлага = ЭтаФорма[Элемент.ПутьКДанным];
    
    ПоказатьОповещениеПользователя("Изменение", , 
        "Флаг " + ИмяЭлемента + " теперь имеет значение: " + ЗначениеФлага);
        
КонецПроцедуры

Дополнительные советы по управлению обработчиками

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

1. Отключение обработчика: Если в какой-то момент логика программы требует программно изменить значение флага, но при этом нельзя допустить срабатывания кода в ПриИзменении, обработчик можно временно «отцепить».


&НаСервере
Процедура ОтключитьОбработчик()
    Элементы.ФлагПрограммный.УстановитьДействие("ПриИзменении", "");
КонецПроцедуры

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

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

Таким образом, мы выяснили, что для успешной работы программного обработчика необходимо строго соблюдать соответствие имен реквизитов, использовать правильный контекст &НаКлиенте и не забывать про обязательный параметр Элемент в описании процедуры.

← На главную