В разработке на платформе 1С:Предприятие 8.3 часто возникает ситуация, когда необходимо создать множество однотипных кнопок (например, плиточный интерфейс, клавиатура или выбор мест в зале), которые должны выполнять схожее действие. Создавать под каждую кнопку отдельную команду — трудозатратно и неэффективно с точки зрения поддержки кода. Оптимальным решением является привязка всех кнопок к одному обработчику. Однако здесь возникает главный вопрос: как внутри этого обработчика понять, какая именно кнопка инициировала вызов? Разберем подробно все способы решения этой задачи, их преимущества и ограничения.
Самый простой и логичный способ в управляемом интерфейсе — обратиться к свойству формы ТекущийЭлемент. В момент нажатия на кнопку (если она находится непосредственно на форме), фокус ввода переходит на нее, и платформа фиксирует этот элемент как текущий.
Рассмотрим ситуацию, когда у нас есть 45 кнопок для выбора чисел. Все они привязаны к одной клиентской процедуре-команде. Для того чтобы изменить оформление нажатой кнопки (например, сделать шрифт жирным и поменять цвет фона), мы можем использовать следующий код:
&НаКлиенте
Процедура НажатиеНаКнопку(Команда)
// Получаем имя элемента, который сейчас находится в фокусе
ИмяЭлемента = ЭтаФорма.ТекущийЭлемент.Имя;
// Находим сам элемент в коллекции Элементы
ТекКнопка = Элементы.Найти(ИмяЭлемента);
Если ТекКнопка <> Неопределено Тогда
// Проверяем текущее состояние шрифта
Если ТекКнопка.Шрифт.Жирный Тогда
// Возвращаем стандартное оформление
ТекКнопка.Шрифт = Новый Шрифт(,,Ложь);
ТекКнопка.ЦветФона = Новый Цвет(); // Авто-цвет
Иначе
// Устанавливаем выделение
ТекКнопка.Шрифт = Новый Шрифт(,,Истина);
ТекКнопка.ЦветФона = Новый Цвет(179, 172, 134);
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Важный нюанс: Этот метод отлично работает для обычных кнопок, размещенных в группах или просто на поле формы. Однако, если кнопка расположена в Командной панели или в Подменю, она может не получать фокус при нажатии. В этом случае ТекущийЭлемент вернет тот объект, который был активен до клика по меню (например, поле ввода или таблицу), и идентификация не сработает.
Если кнопок очень много или их состав динамически меняется, лучше всего создавать их программно. Это позволяет нам не только автоматизировать процесс, но и (при необходимости) назначать каждой кнопке свою уникальную команду, что снимает вопрос идентификации.
Проанализируем ситуацию, когда нам нужно программно создать кнопки в обработчике ПриСозданииНаСервере. Обратите внимание, что в управляемом интерфейсе изменять структуру элементов формы (добавлять команды и кнопки) можно только на сервере.
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
Для Индекс = 1 По 45 Цикл
ИмяКнопки = "Кнопка_" + Индекс;
// 1. Создаем команду формы
НоваяКоманда = ЭтаФорма.Команды.Добавить(ИмяКнопки);
НоваяКоманда.Действие = "ОбработчикНажатияКнопки"; // Общая процедура
НоваяКоманда.Заголовок = "Число " + Индекс;
// 2. Создаем кнопку и привязываем ее к команде
НовыйЭлемент = Элементы.Добавить(ИмяКнопки, Тип("КнопкаФормы"), Элементы.ГруппаКнопок);
НовыйЭлемент.ИмяКоманды = ИмяКнопки;
КонецЦикла;
КонецПроцедуры
В данном примере мы все равно привязываем все команды к одному действию ОбработчикНажатияКнопки. Чтобы в этом случае понять, какая кнопка нажата, мы используем параметр Команда, который передается в процедуру:
&НаКлиенте
Процедура ОбработчикНажатияКнопки(Команда)
// Параметр Команда содержит объект команды, у которой есть имя
ИмяНажатойКоманды = Команда.Имя;
// Теперь мы точно знаем, какая кнопка была нажата,
// так как имя кнопки совпадает с именем команды
ТекКнопка = Элементы[ИмяНажатойКоманды];
// Выполняем действия...
Сообщить("Нажато число: " + ТекКнопка.Заголовок);
КонецПроцедуры
Если ваша задача — выбор множества элементов (как в случае с лотереей «6 из 45»), создание 45 кнопок может быть не самым эффективным решением с точки зрения производительности интерфейса. Каждый элемент формы потребляет ресурсы при отрисовке.
Вместо массива кнопок можно рассмотреть использование элемента формы Поле списка. Рассмотрим алгоритм реализации:
СписокЗначений.В этом случае пользователю не нужно «нажимать» кнопки — он просто отмечает галочками нужные числа. Программно получить выбранные числа можно одним циклом по списку значений, проверяя свойство Пометка. Это избавляет от необходимости манипулировать шрифтами и цветами кнопок вручную, так как платформа берет визуализацию на себя.
При программном изменении свойств Шрифт или ЦветФона важно помнить о клиент-серверном взаимодействии. В управляемом приложении изменение визуальных свойств элементов формы через код на клиенте (как показано в способе 1) происходит мгновенно. Однако, если логика требует обращения к серверу (например, проверить, доступно ли еще это число для выбора в базе данных), оформление лучше менять после возврата с сервера.
Также стоит учитывать, что в 1С не существует полноценного ООП для элементов формы в контексте событий. Мы не можем передать в обработчик команды произвольный объект или «Self». Поэтому связка ТекущийЭлемент.Имя или идентификация через имя самой Команды остаются единственными надежными способами в рамках стандартной парадигмы платформы.
Резюмируем:
ЭтаФорма.ТекущийЭлемент.СписокЗначений с пометками или Таблицу формы.