Как передать параметры в обработчик динамически созданной команды на управляемой форме 1С?

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

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

Разберем, почему возникает данная проблема, как устроена работа команд в управляемом интерфейсе и какими способами можно передать нужные параметры в вызываемый код.

Причина ограничения платформы

Проанализируем структуру объявления команды. Когда мы создаем команду программно на сервере, мы привязываем ее к процедуре формы через свойство Действие:


ИмяКоманды = "ВК_" + ИдентификаторКнопки;
Команда = Команды.Добавить(ИмяКоманды);
Команда.Действие = "ОбработатьНажатиеКнопки";

НоваяКнопка = Элементы.Добавить(ИмяКнопки, Тип("КнопкаФормы"), ГруппаРодитель);
НоваяКнопка.ИмяКоманды = ИмяКоманды;

Платформа 1С:Предприятие 8.3 жестко регламентирует сигнатуру клиентского обработчика команды формы. Процедура-обработчик обязана иметь строго один параметр:


&НаКлиенте
Процедура ОбработатьНажатиеКнопки(Команда)
    // Входящим параметром является только сам объект КомандаФормы
КонецПроцедуры

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

Способ 1. Идентификация параметров через имя команды (Команда.Имя)

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

Вариант А: Кодирование параметров в имени команды

Если требуется передать простой идентификатор (номер телефона, индекс или строковый код), мы можем зашить его в суффикс имени команды при создании:


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

В едином клиентском обработчике отсекаем служебный префикс и получаем исходное значение параметра:


&НаКлиенте
Процедура НабратьКонтрагента(Команда)
    
    Префикс = "КомандаНабрать_";
    Если СтрНачинаетсяС(Команда.Имя, Префикс) Тогда
        НомерТелефона = Сред(Команда.Имя, СтрДлина(Префикс) + 1);
        ВыполнитьЗвонок(НомерТелефона);
    КонецЕсли;
    
КонецПроцедуры

Вариант Б: Хранение параметров в реквизите формы

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

  1. При программном создании команд на сервере сохраняем параметры во временную таблицу или структуру реквизита формы, где ключом выступает ИмяКоманды.
  2. В обработчике команды по значению Команда.Имя извлекаем соответствующую структуру параметров и передаем ее в целевую бизнес-логику.

Способ 2. Использование выпадающего меню (ПоказатьВыборИзМеню)

Если динамические кнопки создаются для реализации выпадающего меню или подменю, создание серверных команд и элементов формы часто оказывается избыточным. Гораздо проще и эффективнее использовать встроенный механизм работы со списком значений и метод ПоказатьВыборИзМеню.

Разберем реализацию этого подхода по шагам:

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

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


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

&НаКлиенте
Процедура ПослеВыбораИзМеню(ВыбранныйЭлемент, ДополнительныеПараметры) Экспорт
    
    Если ВыбранныйЭлемент = Неопределено Тогда
        Возврат; // Пользователь закрыл меню без выбора
    КонецЕсли;
    
    ПараметрыВыбора = ВыбранныйЭлемент.Значение;
    ВыполнитьЗвонок(ПараметрыВыбора.Телефон);
    
КонецПроцедуры

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

Способ 3. Отдельные процедуры-обработчики для фиксированного набора действий

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


&НаКлиенте
Процедура ДействиеВариант1(Команда)
    ВыполнитьОбщуюЛогику(Параметр1);
КонецПроцедуры

&НаКлиенте
Процедура ДействиеВариант2(Команда)
    ВыполнитьОбщуюЛогику(Параметр2);
КонецПроцедуры

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

← На главную