Контекстное меню в управляемой форме 1С: добавляем команду по правой кнопке мыши

· 9 мин

Содержание

Чтобы добавить контекстное меню в 1С, создайте в форме команду, затем перетащите её в узел «Контекстное меню» нужного элемента на закладке «Элементы». Обработчик команды напишите на клиенте. Так делают для таблиц, списков и полей ввода в управляемой форме.

Всё ниже относится к платформе 8.3 с интерфейсом «Такси» и управляемым формам. Нужна ли разработка? Для готовой типовой конфигурации правка форм идёт через расширение: изменять типовую форму напрямую не стоит, при обновлении изменения придётся переносить вручную.

С чего начать: команда, элемент и контекстное меню

В управляемой форме три отдельные сущности, и путаница между ними — частая причина «не работает »:

  • Команда формы — действие с именем, заголовком и обработчиком. Живёт на закладке «Команды».
  • Кнопка — элемент формы, который ссылается на команду. Именно кнопка видна пользователю.
  • Контекстное меню элемента — группа, куда кнопки попадают по правому щелчку мыши. Есть у таблицы, поля ввода, поля табличного документа.

Одну команду можно показать в нескольких местах: в командной панели, в контекстном меню, в подменю. Обработчик при этом один.

Перед началом проверьте две вещи:

  1. Форма управляемая. У обычных форм свой механизм, и описанные ниже шаги к ним не относятся.
  2. Вы работаете в конфигураторе с правом изменения конфигурации либо в расширении.

Если команда нужна только в одной таблице, добавляйте её в контекстное меню этой таблицы. Для действий над всей формой лучше командная панель формы.

Пошагово: как добавить команду в контекстное меню через конфигуратор

Порядок для справочника, документа или обработки:

  1. Откройте форму в конфигураторе. Перейдите на закладку «Команды» и нажмите «Добавить».
  2. Задайте имя без пробелов, например ПоказатьИсторию, и заголовок для пользователя: «Показать историю».
  3. В поле «Действие» нажмите лупу и выберите создание обработчика на клиенте. В модуле формы появится процедура с параметром Команда.
  4. Перейдите на закладку «Элементы». Выделите таблицу или поле, для которого нужно меню.
  5. Откройте свойства элемента и найдите «Контекстное меню». В дереве элементов у таблицы появится дочерний узел «Контекстное меню».
  6. Перетащите команду со вкладки «Команды» в этот узел либо добавьте кнопку и укажите у неё имя команды.
  7. Сохраните и запустите 1С:Предприятие в режиме отладки. Щёлкните правой кнопкой по таблице: пункт должен быть в меню.

Если у меню включено автозаполнение, платформа сама добавляет стандартные команды (копировать, найти, изменить и другие для таблицы). Ваш пункт встанет после них. Чтобы убрать лишнее или собрать меню «с нуля», отключите автозаполнение у контекстного меню и добавьте нужные кнопки вручную.

Если отключить автозаполнение, пропадут и привычные пункты. Пользователи заметят это сразу. Верните нужные стандартные команды кнопками.

Подменю и разделители

Когда пунктов больше пяти-шести, группируйте их. В контекстном меню добавьте группу вида «Подменю» и перетащите в неё команды. Для визуального разделения используйте группу вида «Группа без отображения» внутри меню: пункты внутри остаются рядом, а между группами платформа рисует границу.

Обработка команды: что написать в модуле формы

Обработчик — клиентская процедура. Типовой случай: действие над текущей строкой таблицы.

&НаКлиенте
Процедура ПоказатьИсторию(Команда)

    ТекущиеДанные = Элементы.Список.ТекущиеДанные;
    Если ТекущиеДанные = Неопределено Тогда
        Возврат;
    КонецЕсли;

    ПоказатьПредупреждение(, "Выбрана строка: " + ТекущиеДанные.Наименование);

КонецПроцедуры

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

