Использование ограничений доступа к данным для различных объектов 1С:Предприятия 8

Этот раздел содержит информацию об особенностях использования ограничений доступа к данным, определяемых поведением различных объектов 1С:Предприятия.

О принципах функционирования ограничений доступа к данным

Основные принципы функционирования и использования ограничений доступа к данным описаны в документации 1С:Предприятия 8 и в разделе "Ограничения доступа к данным. Сведения о принципах функционирования".

Для лучшего понимания механизма проверки ограничений доступа полезно иметь в виду следующие правила:

Приведем несколько примеров.

Например, в случае простейшего ограничения вида:

Копировать в буфер обмена

ГДЕ Реквизит = &ПравильноеЗначениеРеквизита

можно считать, что для каждой записи, для которой проверяется ограничение(проверяемой записи), выполняется запрос следующего вида:

Копировать в буфер обмена

ВЫБРАТЬ 1
ИЗ ТаблицаИзОднойПроверяемойЗаписи
ГДЕ Реквизит = &ПравильноеЗначениеРеквизита

В данной таблице доступ к записи, в которой значение реквизита "Реквизит" совпадает со значением параметра сеанса "ПравильноеЗначениеРеквизита", разрешен. К другим записям этой таблицы доступ запрещен.

Другой пример. Усложним ограничение. Допустим нужно разрешить доступ к записи таблицы "Справочник.Контрагенты" не только если ее "Реквизит" имеет "правильное значение", но и в том случае, если "правильное значение" имеет "Реквизит" родителя этой записи (1-го или 2-го уровня). В этом случае ограничение может иметь следующий вид:

Копировать в буфер обмена

Контрагенты
ИЗ Справочник.Контрагенты КАК Контрагенты
ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Контрагенты КАК Контрагенты1
ПО Контрагенты.Родитель = Контрагенты1.Ссылка
ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Контрагенты КАК Контрагенты2
ПО Контрагенты1.Родитель = Контрагенты2.Ссылка
ГДЕ Контрагенты.Реквизит = &ПравильноеЗначениеРеквизита ИЛИ Контрагенты1.Реквизит = &ПравильноеЗначениеРеквизита ИЛИ Контрагенты2.Реквизит = &ПравильноеЗначениеРеквизита

Тогда запрос, который будет выполнятся в процессе проверки этого ограничения для конкретной записи справочника "Контрагенты", будет иметь вид:

Копировать в буфер обмена

ВЫБРАТЬ 1
ИЗ ТаблицаИзОднойПроверяемойЗаписи КАК Контрагенты
ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Контрагенты КАК Контрагенты1
ПО Контрагенты.Родитель = Контрагенты1.Ссылка
ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Контрагенты КАК Контрагенты2
ПО Контрагенты1.Родитель = Контрагенты2.Ссылка
ГДЕ Контрагенты.Реквизит = &ПравильноеЗначениеРеквизита ИЛИ Контрагенты1.Реквизит = &ПравильноеЗначениеРеквизита ИЛИ Контрагенты2.Реквизит = &ПравильноеЗначениеРеквизита 

Обращения по ссылкам в запросах и ограничения доступа к данным

При установке ограничений доступа к данным важно понимать, что ограничение проверяется при обращении к записи той таблицы базы данных, к которой относится ограничение. При этом если выполняется запрос к данным с ключевым словом РАЗРЕШЕННЫЕ, то запрет доступа к некоторой записи означает, что при выполнении этого запроса будет считаться, что эта запись таблицы базы данных (не результата запроса) отсутствует.

Например.

Пусть на справочник "Контрагенты" установлено следующее ограничение доступа:

Копировать в буфер обмена

ГДЕ Ответственный = &ТекущийПользователь

а сам справочник содержит такие записи:

Имя
(строка)

Ответственный
(ссылка на Справочник.Пользователи)

Завод имени Лапкина Иванов
Пекарня Косолапова Любимов
Электроламповый завод Иванов
Трикотажная фабрика Генералов

Пусть регистр сведений "КонтактнаяИнформация" содержит следующие записи:

КонтактноеЛицо
(ссылка на Справочник.ФизЛица)

Организация
(ссылка на Справочник.Контрагенты)

Зайкин А. В. Завод имени Лапкина
Тонков Т. А. Пекарня Косолапова
Петров А. А. Электроламповый завод
Сидоров И. И. Трикотажная фабрика

Тогда если текущим пользователем является пользователь "Иванов", то результатом запроса:

