Контекстное меню в управляемой форме 1С: добавляем команду по правой кнопке мыши
Содержание
Чтобы добавить контекстное меню в 1С, создайте в форме команду, затем перетащите её в узел «Контекстное меню» нужного элемента на закладке «Элементы». Обработчик команды напишите на клиенте. Так делают для таблиц, списков и полей ввода в управляемой форме.
Всё ниже относится к платформе 8.3 с интерфейсом «Такси» и управляемым формам. Нужна ли разработка? Для готовой типовой конфигурации правка форм идёт через расширение: изменять типовую форму напрямую не стоит, при обновлении изменения придётся переносить вручную.
С чего начать: команда, элемент и контекстное меню
В управляемой форме три отдельные сущности, и путаница между ними — частая причина «не работает »:
- Команда формы — действие с именем, заголовком и обработчиком. Живёт на закладке «Команды».
- Кнопка — элемент формы, который ссылается на команду. Именно кнопка видна пользователю.
- Контекстное меню элемента — группа, куда кнопки попадают по правому щелчку мыши. Есть у таблицы, поля ввода, поля табличного документа.
Одну команду можно показать в нескольких местах: в командной панели, в контекстном меню, в подменю. Обработчик при этом один.
Перед началом проверьте две вещи:
- Форма управляемая. У обычных форм свой механизм, и описанные ниже шаги к ним не относятся.
- Вы работаете в конфигураторе с правом изменения конфигурации либо в расширении.
Если команда нужна только в одной таблице, добавляйте её в контекстное меню этой таблицы. Для действий над всей формой лучше командная панель формы.
Пошагово: как добавить команду в контекстное меню через конфигуратор
Порядок для справочника, документа или обработки:
- Откройте форму в конфигураторе. Перейдите на закладку «Команды» и нажмите «Добавить».
- Задайте имя без пробелов, например
ПоказатьИсторию, и заголовок для пользователя: «Показать историю». - В поле «Действие» нажмите лупу и выберите создание обработчика на клиенте. В модуле формы появится процедура с параметром
Команда. - Перейдите на закладку «Элементы». Выделите таблицу или поле, для которого нужно меню.
- Откройте свойства элемента и найдите «Контекстное меню». В дереве элементов у таблицы появится дочерний узел «Контекстное меню».
- Перетащите команду со вкладки «Команды» в этот узел либо добавьте кнопку и укажите у неё имя команды.
- Сохраните и запустите 1С:Предприятие в режиме отладки. Щёлкните правой кнопкой по таблице: пункт должен быть в меню.
Если у меню включено автозаполнение, платформа сама добавляет стандартные команды (копировать, найти, изменить и другие для таблицы). Ваш пункт встанет после них. Чтобы убрать лишнее или собрать меню «с нуля», отключите автозаполнение у контекстного меню и добавьте нужные кнопки вручную.
Если отключить автозаполнение, пропадут и привычные пункты. Пользователи заметят это сразу. Верните нужные стандартные команды кнопками.
Подменю и разделители
Когда пунктов больше пяти-шести, группируйте их. В контекстном меню добавьте группу вида «Подменю» и перетащите в неё команды. Для визуального разделения используйте группу вида «Группа без отображения» внутри меню: пункты внутри остаются рядом, а между группами платформа рисует границу.
Обработка команды: что написать в модуле формы
Обработчик — клиентская процедура. Типовой случай: действие над текущей строкой таблицы.
&НаКлиенте
Процедура ПоказатьИсторию(Команда)
ТекущиеДанные = Элементы.Список.ТекущиеДанные;
Если ТекущиеДанные = Неопределено Тогда
Возврат;
КонецЕсли;
ПоказатьПредупреждение(, "Выбрана строка: " + ТекущиеДанные.Наименование);
КонецПроцедуры
Проверка на Неопределено обязательна. Пользователь может вызвать меню, когда строк в таблице нет или курсор стоит на группе.
Если команду нужно применить к нескольким выделенным строкам, берите Элементы.Список.ВыделенныеСтроки. Для динамического списка там лежат ссылки, для таблицы формы на реквизите — идентификаторы строк.
&НаКлиенте
Процедура ОтметитьВыделенные(Команда)
Для Каждого Строка Из Элементы.Список.ВыделенныеСтроки Цикл
// здесь Строка — ссылка (динамический список)
ОтметитьНаСервере(Строка);
КонецЦикла;
КонецПроцедуры
Обращение к базе из клиентской процедуры в цикле — путь к медленной форме. Если выделенных строк может быть много, передайте на сервер весь массив одним вызовом.
Таблицы значений и списки: чем отличается контекстное меню
Правый щелчок ведёт себя по-разному в зависимости от того, что стоит за таблицей.
| Что за таблицей | Как получить строку | Особенность |
|---|---|---|
| Динамический список | ТекущаяСтрока — ссылка, ТекущиеДанные — поля запроса | Данные только для чтения, изменение — через серверный вызов |
| Табличная часть документа | ТекущиеДанные — строка коллекции | Можно менять поля прямо в клиентской процедуре |
| Таблица значений на реквизите | ТекущиеДанные или Реквизит.НайтиПоИдентификатору(...) | Изменения живут до закрытия формы |
Для динамического списка свойство ТекущиеДанные содержит только те поля, которые есть в запросе списка. Нужного поля нет в запросе — обращение даст ошибку «Поле объекта не обнаружено». Добавьте поле в запрос или получите значение с сервера по ссылке.
Когда пункт должен быть доступен не всегда
Часто команда осмысленна не для каждой строки. Управляйте доступностью в обработчике события таблицы ПриАктивизацииСтроки:
&НаКлиенте
Процедура СписокПриАктивизацииСтроки(Элемент)
Данные = Элементы.Список.ТекущиеДанные;
Элементы.ПоказатьИсторию.Доступность = (Данные <> Неопределено);
КонецПроцедуры
Здесь ПоказатьИсторию — имя кнопки в контекстном меню. Пункт останется виден, но серый. Если пункт нужно полностью скрывать, используйте свойство Видимость.
Серверные вызовы в ПриАктивизацииСтроки на каждое перемещение курсора делать нельзя: форма начнёт тормозить при прокрутке стрелками. Решайте по данным, которые уже лежат на клиенте.
Программное создание меню: когда набор команд меняется
Если состав пунктов зависит от данных (права, тип объекта, настройки), создавайте их кодом. Команды формы добавляются на сервере при открытии формы.
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
Команда = Команды.Добавить("ПоказатьИсторию");
Команда.Заголовок = "Показать историю";
Команда.Действие = "ПоказатьИсторию";
Кнопка = Элементы.Добавить("ПоказатьИсторию", Тип("КнопкаФормы"),
Элементы.Список.КонтекстноеМеню);
Кнопка.ИмяКоманды = "ПоказатьИсторию";
КонецПроцедуры
В свойстве Действие пишется имя клиентской процедуры формы. Она должна существовать в модуле и иметь параметр Команда: иначе при щелчке получите ошибку вызова.
Чтобы собрать подменю, сначала создайте группу:
Группа = Элементы.Добавить("МенюДействия", Тип("ГруппаФормы"),
Элементы.Список.КонтекстноеМеню);
Группа.Вид = ВидГруппыФормы.Подменю;
Группа.Заголовок = "Действия";
Затем кнопки добавляйте с родителем Группа.
Добавлять и удалять команды и элементы можно только на сервере. Из клиентской процедуры такие вызовы не сработают.
Расширение: добавляем пункт без правки типовой конфигурации
Для типовых БП, ЗУП и УТ действуйте через расширение конфигурации . Алгоритм:
- Создайте расширение и добавьте в него нужную форму командой «Расширение формы» (в окне расширения, у объекта).
- Добавьте команду и кнопку в контекстное меню так же, как в обычной конфигурации.
- Обработчик напишите в модуле расширенной формы. Если нужно вмешаться в стандартное событие, используйте директивы
&Послеили&Перед. - Загрузите расширение в базу и обновите конфигурацию БД. Это два отдельных шага: загрузка сама по себе не применяет изменения.
&После("ПриСозданииНаСервере")
Процедура МоёРасш_ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
Элементы.МоёРасш_ПоказатьИсторию.Видимость = ПравоДоступа("Чтение", Метаданные.Справочники.Контрагенты);
КонецПроцедуры
Префикс расширения (МоёРасш_) нужен, чтобы имена не пересеклись с типовыми. Поддержка расширений в платформе есть с 8.3.6, но интерфейс «Такси» и современное поведение форм требуют платформы заметно новее.
Почему не стоит править типовую форму напрямую
Правка типовой формы ставит конфигурацию «на изменение». Потом при каждом обновлении релиза вы объединяете свои правки с новой версией формы, разбираете конфликты и рискуете потерять часть доработки. Расширение живёт отдельно: обновление типовой конфигурации его не затрагивает, а при несовместимости платформа покажет, какие объекты расширения не применились.
Второе преимущество: расширение можно отключить одним флажком. Если после выкладки что-то пошло не так, пользователи вернутся к прежней форме без отката всей конфигурации.
Контекстное меню поля ввода и других элементов
Не только таблицы. Контекстное меню есть у поля ввода, поля флажка, поля табличного документа и у группы. Принцип тот же: команда, кнопка, узел «Контекстное меню» у элемента.
Типичные задачи для поля ввода:
- 🔍 открыть связанный объект или отчёт по значению поля;
- 📋 скопировать значение в нужном формате;
- ⚙️ заполнить соседние поля по выбранному значению.
В обработчике значение поля берут из реквизита формы, например Объект.Контрагент. Если поле не заполнено, действие лучше отключить через Доступность, а не показывать пользователю сообщение об ошибке.
Мини-случай. В документе есть поле «Договор», и бухгалтер часто открывает договор, чтобы свериться со сроками. Добавьте команду ОткрытьДоговор в контекстное меню этого поля. В обработчике проверьте, что значение не пустое, и откройте форму договора через ПоказатьЗначение(, Объект.Договор). Пользователь экономит четыре клика на каждый документ, а типовая форма остаётся нетронутой, если сделано в расширении.
Куда ещё поставить ту же команду
Одна команда формы может быть кнопкой сразу в нескольких местах. Это удобно, когда действие нужно и из контекстного меню, и с панели:
| Место | Когда уместно |
|---|---|
| Контекстное меню таблицы | Действие над строкой, которое нужно в процессе просмотра списка |
| Командная панель таблицы | То же действие, но для пользователей, привыкших к кнопкам |
| Командная панель формы | Действие над документом целиком |
| Подменю «Ещё» | Редкие операции, которые не хочется выносить на видное место |
Если команда продублирована в двух местах, меняйте доступность и видимость через общее имя команды. Элементы формы при этом разные: у каждой кнопки своё имя, поэтому свойства придётся выставить у каждой.
Типичные ошибки и что с ними делать
&НаКлиенте) с одним параметром. Опечатка в имени даёт ошибку только при выполнении.Что проверить перед выкладкой в рабочую базу
Короткая сверка. Выкладывайте только после неё:
- пункт виден в нужной таблице и отсутствует там, где он не нужен;
- команда не падает на пустой таблице и на строке-группе;
- при выделении нескольких строк обработчик не делает серверный вызов в цикле;
- заголовок понятен без пояснений: «Показать историю», а не «Команда1»;
- под пользователем с ограниченными правами форма открывается без ошибок.
Тестируйте на копии базы. Обновление конфигурации БД в рабочей базе делайте вне рабочего времени: пользователям придётся выйти из программы.