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

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

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

Понимание проблемы

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

Решение 1: Использование соответствия в реквизите формы

Самым надежным и профессиональным способом является хранение отображения «Имя кнопки — Ссылка на объект» в реквизите формы. Рассмотрим этот метод по шагам:

  1. Создадим реквизит формы с типом Соответствие или ФиксированноеСоответствие.
  2. При создании кнопок в цикле будем записывать в этот реквизит пару: ключ — это уникальное имя кнопки, значение — ссылка на объект (кассу).
  3. В обработчике команды будем определять имя нажатого элемента и извлекать нужную ссылку из нашего соответствия.

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


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

Кмд = ЭтаФорма.Команды.Добавить(ИмяКнопки);
Кмд.Действие = "НажатиеКнопки";
// ... создание элемента управления ...
ЭлементКнопки.ИмяКоманды = ИмяКнопки;
// В конце сохраняем соответствие в реквизит формы
ЭтотОбъект.СоответствиеКасс = Новый ФиксированноеСоответствие(МаппингКасс);

Теперь в обработчике нам достаточно просто обратиться к реквизиту:


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

Решение 2: Анализ имени элемента

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

Посмотрим, как это работает:

  1. Формируем имя кнопки как Кнопка_ + Строка(Ссылка.УникальныйИдентификатор()).
  2. В обработчике получаем имя нажатой кнопки через Элемент.Имя.
  3. Парсим строку, выделяем идентификатор и восстанавливаем ссылку с помощью метода ПолучитьСсылку() соответствующего типа.

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

Решение 3: Альтернатива — Гиперссылки

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

Заключение: что выбрать?

Для большинства задач автоматизации в управляемых формах мы рекомендуем использовать Решение 1 с применением Соответствия в реквизитах формы. Это наиболее предсказуемый и устойчивый подход, который:

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

← На главную