Копировать в буфер обмена

ВЫБРАТЬ РАЗРЕШЕННЫЕ Имя, Ответственный
ИЗ Справочник.Контрагенты

будет таблица:

Имя
(строка)

Ответственный
(ссылка на Справочник.Пользователи)

Завод имени Лапкина Иванов
Электроламповый завод Иванов

Однако, результатом следующего запроса:

Копировать в буфер обмена

ВЫБРАТЬ РАЗРЕШЕННЫЕ КонтактноеЛицо, Организация
ИЗ РегистрСведений.КонтактнаяИнформация

будет таблица:

КонтактноеЛицо

Организация

Зайкин А. В. Завод имени Лапкина
Тонков Т. А. <Объект не найден> ...
Петров А. А. Электроламповый завод
Сидоров И. И. <Объект не найден> ...

поскольку записи:

Имя
(строка)

Ответственный
(ссылка на Справочник.Пользователи)

Пекарня Косолапова Любимов
Трикотажная фабрика Генералов

противоречат ограничению, и поэтому считаются отсутствующими, а представление непустой ссылки на несуществующую запись равно "<Объект не найден> ...". В то же время, результатом запроса:

Копировать в буфер обмена

ВЫБРАТЬ РАЗРЕШЕННЫЕ КонтактноеЛицо, Организация.Имя КАК Имя, Организация.Ответственный КАК Ответственный
ИЗ РегистрСведений.КонтактнаяИнформация

будет таблица

КонтактноеЛицо

Имя

Ответственный

Зайкин А. В. Завод имени Лапкина Иванов
Тонков Т. А.    
Петров А. А. Электроламповый завод Иванов
Сидоров И. И.    

поскольку противоречащие ограничению записи справочника "Контрагенты" считаются отсутствующими, а значениями полей "Имя" и "Ответственный" по ссылкам, указывающим на несуществующие записи, является значение NULL.

Если же необходимо по тому же признаку ограничить доступ к записям регистра сведений "КонтактнаяИнформация", то на этот регистр можно наложить ограничение вида:

Копировать в буфер обмена

ГДЕ Организация.Ответственный = &ТекущийПользователь

В этом случае результатом выполнения последнего запроса будет таблица:

КонтактноеЛицо

Имя

Ответственный

Зайкин А. В. Завод имени Лапкина Иванов
Петров А. А. Электроламповый завод Иванов

Ограничения и табличные части

Ограничения доступа к данным действуют только на записи таблиц верхнего уровня и не могут ограничивать доступность записей табличных частей. С другой стороны, в тексте ограничения поля табличных частей использоваться могут. В этом случае в процессе проверки ограничения для некоторой записи будет исполнен запрос, в котором табличная часть будет соединена с таблицей из одной проверяемой записи левым внешнем соединением. Таким образом запись будет удовлетворять ограничению, если в ее табличной части найдется хотя бы одна запись, для которой условие в ограничении принимает значение "Истина".

Из соображений эффективности в ограничениях доступа к данным нельзя использовать агрегатные функции. Поэтому возможности участия в ограничениях доступа к данным каких-нибудь условий на совокупности записей табличных частей не предусмотрено. Подобная цель может быть достигнута посредством запросов, вложенных в ограничения, однако пользоваться этим необходимо с осторожностью из-за возможного снижения производительности.

Например, если документ "Накладная" содержит табличную часть "Состав", то ограничения доступа к этому документу проверяются при обращении к каждой накладной, как к единому целому и не могут разрешить доступ к какой-нибудь одной записи его табличной части "Состав", а к какой-нибудь другой запретить.

Пусть таблица "Документ.Накладная" содержит следующие записи:

Контрагент
(ссылка на Справочник.Контрагенты)

Состав (табличная часть)

Номенклатура

Количество

Пекарня Косолапова Булка с маком 20
Пирожок с курагой 30
Трикотажная фабрика Штаны 20
Футболка 100

В этом случае запрос, исполняемый для каждой накладной в процессе проверки следующего ограничения:

Копировать в буфер обмена

ГДЕ Состав.Количество > 50

будет иметь вид

Копировать в буфер обмена

ВЫБРАТЬ 1
ИЗ ТаблицаИзОднойПроверяемойЗаписи КАК Накладная
ЛЕВОЕ ВНЕШНЕЕ СОЕДИНЕНИЕ Документ.Накладная.Состав КАК Состав
ПО Накладная.Ссылка = Состав.Ссылка
ГДЕ Состав.Количество > 50 

