В процессе разработки интерфейсов на платформе 1С:Предприятие часто возникает задача ограничить действия пользователя с табличными частями или списками. Одной из самых востребованных задач является скрытие кнопки Удалить. При этом разработчики часто сталкиваются с тем, что команда исчезает из верхней командной панели, но остается доступной при нажатии правой кнопкой мыши (в контекстном меню). Разберем по шагам все способы решения этой задачи: от административных до программных.
Прежде чем приступать к написанию кода, проанализируем архитектуру безопасности системы. Наиболее правильным и надежным методом является настройка ролей в конфигураторе. Если пользователю в принципе запрещено удалять записи данного типа, платформа сама позаботится о том, чтобы команда не появилась ни в одном меню.
Рассмотрим, как это реализовать:
Важный нюанс: если мы убираем это право, команда Удалить исчезнет автоматически из всех контекстных меню и командных панелей по всей системе. Это избавляет от необходимости прописывать код в каждой форме.
Если нам нужно убрать команду только в конкретной форме, не меняя глобальных прав пользователя, проанализируем свойства элементов формы. По умолчанию для таблиц включено свойство Автозаполнение.
Разберем алгоритм настройки в конфигураторе:
ИмяТаблицыКонтекстноеМеню).После этого контекстное меню станет абсолютно пустым. Теперь мы можем вручную добавить туда только те команды, которые считаем нужными, просто перетащив их из списка команд формы. Этот способ хорош тем, что он статический и не требует выполнения кода при открытии формы.
Часто возникает ситуация, когда решение о доступности удаления нужно принимать динамически, в зависимости от условий. В этом случае рассмотрим программное обращение к элементам контекстного меню. Как правильно отметил участник форума, обращаться нужно к подчиненным элементам самого меню.
Выясним причину, по которой обычное скрытие из командной панели не помогает: контекстное меню — это отдельный объект в коллекции элементов формы. Напишем код в процедуре ПриСозданииНаСервере:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
// Скрываем команду удаления в контекстном меню таблицы "Товары"
// Имя элемента обычно строится по принципу: [ИмяТаблицы]КонтекстноеМенюУдалить
ЭлементМеню = Элементы.Товары.КонтекстноеМеню.ПодчиненныеЭлементы.ТоварыКонтекстноеМенюУдалить;
ЭлементМеню.Видимость = Ложь;
КонецПроцедуры
Обратите внимание на свойство Видимость. Если мы установим его в значение Ложь, команда полностью пропадет. Если же использовать Доступность = Ложь, команда останется в списке, но будет серой (неактивной). Это полезно, если нужно дать пользователю понять, что функция в принципе существует, но сейчас она недоступна.
Иногда нам нужно запретить удаление не для всей таблицы, а только для определенных строк (например, нельзя удалять уже предопределенные данные или заблокированные позиции). В таком случае программный код следует размещать в обработчике события ПриАктивизацииСтроки на клиенте.
Посмотрим на пример реализации:
&НаКлиенте
Процедура ТоварыПриАктивизацииСтроки(Элемент)
ТекущиеДанные = Элементы.Товары.ТекущиеДанные;
Если ТекущиеДанные = Неопределено Тогда
Возврат;
КонецЕсли;
// Допустим, в строке есть флаг "ЗапретРедактирования"
Блокировка = ТекущиеДанные.ЗапретРедактирования;
// Управляем доступностью команды удаления
Элементы.ТоварыКонтекстноеМенюУдалить.Доступность = НЕ Блокировка;
КонецПроцедуры
Внимание: частое изменение свойств элементов в этом событии может привести к небольшим задержкам интерфейса («миганию»), поэтому используйте этот метод осмотрительно.
В сложных формах или при использовании расширений имена элементов контекстного меню могут отличаться от стандартных. Проанализируем ситуацию, когда мы не знаем точного имени элемента. В этом случае мы можем обойти все элементы меню в цикле и найти нужный по имени связанной команды.
&НаСервере
Процедура СкрытьУдалениеУниверсально(ИмяТаблицы)
Меню = Элементы[ИмяТаблицы].КонтекстноеМеню;
Для Каждого Элемент Из Меню.ПодчиненныеЭлементы Цикл
// Проверяем, связана ли кнопка со стандартной командой удаления
Если Найти(Элемент.Имя, "Удалить") > 0 Тогда
Элемент.Видимость = Ложь;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Мы рассмотрели несколько подходов к управлению контекстным меню. Подведем итоги, какой метод выбрать в зависимости от ситуации:
Автозаполнение и добавляйте кнопки вручную.ПриСозданииНаСервере и свойство Видимость.ПриАктивизацииСтроки.Помните, что в веб-клиенте отрисовка меню может иметь свои особенности, поэтому программное управление на сервере (Способ 3) является самым стабильным и универсальным решением для всех типов клиентов 1С.