В процессе администрирования типовых решений 1С, таких как 1С:Бухгалтерия предприятия 3.0, часто возникает задача централизовать ведение нормативно-справочной информации (НСИ). Например, необходимо запретить обычным пользователям создавать новые склады, подразделения, организации или контрагентов, оставив им возможность выбирать уже существующие позиции и просматривать их реквизиты. При этом ключевым требованием является сохранение конфигурации на полной поддержке без включения возможности изменения.
Разберем основные практические способы решения этой задачи, выясним их особенности, а также проанализируем типовые ошибки реализации.
Самым правильным и нативным с точки зрения платформы 1С является разделение прав на уровне метаданных. В типовых профилях групп доступа права на чтение и добавление справочников часто объединены в общих ролях. Однако мы можем вынести нужные настройки в отдельное расширение конфигурации без снятия основной конфигурации с поддержки.
Платформа 1С четко разделяет права доступа: Чтение, Просмотр, Добавление, Изменение и Интерактивное добавление. Если у пользователя отобраны права Добавление и Интерактивное добавление, платформа самостоятельно скроет кнопку Создать в формах списков, заблокирует горячую клавишу Insert и отключит команду Скопировать.
Разберем по шагам создание такой настройки:
ТолькоЧтениеСправочниковНСИ.Склады, Организации, Контрагенты) установим флаги Чтение и Просмотр, сняв флаги Добавление, Изменение, Интерактивное добавление и Редактирование.Если гибкая настройка ролей затруднена из-за сложной структуры типовых прав, задачу можно решить программным перехватом записи объекта. Для этого создадим подписку на событие в расширении конфигурации.
Рассмотрим логику работы подписки. Нам необходимо проверять, является ли объект новым, а также проверять наличие специальных прав или вхождение пользователя в определенную группу доступа.
Разберем пример создания роли-маркера и обработчика события ПередЗаписью:
РазрешеноСозданиеЭлементовНСИ и назначим ее только ответственным сотрудникам (например, администраторам НСИ).ЗапретСозданияНовыхЭлементовПередЗаписью, укажем в источнике требуемые справочники и выберем событие ПередЗаписью.
Процедура ЗапретСозданияНовыхЭлементовПередЗаписью(Источник, Отказ) Экспорт
// Обязательно пропускаем фоновые обмены данными и загрузку
Если Источник.ОбменДанными.Загрузка Тогда
Возврат;
КонецЕсли;
// Проверяем, создается ли новый элемент
Если Источник.ЭтоНовый() Тогда
Если НЕ РольДоступна("РазрешеноСозданиеЭлементовНСИ") Тогда
Отказ = Истина;
ВызватьИсключение "У вас недостаточно прав для создания новых элементов справочника. Обратитесь к администратору НСИ!";
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Проанализируем ключевые моменты этого кода:
ЭтоНовый(): Для определения создания нового объекта следует использовать именно функцию ЭтоНовый(). Проверка через ЗначениеЗаполнено(Источник.Ссылка) может работать некорректно, если ссылка была сгенерирована программно до момента физической записи объекта в базу данных.ВызватьИсключение: Использование конструкции ВызватьИсключение прерывает транзакцию и выводит модальное диалоговое окно по центру экрана, что сразу привлекает внимание пользователя и дает однозначный текст ошибки.ОбменДанными.Загрузка: Критически важная строка. Если ее не указать, любые обмены данными (РИБ, синхронизация с 1С:ЗУП, интеграция с банком, загрузка документов через 1С-ЭДО) завершатся аварийной ошибкой при попытке автоматического создания нового контрагента или склада.В дополнение к серверной проверке полезно заблокировать элементы интерфейса, чтобы пользователь не тратил время на заполнение реквизитов нового элемента, который он не сможет записать.
В расширении для формы списка или формы объекта перехватим событие ПриСозданииНаСервере:
&Вместо("ПриСозданииНаСервере")
Процедура Расш1_ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
ПродолжитьВызов(Отказ, СтандартнаяОбработка);
Если НЕ РольДоступна("РазрешеноСозданиеЭлементовНСИ") Тогда
// Блокируем интерактивное создание в форме списка
Элементы.Список.РазрешитьДобавление = Ложь;
Элементы.Список.РазрешитьКопирование = Ложь;
КонецЕсли;
КонецПроцедуры
Иногда в качестве альтернативы предлагают создать триггер INSTEAD OF INSERT или AFTER INSERT непосредственно в таблице SQL Server. Рассмотрим, почему данный подход категорически неприемлем в среде 1С:
Таким образом, наиболее надежным и безопасным решением является комбинация создания роли в расширении конфигурации и контроля события ПередЗаписью с обязательной проверкой свойства ОбменДанными.Загрузка.