Свой пункт по правой кнопке мыши: команда формы, общая команда и расширение
Содержание
Чтобы добавить команду в контекстное меню 1С, откройте форму в Конфигураторе, создайте команду на вкладке Команды, а затем перетащите её на вкладке Элементы в подчинённый элемент таблицы с именем вида СписокКонтекстноеМеню. Останется написать обработчик — процедуру, которую 1С вызовет по щелчку.
В типовой конфигурации то же самое делают в расширении, чтобы не снимать её с поддержки. Всё описанное относится к платформе 1С:Предприятие 8.3 и управляемым формам, одинаково для БП 3.0, ЗУП 3.1, УТ 11 и собственных конфигураций.
Как устроено контекстное меню в управляемой форме
У управляемой формы нет одного общего контекстного меню. Своё меню есть у каждой таблицы и у каждого поля ввода. В дереве элементов формы оно видно как отдельный подчинённый элемент:
- 📋
Список→СписокКонтекстноеМенюиСписокКоманднаяПанель— для динамического списка; - 📦
Товары→ТоварыКонтекстноеМеню— для табличной части документа; - ✏️
Контрагент→КонтрагентКонтекстноеМеню— для поля ввода.
Каждое такое меню — это группа кнопок. Свойство Автозаполнение (по умолчанию включено) добавляет в неё стандартные команды: «Добавить», «Скопировать», «Изменить», «Пометить на удаление» и другие. Ваши кнопки встают рядом с ними.
Команда в меню — это всего лишь кнопка, которая ссылается на команду. Сама команда бывает трёх видов:
| Вид команды | Где создаётся | Когда подходит |
|---|---|---|
| Команда формы | Вкладка Команды редактора формы | Нужна только в одной форме |
| Общая команда | Ветка Общие → Общие команды | Одна кнопка для списка, карточки и других форм |
| Программная | Код в ПриСозданииНаСервере | Набор команд меняется по условиям, или форму нельзя трогать |
Способ 1. Команда формы в контекстном меню списка
Самый быстрый путь, если команда нужна в одной форме своей конфигурации или обработки.
Создание команды
- Откройте форму в Конфигураторе, например форму списка документа.
- В правой верхней части редактора перейдите на вкладку
Команды, подвкладкаКоманды формы. - Нажмите «Добавить». Задайте
Имялатиницей или кириллицей без пробелов, напримерСуммаВыделенных, и понятныйЗаголовок— его увидит пользователь. - В свойстве
Действиенажмите кнопку с лупой. Конфигуратор спросит, где создать обработчик, — выберите вариант «Создать на клиенте». В модуле формы появится заготовка процедуры с директивой&НаКлиенте. - При желании задайте
КартинкуиПодсказку. Картинка в контекстном меню выводится слева от текста.
Привязка к контекстному меню
- Перейдите на вкладку
Элементыв левой верхней части редактора. - Разверните таблицу
Список, найдите элементСписокКонтекстноеМеню. - Перетащите команду мышью с вкладки
КомандынаСписокКонтекстноеМеню. Появится кнопка с именем видаСписокКонтекстноеМенюСуммаВыделенных. - Порядок пунктов меняют стрелками на панели дерева элементов или перетаскиванием.
- Чтобы отделить свою команду от стандартных, добавьте в меню группу с видом «Группа кнопок» и положите кнопку в неё — 1С нарисует разделитель.
Если нужна та же команда и на панели над списком, перетащите её ещё раз в СписокКоманднаяПанель. Одна команда может иметь сколько угодно кнопок.
Способ 2. Общая команда для нескольких форм
Общая команда удобна, когда пункт нужен и в списке, и в карточке, и в форме выбора. Код пишется один раз — в модуле самой команды.
Настройка свойств
- В дереве конфигурации откройте
Общие → Общие командыи добавьте новую. - В свойстве
Тип параметра командывыберите тип ссылки, напримерДокументСсылка.РеализацияТоваровУслуг. Можно отметить несколько типов. Режим использования параметра:Одиночный— команда получит одну ссылку,Множественный— массив выделенных строк.Группазадаёт место по умолчанию, напримерКомандная панель формы. Отдельной стандартной группы «контекстное меню» в этом списке нет — в меню команду ставят руками в форме.- Если команда меняет данные, включите свойство
Изменяет данные. Тогда пользователю с правом только на чтение кнопка будет недоступна.
Размещение в контекстном меню
Откройте нужную форму, вкладка Команды → подвкладка Глобальные команды. Там собраны команды, которые подходят к данным формы, сгруппированные по источнику параметра. Найдите свою под источником Список и перетащите её в СписокКонтекстноеМеню — источник параметра подставится сам.
Код общей команды живёт в её модуле:
&НаКлиенте
Процедура ОбработкаКоманды(ПараметрКоманды, ПараметрыВыполненияКоманды)
// При режиме «Множественный» ПараметрКоманды — массив ссылок
Если ПараметрКоманды.Количество() = 0 Тогда
Возврат;
КонецЕсли;
ОткрытьФорму("Обработка.ПроверкаДокументов.Форма",
Новый Структура("Документы", ПараметрКоманды),
ПараметрыВыполненияКоманды.Источник);
КонецПроцедуры
Форма-владелец передаётся третьим параметром, поэтому открытая форма будет связана с той, откуда её вызвали.
Добавление команды в типовую конфигурацию через расширение
В БП 3.0, ЗУП 3.1 или УТ 11 менять форму напрямую — значит снять объект с поддержки и усложнить каждое обновление. Расширения конфигурации появились в платформе 8.3.6 и решают задачу без этого.
- В Конфигураторе:
Конфигурация → Расширения конфигурации, добавьте новое расширение. Назначение —АдаптацияилиДополнение. - В основной конфигурации найдите нужную форму, щёлкните по ней правой кнопкой и выберите «Добавить в расширение». Форма появится в расширении как заимствованная.
- Откройте заимствованную форму в расширении. Дальше всё как в способе 1: новая команда на вкладке
Команды, кнопка вСписокКонтекстноеМеню, обработчик в модуле формы расширения. - Сохраните расширение и обновите его конфигурацию базы данных — это отдельный шаг от сохранения. Перезапустите сеанс 1С:Предприятия.
Расширение по умолчанию работает в безопасном режиме. Простые запросы и открытие форм в нём выполняются, а работа с файлами на диске сервера и внешними компонентами будет запрещена, пока администратор не снимет флаг.
Для своей новой команды обработчик пишется обычной процедурой. Аннотации &Перед, &После и &Вместо нужны только для перехвата существующих типовых процедур.
Готовое расширение можно сохранить в файл .cfe и подключить в рабочей базе без Конфигуратора: Все функции → Стандартные → Управление расширениями конфигурации.
Перед подключением расширения в рабочую базу проверьте его на копии: ошибка в ПриСозданииНаСервере заимствованной формы не даст открыть форму никому.
Код обработчика: как получить строку, на которой щёлкнули
Контекстное меню вызывают на конкретной строке, поэтому почти любой обработчик начинается с вопроса «какая строка?». Ответ зависит от вида таблицы:
- 🔹
Элементы.Список.ТекущаяСтрока— ссылка на текущий объект динамического списка; - 🔹
Элементы.Список.ВыделенныеСтроки— массив ссылок на все выделенные строки; - 🔹
Элементы.Товары.ТекущиеДанные— данные текущей строки табличной части (илиНеопределено, если строк нет).
Пример: команда «Сумма выделенных» для списка реализаций. Пользователь выделяет несколько документов, жмёт правую кнопку — и видит общую сумму.
&НаКлиенте
Процедура СуммаВыделенных(Команда)
Выделенные = Элементы.Список.ВыделенныеСтроки;
Если Выделенные.Количество() = 0 Тогда
ПоказатьПредупреждение(, "Выделите хотя бы один документ.");
Возврат;
КонецЕсли;
Сумма = СуммаДокументовНаСервере(Выделенные);
ПоказатьПредупреждение(, СтрШаблон("Выделено документов: %1. Сумма: %2",
Формат(Выделенные.Количество(), "ЧГ=0"),
Формат(Сумма, "ЧДЦ=2; ЧН=0")));
КонецПроцедуры
&НаСервереБезКонтекста
Функция СуммаДокументовНаСервере(Ссылки)
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ЕСТЬNULL(СУММА(Док.СуммаДокумента), 0) КАК Сумма
|ИЗ
| Документ.РеализацияТоваровУслуг КАК Док
|ГДЕ
| Док.Ссылка В (&Ссылки)";
Запрос.УстановитьПараметр("Ссылки", Ссылки);
Выборка = Запрос.Выполнить().Выбрать();
Выборка.Следующий();
Возврат Выборка.Сумма;
КонецФункции
Серверная функция объявлена &НаСервереБезКонтекста: на сервер уходит только массив ссылок, а не вся форма. Для команды, которая вызывается часто, это заметно быстрее.
Для табличной части проверка другая:
&НаКлиенте
Процедура ПоказатьНоменклатуру(Команда)
ТекущиеДанные = Элементы.Товары.ТекущиеДанные;
Если ТекущиеДанные = Неопределено Тогда
Возврат;
КонецЕсли;
ПоказатьЗначение(, ТекущиеДанные.Номенклатура);
КонецПроцедуры
Если обработчик меняет записанные объекты, после серверного вызова обновите список: Элементы.Список.Обновить().
Команда в табличной части документа
У табличной части есть своя тонкость: строки живут в данных формы, а не в базе. Поэтому обработчик может менять их прямо на клиенте, без серверного вызова: ТекущиеДанные.Количество = 1. Документ при этом станет модифицированным, и 1С предложит его записать.
Если форма открыта только для просмотра (например, документ проведён, а у пользователя нет права на изменение), такая команда должна быть недоступна. Проверьте свойство ТолькоПросмотр формы и таблицы в начале обработчика и выходите из процедуры, если оно включено.
Когда команда добавляет строки или пересчитывает суммы по всей таблице, удобнее вызвать серверную процедуру формы с директивой &НаСервере. Она получит доступ к реквизиту Объект и его табличным частям целиком, а после возврата форма перерисуется сама.
Программное добавление команды в контекстное меню
Иногда форму в Конфигураторе удобнее не трогать, а добавить пункт кодом. Например, когда команд несколько и их список зависит от настроек. Делается это в ПриСозданииНаСервере:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
НоваяКоманда = Команды.Добавить("СуммаВыделенных");
НоваяКоманда.Заголовок = "Сумма выделенных";
НоваяКоманда.Действие = "СуммаВыделенных";
Кнопка = Элементы.Добавить("КнопкаСуммаВыделенных",
Тип("КнопкаФормы"), Элементы.СписокКонтекстноеМеню);
Кнопка.ИмяКоманды = "СуммаВыделенных";
КонецПроцедуры
Свойство Действие — это имя процедуры-обработчика. Процедура СуммаВыделенных(Команда) с директивой &НаКлиенте должна существовать в модуле формы, иначе при щелчке будет ошибка.
Чтобы поставить кнопку не в конец меню, а перед определённым пунктом, используйте Элементы.Вставить(...) — у него есть параметр «элемент, перед которым вставлять».
Видимость и доступность пункта меню
Пункт, который нельзя выполнить, лучше скрыть или сделать серым. Для этого есть четыре рычага.
| Рычаг | Где настроить | Что даёт |
|---|---|---|
| Права роли | Роль → общая команда, право Просмотр | Без права команды в меню нет вообще |
| Функциональная опция | Свойство команды Функциональные опции | Команда пропадает, если опция выключена |
| Код при открытии | ПриСозданииНаСервере | Скрыть по условию: Элементы.КнопкаСуммаВыделенных.Видимость = Ложь |
| Код при смене строки | Событие таблицы ПриАктивизацииСтроки | Делать пункт серым для неподходящих строк |
Проверку роли в коде делают так:
Элементы.КнопкаСуммаВыделенных.Видимость = РольДоступна("ПолныеПрава");
Для доступности по текущей строке не нагружайте сервер. Событие ПриАктивизацииСтроки срабатывает при каждом движении курсора, поэтому проверку откладывают через обработчик ожидания:
&НаКлиенте
Процедура СписокПриАктивизацииСтроки(Элемент)
ПодключитьОбработчикОжидания("ОбновитьДоступностьКоманд", 0.2, Истина);
КонецПроцедуры
&НаКлиенте
Процедура ОбновитьДоступностьКоманд()
ТекущиеДанные = Элементы.Список.ТекущиеДанные;
Элементы.КнопкаСуммаВыделенных.Доступность =
ТекущиеДанные <> Неопределено И ТекущиеДанные.Проведен;
КонецПроцедуры
Поле Проведен должно быть в данных динамического списка. Если его нет среди колонок, отметьте его в настройке списка как используемое всегда.
Свойство кнопки Только во всех действиях прячет её в меню «Ещё» командной панели. Для контекстного меню оно не нужно, но полезно, если ту же команду вы вывели и на панель, а места там мало.
Команда не появилась или не работает: отладка
Запустите отладку из Конфигуратора (Отладка → Начать отладку), поставьте точку останова на первую строку обработчика клавишей F9 и вызовите команду. Если отладчик не остановился, проблема в размещении или правах, а не в коде.
Частые вопросы
Можно ли добавить свою команду в контекстное меню всех списков сразу?
ПриСозданииНаСервере каждой формы.Как вложить несколько команд в подменю?
Можно ли назначить команде горячую клавишу?
Сочетание клавиш. Не занимайте сочетания стандартных команд, например F2, F9 и Ins.Будет ли команда работать в веб-клиенте?
ПоказатьПредупреждение и ПоказатьВопрос, а не Предупреждение и Вопрос.