При работе в типовой конфигурации «1С:Бухгалтерия предприятия 3.0» часто возникает задача ограничить список складов в документах (например, в документе ПеремещениеТоваров), чтобы рядовой пользователь мог выбрать только тот склад, за который он отвечает или к которому ему предоставлен доступ.
В отличие от крупных ERP-систем, в 1С:БП 3.0 отсутствует встроенный механизм ограничения прав на уровне записей (RLS) по складам. Разберем по шагам, как правильно подгружать только доступные пользователю склады в выпадающие списки формы и какие свойства элементов управления необходимо настроить.
В конфигурации 1С:БП 3.0 связь между текущим пользователем и складом обычно определяется через физическое лицо. Пользователь связан со справочником Пользователи через реквизит ФизическоеЛицо, а ответственные за склады хранятся в регистре сведений ОтветственныеЛица.
Рассмотрим серверную функцию, которая формирует список разрешенных складов для текущего пользователя информационной базы:
&НаСервере
Функция ПолучитьСкладыПоОтветственному()
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ РАЗРЕШЕННЫЕ РАЗЛИЧНЫЕ
| ОтветственныеЛицаСрезПоследних.СтруктурнаяЕдиница КАК Склад
|ИЗ
| РегистрСведений.ОтветственныеЛица.СрезПоследних КАК ОтветственныеЛицаСрезПоследних
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.Пользователи КАК Пользователи
| ПО ОтветственныеЛицаСрезПоследних.ФизическоеЛицо = Пользователи.ФизическоеЛицо
|ГДЕ
| Пользователи.Ссылка = &Пользователь";
Запрос.УстановитьПараметр("Пользователь", ПараметрыСеанса.ТекущийПользователь);
Возврат Запрос.Выполнить().Выгрузить().ВыгрузитьКолонку("Склад");
КонецФункции
Если с одним складом должны работать сразу несколько пользователей или структура ответственности отличается от штатного регистра ОтветственныеЛица, можно использовать отдельный справочник (например, СкладыДоступ) с реквизитами Склад и ФизическоеЛицо.
Проанализируем пример запроса для такой структуры данных:
&НаСервере
Функция ПолучитьСкладыПоДоступу()
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ РАЗЛИЧНЫЕ
| СкладыДоступ.Склад КАК Склад
|ИЗ
| Справочник.СкладыДоступ КАК СкладыДоступ
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.Пользователи КАК Пользователи
| ПО СкладыДоступ.ФизическоеЛицо = Пользователи.ФизическоеЛицо
|ГДЕ
| Пользователи.Ссылка = &Пользователь";
Запрос.УстановитьПараметр("Пользователь", ПараметрыСеанса.ТекущийПользователь);
Возврат Запрос.Выполнить().Выгрузить().ВыгрузитьКолонку("Склад");
КонецФункции
Чтобы список доступных складов подставлялся при клике на поле ввода (например, СкладОтправитель), перехватим события НачалоВыбора и НачалоВыбораИзСписка. Для администраторов и пользователей с полными правами ограничение применять не нужно, поэтому добавим проверку роли РольДоступна("ПолныеПрава").
Посмотрим, как выглядит клиентский код обработки подстановки значений:
&НаКлиенте
Процедура СкладОтправительНачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка)
Если ПолныеПрава() Тогда
Возврат;
КонецЕсли;
СтандартнаяОбработка = Ложь;
ДанныеВыбора = Новый СписокЗначений;
ДанныеВыбора.ЗагрузитьЗначения(ПолучитьСкладыПоОтветственному());
КонецПроцедуры
&НаКлиенте
Процедура СкладОтправительНачалоВыбораИзСписка(Элемент, СтандартнаяОбработка)
СкладОтправительНачалоВыбора(Элемент, СтандартнаяОбработка);
КонецПроцедуры
&НаСервере
Функция ПолныеПрава()
Возврат РольДоступна("ПолныеПрава");
КонецФункции
Даже при перехвате событий выбора платформа 8.3 может показывать пользователю недоступные склады из истории ввода или через подсказки при вводе по строке. Чтобы исключить выбор «чужих» складов, настройте свойства реквизита формы в конфигураторе или в модуле формы:
Истина.Не использовать (ИспользоватьИсториюВыбораПриВводе.НеИспользовать). Это отключит подсказки из ранее сохраненного ввода платформы.Ложь (чтобы нельзя было перейти в справочник без прав).Ложь (чтобы исключить создание новых складов из формы документа).Помните, что любые ограничения, заданные только на уровне формы, можно обойти с помощью обработки или внешних механизмов. Для надежной защиты данных рекомендуется дополнительно проверять соответствие выбранного склада и текущего пользователя в модуле объекта документа в событии ПередЗаписью.