Как по двойному щелчку на списке документов открыть контекстное меню в 1С

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

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

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

Концепция реализации механизма

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

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

Давайте пошагово разберем весь процесс реализации этой логики на практике.

Шаг 1. Настройка обработчика события динамического списка

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

Выполним следующие действия в конфигураторе:

  1. Откроем нужную управляемую форму списка документов.
  2. Найдем элемент формы типа Таблица (обычно он связан с реквизитом Список).
  3. В панели свойств элемента перейдем к разделу "События".
  4. Найдем событие Выбор и нажмем на кнопку с лупой для создания клиентского обработчика.

Платформа сгенерирует заготовку процедуры. Наша задача в этой процедуре — установить флаг отмены стандартной обработки. Проанализируем пример кода:


&НаКлиенте
Процедура СписокВыбор(Элемент, ВыбраннаяСтрока, Поле, СтандартнаяОбработка)
    
    // 1. Отменяем стандартное открытие карточки документа платформой
    СтандартнаяОбработка = Ложь;
    
    // 2. Вызываем процедуру построения и отображения нашего меню
    ВызватьПрограммноеМеню(Элемент);
    
КонецПроцедуры

Установка параметра СтандартнаяОбработка = Ложь критически важна. Именно она "сообщает" платформе, что стандартный сценарий открытия формы документа выполнять не требуется.

Шаг 2. Программное формирование списка команд и вывод меню

Теперь рассмотрим, как показать пользователю красивое всплывающее меню выбора прямо у выделенной строки. Для этого мы применим метод ПоказатьВыборИзМеню(). Этот метод является немодальным, что полностью соответствует современным стандартам разработки под управляемый интерфейс и веб-клиент.

Опишем процедуру ВызватьПрограммноеМеню на клиенте. Мы создадим вспомогательный объект СписокЗначений, наполним его командами и передадим в метод отображения меню. Также мы настроим механизм обратного вызова (оповещение) для обработки выбора пользователя.


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

Шаг 3. Обработка выбора пользователя

После того как пользователь кликнет по одному из пунктов нашего всплывающего меню (или закроет его кликом в свободную область), платформа вызовет процедуру обратного вызова, которую мы указали в ОписаниеОповещения.

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


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

Динамическое контекстное меню на основе данных строки

Одно из ключевых преимуществ программного формирования меню заключается в возможности динамически изменять состав его пунктов в зависимости от реквизитов выбранного документа. Например, если документ уже проведен, глупо показывать ему пункт "Провести", логичнее предложить команду "Отменить проведение".

Для реализации такой проверки мы можем обратиться к свойству ТекущиеДанные нашей таблицы списка. Рассмотрим улучшенный вариант построения списка команд:


&НаКлиенте
Процедура ВызватьПрограммноеМенюДинамически(Элемент)
    
    СтрокаДанных = Элементы.Список.ТекущиеДанные;
    Если СтрокаДанных = Неопределено Тогда
        Возврат;
    КонецЕсли;
    
    СписокКоманд = Новый СписокЗначений;
    
    // Базовая команда, доступная всегда
    СписокКоманд.Добавить("Открыть", "Открыть");
    
    // Условное добавление команд проведения
    Если СтрокаДанных.Проведен Тогда
        СписокКоманд.Добавить("ОтменитьПроведение", "Отменить проведение");
    Иначе
        СписокКоманд.Добавить("Провести", "Провести документ");
    КонецЕсли;
    
    // Проверка статуса согласования
    Если СтрокаДанных.Статус = ПредопределенноеЗначение("Перечисление.СтатусыДокументов.Черновик") Тогда
        СписокКоманд.Добавить("НаСогласование", "Отправить на согласование");
    КонецЕсли;
    
    Оповещение = Новый ОписаниеОповещения("ПослеВыбораИзМеню", ЭтотОбъект);
    ПоказатьВыборИзМеню(Оповещение, СписокКоманд, Элемент);
    
КонецПроцедуры

Важное примечание: Свойство ТекущиеДанные содержит значения только тех колонок, которые выведены на форму или добавлены в свойствах динамического списка в категорию "Использовать всегда". Если вам необходим реквизит, которого нет на форме, его проверку следует выполнять через серверный вызов.

UI/UX стандарты и альтернативные варианты

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

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

  1. Настройка стандартного контекстного меню таблицы. Вы можете переопределить состав команд, доступных по правой кнопке мыши, непосредственно в свойствах таблицы управляемой формы (раздел "Контекстное меню"). Это сохранит привычное поведение системы.
  2. Вынесение популярных команд на командную панель формы. Разместите в шапке списка кнопку с выпадающим подменю. Это сделает функционал очевидным для всех пользователей без необходимости угадывать неочевидные жесты.
  3. Использование специализированных кнопок в строках списка. Начиная со средних версий платформы 8.3, в таблицах можно размещать графические элементы управления прямо внутри ячеек строк динамического списка.

Тем не менее, в специализированных "АРМ" (автоматизированных рабочих местах) операторов, ориентированных на сверхбыстрый ввод данных или работу с сенсорными экранами без клавиатуры и мыши, подход с двойным тапом для быстрого выбора действия показывает себя как крайне эффективное и эргономичное решение.

← На главную