Как запретить выбор упаковки конкретным пользователям в документах 1С?

Программист 1С v8.3 (Управляемые формы) Управленческий учет Торговля и дистрибуция
← На главную

В процессе автоматизации торговых операций часто возникает задача разграничения прав не только на уровне целых документов или справочников, но и на уровне конкретных реквизитов табличных частей. Одной из таких задач является запрет выбора упаковок (единиц измерения с коэффициентом, отличным от единицы) для определенных категорий сотрудников. Например, это может быть актуально для поваров или рядовых сотрудников склада, которые должны работать только с базовыми единицами измерения («штуки», «кг»), чтобы избежать ошибок при вводе данных. Рассмотрим подробнее, как реализовать этот механизм в современных конфигурациях на платформе 1С:Предприятие 8.3.

Метод 1. Использование расширений и событий формы

Проанализируем наиболее гибкий и современный способ — внесение изменений через расширение конфигурации. Этот метод позволяет не снимать основную конфигурацию с поддержки. Нам необходимо перехватить момент выбора упаковки на форме документа (например, ПриобретениеТоваровУслуг или РеализацияТоваровУслуг).

Разберем логику реализации. Нам потребуется расширить форму документа и создать обработчик события ПриИзменении для колонки Упаковка. В этом обработчике мы будем проверять текущего пользователя. Выясним причину ошибки: если пользователь входит в список «ограниченных», а выбранная упаковка не является базовой, мы должны вернуть значение в исходное состояние или очистить его.

Пример кода для модуля формы в расширении:


&НаКлиенте
Процедура Расш1_ТоварыУпаковкаПриИзмененииПосле(Элемент)
    ТекущиеДанные = Элементы.Товары.ТекущиеДанные;
    Если ТекущиеДанные = Неопределено Тогда
        Возврат;
    КонецЕсли;
    
    // Проверяем права пользователя на сервере
    Если ПроверитьЗапретИспользованияУпаковок() Тогда
        Если ЗначениеЗаполнено(ТекущиеДанные.Упаковка) Тогда
            // Если упаковка выбрана, проверяем её коэффициент через серверный вызов
            Если ПолучитьКоэффициентУпаковки(ТекущиеДанные.Упаковка) <> 1 Тогда
                ОбщегоНазначенияКлиентСервер.СообщитьПользователю("Вам запрещено выбирать упаковки с коэффициентом отличным от 1!");
                ТекущиеДанные.Упаковка = Справочники.УпаковкиЕдиницыИзмерения.ПустаяСсылка();
                // При необходимости вызываем штатный пересчет документа
                РассчитатьСуммуТабличнойЧасти(ТекущиеДанные);
            КонецЕсли;
        КонецЕсли;
    КонецЕсли;
КонецПроцедуры

Метод 2. Ограничение прав на уровне записей (RLS)

Посмотрим на ситуацию со стороны прав доступа. Если мы хотим, чтобы пользователи в принципе не видели список доступных упаковок, можно применить механизм RLS (Row Level Security). В этом случае ограничение накладывается непосредственно на справочник Упаковки (или НаборыУпаковок в зависимости от конфигурации).

Для реализации этого метода выполним следующие шаги:

  1. Создадим новый профиль групп доступа или отредактируем существующий для целевых пользователей.
  2. В роли, отвечающей за чтение упаковок, добавим условие ограничения доступа.
  3. Пропишем запрос, который будет возвращать пустой результат для определенных пользователей или групп пользователей.

Важный момент: использование RLS может существенно снизить производительность системы, если запросы к базе данных станут слишком сложными. Однако для справочника упаковок, который обычно невелик, это допустимое решение. Главный плюс — пользователю даже не будет предложен выбор в выпадающем списке.

Метод 3. Программная настройка условного оформления

Рассмотрим вариант, при котором мы не хотим менять логику проведения или записи, а хотим лишь визуально ограничить доступ к полю на форме. Это можно сделать через УсловноеОформление или просто программно управляя свойством ТолькоПросмотр.

В процедуре ПриСозданииНаСервере проанализируем текущего пользователя и, если он попадает под критерии запрета, заблокируем колонку:


&НаСервере
Процедура БлокировкаКолонкиУпаковок()
    // Проверка принадлежности к роли или списку пользователей
    Если ПользователиИнформационнойБазы.ТекущийПользователь().Имя = "ШефПовар" Тогда
        ЭлементФормы = Элементы.ТоварыУпаковка;
        ЭлементФормы.ТолькоПросмотр = Истина;
        
        // Также можно скрыть колонку вовсе
        // ЭлементФормы.Видимость = Ложь;
    КонецЕсли;
КонецПроцедуры

Этот метод считается «мягким», так как он не защищает от записи данных, загруженных, например, через внешние обработки или механизмы обмена, но эффективно работает для обычного интерфейсного ввода.

Метод 4. Подписка на событие ПередЗаписью (Жесткий контроль)

Чтобы гарантировать 100% соблюдение регламента, независимо от того, как данные попали в документ, необходимо реализовать проверку на уровне объекта. Для этого лучше всего использовать Подписку на событие ПередЗаписью для необходимых типов документов.

Разберем алгоритм работы такой подписки:

  1. Система перехватывает попытку записи документа.
  2. Проверяется автор документа или текущий пользователь.
  3. Производится обход табличной части Товары.
  4. Если найдена строка, где заполнена упаковка с коэффициентом не равным 1, транзакция записи отменяется.

Пример реализации в модуле подписки:


Процедура ПроверитьУпаковкиПередЗаписью(Источник, Отказ, РежимЗаписи, РежимПроведения) Экспорт
    Если Отказ Или Источник.ОбменДанными.Загрузка Тогда
        Возврат;
    КонецЕсли;

    // Определяем, нужно ли проверять этого пользователя
    Если НужноКонтролироватьПользователя(ПараметрыСеанса.ТекущийПользователь) Тогда
        Для Каждого СтрокаТЧ Из Источник.Товары Цикл
            Если ЗначениеЗаполнено(СтрокаТЧ.Упаковка) Тогда
                // Проверяем коэффициент через реквизиты упаковки
                Коэффициент = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(СтрокаТЧ.Упаковка, "Коэффициент");
                Если Коэффициент <> 1 Тогда
                    Сообщение = Новый СообщениеПользователю;
                    Сообщение.Текст = "Строка №" + СтрокаТЧ.НомерСтроки + ": Использование упаковок запрещено!";
                    Сообщение.Поле = "Товары[" + (СтрокаТЧ.НомерСтроки - 1) + "].Упаковка";
                    Сообщение.УстановитьДанные(Источник);
                    Сообщение.Сообщить();
                    Отказ = Истина;
                КонецЕсли;
            КонецЕсли;
        КонецЦикла;
    КонецЕсли;
КонецПроцедуры

Метод 5. Административное скрытие через «Изменить форму»

Выясним, можно ли решить задачу без программирования. В платформе 1С предусмотрена возможность настройки видимости элементов для конкретных ролей. Если в конфигурации создана специальная роль для этих двух пользователей (например, Роль_БезПраваУпаковок), администратор может зайти в настройки формы документа и в разделе «Права» снять видимость с колонки Упаковка для этой роли.

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

Резюме

Для надежного решения задачи рекомендуется комбинировать подходы: визуально скрывать поле через условное оформление или настройки формы для удобства пользователя и дублировать проверку в подписке на событие ПередЗаписью для обеспечения целостности данных. Использование расширений позволит сохранить чистоту типовой конфигурации и обеспечит легкое обновление системы в будущем.

← На главную