Если команду нужно применить к нескольким выделенным строкам, берите Элементы.Список.ВыделенныеСтроки. Для динамического списка там лежат ссылки, для таблицы формы на реквизите — идентификаторы строк.

&НаКлиенте
Процедура ОтметитьВыделенные(Команда)

    Для Каждого Строка Из Элементы.Список.ВыделенныеСтроки Цикл
        // здесь Строка — ссылка (динамический список)
        ОтметитьНаСервере(Строка);
    КонецЦикла;

КонецПроцедуры

Обращение к базе из клиентской процедуры в цикле — путь к медленной форме. Если выделенных строк может быть много, передайте на сервер весь массив одним вызовом.

Таблицы значений и списки: чем отличается контекстное меню

Правый щелчок ведёт себя по-разному в зависимости от того, что стоит за таблицей.

Что за таблицейКак получить строкуОсобенность
Динамический списокТекущаяСтрока — ссылка, ТекущиеДанные — поля запросаДанные только для чтения, изменение — через серверный вызов
Табличная часть документаТекущиеДанные — строка коллекцииМожно менять поля прямо в клиентской процедуре
Таблица значений на реквизитеТекущиеДанные или Реквизит.НайтиПоИдентификатору(...)Изменения живут до закрытия формы

Для динамического списка свойство ТекущиеДанные содержит только те поля, которые есть в запросе списка. Нужного поля нет в запросе — обращение даст ошибку «Поле объекта не обнаружено». Добавьте поле в запрос или получите значение с сервера по ссылке.

Когда пункт должен быть доступен не всегда

Часто команда осмысленна не для каждой строки. Управляйте доступностью в обработчике события таблицы ПриАктивизацииСтроки:

&НаКлиенте
Процедура СписокПриАктивизацииСтроки(Элемент)

    Данные = Элементы.Список.ТекущиеДанные;
    Элементы.ПоказатьИсторию.Доступность = (Данные <> Неопределено);

КонецПроцедуры

Здесь ПоказатьИсторию — имя кнопки в контекстном меню. Пункт останется виден, но серый. Если пункт нужно полностью скрывать, используйте свойство Видимость.

Серверные вызовы в ПриАктивизацииСтроки на каждое перемещение курсора делать нельзя: форма начнёт тормозить при прокрутке стрелками. Решайте по данным, которые уже лежат на клиенте.

Программное создание меню: когда набор команд меняется

Если состав пунктов зависит от данных (права, тип объекта, настройки), создавайте их кодом. Команды формы добавляются на сервере при открытии формы.

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)

    Команда = Команды.Добавить("ПоказатьИсторию");
    Команда.Заголовок = "Показать историю";
    Команда.Действие  = "ПоказатьИсторию";

    Кнопка = Элементы.Добавить("ПоказатьИсторию", Тип("КнопкаФормы"),
        Элементы.Список.КонтекстноеМеню);
    Кнопка.ИмяКоманды = "ПоказатьИсторию";

КонецПроцедуры

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

Чтобы собрать подменю, сначала создайте группу:

Группа = Элементы.Добавить("МенюДействия", Тип("ГруппаФормы"),
    Элементы.Список.КонтекстноеМеню);
Группа.Вид = ВидГруппыФормы.Подменю;
Группа.Заголовок = "Действия";

Затем кнопки добавляйте с родителем Группа.

Добавлять и удалять команды и элементы можно только на сервере. Из клиентской процедуры такие вызовы не сработают.

Расширение: добавляем пункт без правки типовой конфигурации

Для типовых БП, ЗУП и УТ действуйте через расширение конфигурации . Алгоритм:

  1. Создайте расширение и добавьте в него нужную форму командой «Расширение формы» (в окне расширения, у объекта).
  2. Добавьте команду и кнопку в контекстное меню так же, как в обычной конфигурации.
  3. Обработчик напишите в модуле расширенной формы. Если нужно вмешаться в стандартное событие, используйте директивы &После или &Перед.
  4. Загрузите расширение в базу и обновите конфигурацию БД. Это два отдельных шага: загрузка сама по себе не применяет изменения.