Следовательно доступ будет разрешен только для записи "Трикотажная фабрика". Поэтому запрос:

Копировать в буфер обмена

ВЫБРАТЬ РАЗРЕШЕННЫЕ Контрагент, Состав.(Номенклатура, Количество)
ИЗ Документ.Накладная

выдаст таблицу:

Контрагент

Состав

Номенклатура

Количество

Трикотажная фабрика Штаны 20
Футболка 100

а запрос к вложенной таблице:

Копировать в буфер обмена

ВЫБРАТЬ РАЗРЕШЕННЫЕ Контрагент, Номенклатура, Количество
ИЗ Документ.Накладная.Состав

выдаст таблицу

Контрагент

 Номенклатура

Количество

Трикотажная фабрика Штаны 20
Трикотажная фабрика Футболка 100

поскольку ограничение накладывается только на записи верхнего уровня, но не на записи табличных частей.

Если нужно разрешить доступ еще и к тем накладным, у которых состав пустой, то ограничение может быть модифицировано так:

Копировать в буфер обмена

ГДЕ Состав.Количество > 50 ИЛИ Состав.Количество ЕСТЬ NULL

Если же необходимо разрешить доступ только к тем накладным, у которых в табличной части "Состав" нет записей с "Количеством", превышающем 50, то в ограничении необходимо использовать вложенный запрос:

Копировать в буфер обмена

Накладная1
ИЗ Документ.Накладная КАК Накладная1
ГДЕ Накладная1.Ссылка В
    (
        ВЫБРАТЬ Состав1.Ссылка
        ИЗ Документ.Накладная.Состав КАК Состав1
        СГРУППИРОВАТЬ ПО Состав1.Ссылка
        ИМЕЮЩИЕ МАКСИМУМ(Состав1.Количество) <= 50
    ) ИЛИ Накладная1.Состав.Количество ЕСТЬ NULL

Объекты встроенного языка

Для работы с данными в объектной технике во встроенном языке 1С:Предприятия предусмотрены специальные объекты. Например для справочника это: СправочникиМенеджер, СправочникМенеджер.<Имя справочника>, СправочникСсылка.<Имя справочника>, СправочникОбъект.<Имя справочника>, и другие.

Все операции над объектами встроенного языка 1С:Предприятия выполняются в режиме "ВСЕ" (без использования режима "РАЗРЕШЕННЫЕ"). Для успешного получения разрешенных объектов в соответствующих методах объектов необходимо указывать отборы, не противоречащие ограничениям. Например, если на чтение из регистра сведений "КонтактнаяИнформация" установлено ограничение вида:

Копировать в буфер обмена

ГДЕ Тип = &ТипКонтактнойИнформации"

то для успешного выполнения метода

Копировать в буфер обмена
Срез = РегистрыСведений.КонтактнаяИнформация.СрезПоследних();

необходимо установить отбор:

Копировать в буфер обмена
Отбор = Новый Структура;
Отбор.Вставить("Тип", ПараметрыСеанса.ТипКонтактнойИнформации);
Срез = РегистрыСведений.КонтактнаяИнформация.СрезПоследних(, Отбор);

Если ограничение доступа сложное и не может быть сформулировано в терминах отборов, то использование выборки (метод Выбрать()) и аналогичных оказывается невозможным. В этом случае следует использовать запросы. Проектирование разграничения доступа к данным таким образом, чтобы ограничения могли быть сформулированы в терминах отборов, позволит использовать объекты встроенного языка с максимальной гибкостью.

Виртуальные таблицы запросов

При использовании в запросах без ключевого слова РАЗРЕШЕННЫЕ виртуальных таблиц в условиях установленных ограничений доступа к данным необходимо указывать отборы, не противоречащие ограничениям не только для запроса в целом, но и для виртуальных таблиц. Например:

Копировать в буфер обмена

ВЫБРАТЬ
КонтактнаяИнформацияСрезПервых.Представление
ИЗ
РегистрСведений.КонтактнаяИнформация.СрезПоследних(,Тип = &Тип) КАК КонтактнаяИнформацияСрезПервых
ГДЕ
КонтактнаяИнформацияСрезПервых.Тип = &Тип

Выделенный отбор по виртуальной таблице "СрезПоследних" может содержать произвольное логическое выражение, допустимое для раздела ГДЕ, использующее поля, которые присутствуют в виртуальной таблице.