Этот раздел содержит информацию об особенностях использования ограничений доступа к данным, определяемых поведением различных объектов 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С:Предприятия выполняются в режиме "ВСЕ" (без использования режима "РАЗРЕШЕННЫЕ"). Для успешного получения разрешенных объектов в соответствующих методах объектов необходимо указывать отборы, не противоречащие ограничениям. Например, если на чтение из регистра сведений "КонтактнаяИнформация" установлено ограничение вида:
Копировать в буфер обменаГДЕ Тип = &ТипКонтактнойИнформации"
то для успешного выполнения метода
Копировать в буфер обменаСрез = РегистрыСведений.КонтактнаяИнформация.СрезПоследних();
необходимо установить отбор:
Копировать в буфер обменаОтбор = Новый Структура; Отбор.Вставить("Тип", ПараметрыСеанса.ТипКонтактнойИнформации); Срез = РегистрыСведений.КонтактнаяИнформация.СрезПоследних(, Отбор);
Если ограничение доступа сложное и не может быть сформулировано в терминах отборов, то использование выборки (метод Выбрать()) и аналогичных оказывается невозможным. В этом случае следует использовать запросы. Проектирование разграничения доступа к данным таким образом, чтобы ограничения могли быть сформулированы в терминах отборов, позволит использовать объекты встроенного языка с максимальной гибкостью.
При использовании в запросах без ключевого слова РАЗРЕШЕННЫЕ виртуальных таблиц в условиях установленных ограничений доступа к данным необходимо указывать отборы, не противоречащие ограничениям не только для запроса в целом, но и для виртуальных таблиц. Например:
Копировать в буфер обменаВЫБРАТЬ
КонтактнаяИнформацияСрезПервых.Представление
ИЗ
РегистрСведений.КонтактнаяИнформация.СрезПоследних(,Тип = &Тип) КАК КонтактнаяИнформацияСрезПервых
ГДЕ
КонтактнаяИнформацияСрезПервых.Тип = &Тип
Выделенный отбор по виртуальной таблице "СрезПоследних" может содержать произвольное логическое выражение, допустимое для раздела ГДЕ, использующее поля, которые присутствуют в виртуальной таблице.