&После("ПриСозданииНаСервере")
Процедура МоёРасш_ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)

    Элементы.МоёРасш_ПоказатьИсторию.Видимость = ПравоДоступа("Чтение", Метаданные.Справочники.Контрагенты);

КонецПроцедуры

Префикс расширения (МоёРасш_) нужен, чтобы имена не пересеклись с типовыми. Поддержка расширений в платформе есть с 8.3.6, но интерфейс «Такси» и современное поведение форм требуют платформы заметно новее.

Почему не стоит править типовую форму напрямую

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

Второе преимущество: расширение можно отключить одним флажком. Если после выкладки что-то пошло не так, пользователи вернутся к прежней форме без отката всей конфигурации.

Контекстное меню поля ввода и других элементов

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

Типичные задачи для поля ввода:

  • 🔍 открыть связанный объект или отчёт по значению поля;
  • 📋 скопировать значение в нужном формате;
  • ⚙️ заполнить соседние поля по выбранному значению.

В обработчике значение поля берут из реквизита формы, например Объект.Контрагент. Если поле не заполнено, действие лучше отключить через Доступность, а не показывать пользователю сообщение об ошибке.

Мини-случай. В документе есть поле «Договор», и бухгалтер часто открывает договор, чтобы свериться со сроками. Добавьте команду ОткрытьДоговор в контекстное меню этого поля. В обработчике проверьте, что значение не пустое, и откройте форму договора через ПоказатьЗначение(, Объект.Договор). Пользователь экономит четыре клика на каждый документ, а типовая форма остаётся нетронутой, если сделано в расширении.

Куда ещё поставить ту же команду

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

МестоКогда уместно
Контекстное меню таблицыДействие над строкой, которое нужно в процессе просмотра списка
Командная панель таблицыТо же действие, но для пользователей, привыкших к кнопкам
Командная панель формыДействие над документом целиком
Подменю «Ещё»Редкие операции, которые не хочется выносить на видное место

Если команда продублирована в двух местах, меняйте доступность и видимость через общее имя команды. Элементы формы при этом разные: у каждой кнопки своё имя, поэтому свойства придётся выставить у каждой.

Типичные ошибки и что с ними делать

Диагностика: выберите симптом

Что проверить перед выкладкой в рабочую базу

Короткая сверка. Выкладывайте только после неё:

  • пункт виден в нужной таблице и отсутствует там, где он не нужен;
  • команда не падает на пустой таблице и на строке-группе;
  • при выделении нескольких строк обработчик не делает серверный вызов в цикле;
  • заголовок понятен без пояснений: «Показать историю», а не «Команда1»;
  • под пользователем с ограниченными правами форма открывается без ошибок.

Тестируйте на копии базы. Обновление конфигурации БД в рабочей базе делайте вне рабочего времени: пользователям придётся выйти из программы.

Частые вопросы

Можно ли добавить контекстное меню в обычную (неуправляемую) форму?
Да, но механизм другой: меню описывается в самом диалоге формы и привязывается к элементу в его свойствах. Для управляемых форм, которые используются в 8.3, применяйте команды и группу «Контекстное меню».
Чем контекстное меню отличается от командной панели?
Командная панель всегда на виду, контекстное меню появляется по правой кнопке мыши и относится к конкретному элементу. Одну команду можно показать в обоих местах.
Как повесить на команду горячую клавишу?
В свойствах команды есть сочетание клавиш. Назначайте то, что не занято системными действиями платформы и типовых форм, иначе привычный пункт перестанет срабатывать.
Можно ли убрать стандартный пункт из контекстного меню?
Самый надёжный путь: отключите автозаполнение у контекстного меню и добавьте кнопками только нужные команды.
Нужно ли перезапускать клиент после изменения меню?
В режиме отладки достаточно закрыть форму и открыть заново. Для расширения нужно ещё обновить конфигурацию БД.