Как передать параметр (строку) в обработчик нажатия динамически созданной кнопки?

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

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

Ограничение объекта Действие и сигнатура событий

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

Для события Нажатие кнопки процедура всегда должна иметь ровно один параметр — Элемент. Попытка передать в конструктор Новый Действие дополнительные аргументы или указать процедуру с иным количеством параметров приведет к ошибке во время выполнения. Разберем по шагам, как обойти это ограничение.

Решение 1: Использование контекста текущей строки (Рекомендуемое)

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

Посмотрим на пример реализации такой процедуры:


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

Этот способ является наиболее производительным и «чистым» с точки зрения архитектуры 1С, так как не требует хранения лишних данных в памяти.

Решение 2: Идентификация через имя элемента

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

Рассмотрим, как это может выглядеть при генерации кнопок:


Процедура СоздатьКнопкиВТаблице()
    Для Каждого СтрокаТЧ Из Объект.Товары Цикл
        ИмяКнопки = "Кнопка_ID_" + СтрокаТЧ.НомерСтроки;
        НоваяКнопка = ЭлементыФормы.Добавить(Тип("Кнопка"), ИмяКнопки, Истина, ЭлементыФормы.ПанельКнопок);
        НоваяКнопка.УстановитьДействие("Нажатие", Новый Действие("ОбработатьНажатиеДинамическойКнопки"));
    КонецЦикла;
КонецПроцедуры

В обработчике мы анализируем имя кнопки, которая пришла в параметр Элемент:


Процедура ОбработатьНажатиеДинамическойКнопки(Элемент) Экспорт
    // Извлекаем ID из имени "Кнопка_ID_5"
    ЧастиИмени = СтрРазделить(Элемент.Имя, "_");
    НомерСтроки = Число(ЧастиИмени[2]);
    
    // Находим строку по номеру или другому идентификатору
    СтрокаДанных = Объект.Товары[НомерСтроки - 1];
    // ... дальнейшая логика
КонецПроцедуры

Решение 3: Альтернативные методы (Тэг и ДопСвойства)

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

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

Особенности для Управляемых форм (v8.3)

Если вы работаете в интерфейсе «Такси», подход с программным созданием кнопок в каждой строке практически не используется. Вместо этого применяется механизм команд:

  1. Создается КомандаФормы.
  2. Эта команда перетаскивается в колонку таблицы в дереве элементов.
  3. В обработчике команды на сервере или клиенте мы обращаемся к Элементы.ИмяТаблицы.ТекущиеДанные.

Это работает «из коробки» и не требует никаких ухищрений с объектом Действие, так как контекст строки в управляемом приложении определяется автоматически через выделение в UI.

Заключение и рекомендации

Подведем итоги нашего исследования. Если вам необходимо реализовать логику «кнопка в строке»:

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

← На главную