Как узнать, на какую кнопку нажал пользователь при программном создании элементов в 1С

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

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

Анализ проблемы: почему стандартные методы не работают в подменю

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

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

Основное решение: создание уникальных команд для каждой кнопки

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

Проанализируем алгоритм реализации этого подхода:

  1. Для каждого необходимого элемента создается объект КомандаФормы через коллекцию ЭтаФорма.Команды.Добавить().
  2. Имя команды должно быть уникальным и, желательно, содержать в себе полезный идентификатор (например, код или ID объекта).
  3. В качестве действия команды указывается имя экспортной клиентской процедуры.
  4. Создается элемент формы (кнопка), свойство ИмяКоманды которого связывается с именем созданной команды.

Рассмотрим пример кода, реализующий эту логику:


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

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

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

Альтернативный подход: использование метода ПоказатьВыборИзМеню

Если кнопок предполагается очень много (например, более 50-100), создание отдельной команды для каждой из них может негативно сказаться на производительности формы, увеличивая объем данных при передаче между сервером и клиентом. В таком случае выясним, можно ли упростить задачу.

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

Посмотрим на пример реализации:

  1. Создаем одну статическую команду и кнопку "Выбрать вариант".
  2. В обработчике команды формируем СписокЗначений.
  3. Вызываем метод ПоказатьВыборИзМеню, передавая в него список и описание оповещения.
  4. В процедуре обработки выбора получаем выбранное значение.

Этот метод избавляет от необходимости генерировать уникальные имена и следить за уникальностью команд в коллекции формы. Платформа сама отрисует меню и вернет результат выбора в процедуру обратного вызова.

Связывание через паттерны именования

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

Резюме и рекомендации

Подведем итоги нашего анализа. Выбор метода зависит от сложности вашей задачи:

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

← На главную