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