Как узнать, на какую кнопку нажал пользователь в управляемом интерфейсе 1С

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

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

Способ 1. Использование свойства формы ТекущийЭлемент

Самый простой и логичный способ в управляемом интерфейсе — обратиться к свойству формы ТекущийЭлемент. В момент нажатия на кнопку (если она находится непосредственно на форме), фокус ввода переходит на нее, и платформа фиксирует этот элемент как текущий.

Рассмотрим ситуацию, когда у нас есть 45 кнопок для выбора чисел. Все они привязаны к одной клиентской процедуре-команде. Для того чтобы изменить оформление нажатой кнопки (например, сделать шрифт жирным и поменять цвет фона), мы можем использовать следующий код:


&НаКлиенте
Процедура НажатиеНаКнопку(Команда)
    
    // Получаем имя элемента, который сейчас находится в фокусе
    ИмяЭлемента = ЭтаФорма.ТекущийЭлемент.Имя;
    
    // Находим сам элемент в коллекции Элементы
    ТекКнопка = Элементы.Найти(ИмяЭлемента);
    
    Если ТекКнопка <> Неопределено Тогда
        // Проверяем текущее состояние шрифта
        Если ТекКнопка.Шрифт.Жирный Тогда
            // Возвращаем стандартное оформление
            ТекКнопка.Шрифт = Новый Шрифт(,,Ложь);
            ТекКнопка.ЦветФона = Новый Цвет(); // Авто-цвет
        Иначе
            // Устанавливаем выделение
            ТекКнопка.Шрифт = Новый Шрифт(,,Истина);
            ТекКнопка.ЦветФона = Новый Цвет(179, 172, 134);
        КонецЕсли;
    КонецЕсли;
    
КонецПроцедуры

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

Способ 2. Программное создание команд и кнопок

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

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


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    
    Для Индекс = 1 По 45 Цикл
        
        ИмяКнопки = "Кнопка_" + Индекс;
        
        // 1. Создаем команду формы
        НоваяКоманда = ЭтаФорма.Команды.Добавить(ИмяКнопки);
        НоваяКоманда.Действие = "ОбработчикНажатияКнопки"; // Общая процедура
        НоваяКоманда.Заголовок = "Число " + Индекс;
        
        // 2. Создаем кнопку и привязываем ее к команде
        НовыйЭлемент = Элементы.Добавить(ИмяКнопки, Тип("КнопкаФормы"), Элементы.ГруппаКнопок);
        НовыйЭлемент.ИмяКоманды = ИмяКнопки;
        
    КонецЦикла;
    
КонецПроцедуры

В данном примере мы все равно привязываем все команды к одному действию ОбработчикНажатияКнопки. Чтобы в этом случае понять, какая кнопка нажата, мы используем параметр Команда, который передается в процедуру:


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

Способ 3. Оптимизация через использование Списка значений

Если ваша задача — выбор множества элементов (как в случае с лотереей «6 из 45»), создание 45 кнопок может быть не самым эффективным решением с точки зрения производительности интерфейса. Каждый элемент формы потребляет ресурсы при отрисовке.

Вместо массива кнопок можно рассмотреть использование элемента формы Поле списка. Рассмотрим алгоритм реализации:

  1. Создаем реквизит формы с типом СписокЗначений.
  2. Выносим его на форму и устанавливаем вид Поле списка.
  3. В свойствах элемента включаем Режим отображения: Пометка.
  4. Заполняем список значениями от 1 до 45.

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

Особенности работы с оформлением (Шрифт и Цвет)

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

Также стоит учитывать, что в 1С не существует полноценного ООП для элементов формы в контексте событий. Мы не можем передать в обработчик команды произвольный объект или «Self». Поэтому связка ТекущийЭлемент.Имя или идентификация через имя самой Команды остаются единственными надежными способами в рамках стандартной парадигмы платформы.

Резюмируем:

← На главную