Обновлено: 23.09.2023
« Как стать программистом 1С » Язык 1С » Препроцессор 1С и компилятор 1С
Препроцессор 1С и компилятор 1С
После написания программы на встроенном языке 1С она сохраняется в конфигурацию в составе модуля. При запуске 1С в режиме 1С Предприятие программа на языке 1С будет выполнена.
Сначала немного терминов:
-
— специальная программа, которая перерабатывает программный код из «вида» удобного для работы программиста, в «вид», удобный для работы копилятора; — специальная программа, которая умеет перерабатывать программный код в «машинный» код — выполняемый непосредственно процессором компьютера; — специальная программа, которая вместо компилирования кода в машинный код для процессора, выполняет его самостоятельно. Интерпретатор с предварительной компиляцией — компилирует программу не в машинный код, а в специальный «байт-код» удобный для последующего выполнения интерпретатором.
Как выполняются программы написанные на встроенном языке 1С?
Программа на языке 1С перед выполнением компилируется – преобразовывается в специальный код.
Выполнение кода на языке 1С производится в три этапа:
- Обработка модулей препроцессором 1С согласно директив препроцессора 1С
- Компиляция в байт-код
- Исполнение
Компиляция производится отдельно на клиенте и отдельно на сервере (даже одного и того же модуля), при первом обращении к нему.
Компилятор 1С на входе получает модуль не в том виде, в каком его видит программист. Препроцессор 1С разрезает модуль на части (вырезая не нужное) и потом соединяет его.
Директива препроцессора 1С — это способ указать препроцессору 1С где будет выполняться указанный участок кода на языке 1С.
Это связано с тем, что выполнение текста программы производится на сервере и на клиенте. Есть функции и процедуры, которые не могут быть выполнены на сервере/клиенте. Например на сервере Вы не можете показать пользователю предупреждение с необходимостью нажатия кнопки ОК.
Поэтому в модуле указывается где должен выполняться код:
- Общий модуль (ветка Общие/Общие модули) – в свойствах модуля указывается может ли он выполняться на сервере и на клиенте
- В остальных модулях – для этого используются директива препроцессора 1С.
Непосредственно в тексте модуля, блоки программного кода, отмечаются директивы препроцессора 1С:
Функция Пример1() //будет выполнена и на клиенте и на сервере
КонецФункции
Если никаких инструкций препроцессору 1С в тексте не указано, и использована функция, которую нельзя выполнять на сервере/клиенте, то в момент компилирования модуля (при первом доступе к нему) в исполняемом режиме будет вызвана ошибка.
«Обертывать» можно не только функции, но и конкретные строки исполняемого кода.
Так как компиляция 1С на данный момент еще не началась, то можно с помощью таких блоков создавать функции с одинаковыми наименованиями (для сервера, для клиента).
В модуле управляемой формы инструкции препроцессору 1С рекомендуется использовать только внутри функций/процедур.
После того, как препроцессор 1С «склеил» модуль, он передает его компилятору 1С, который его компилирует. Далее в режиме исполнения код будет выполнен.
При выполнении кода одного модуля, [может] происходит разовое/множественное переключения выполнения с клиента на сервер и обратно.
Например, если требуется выполнить запрос к базе данных, то выполнение будет переключено на сервер, выполнен запрос, данные переданы на клиент. Таким образом модуль существует на сервере и на клиенте.
Переключение исполнения с клиента на сервер и обратно производится «автоматически».
По умолчанию толстый клиент выполняет весь код на клиенте и иногда вызывает сервер. Тонкий клиент наоборот – все выполняет на сервере и иногда вызывает клиент (хотя в любом случае инициализация первого вызова сервера производится клиентом).
Программист в получившемся «склеенном» модуле может для каждой функции указать, где ее требуется исполнять. Не забываем, что доступ к данным производится на сервере, а инициализация вызова на клиенте. Например:
&НаСервере
Функция ПолучитьДанныеБазыДанных()
Запрос = Новый Запрос(«»);
КонецФункции
Ранее, в толстом клиенте, форма создавалась и была доступна только на клиенте (если не передать ее параметром на сервер, конечно). Управляемая форма создается на сервере и может обрабатываться на клиенте и на сервере.
Поэтому, при выполнении функций модуля, при переключении выполнения с клиента на сервер и обратно, передаются кроме прочего все данные формы (называется «контекст»).
Данных может быть много и передаваться они будут «долго». А в вызываемой функции они могут быть и не нужны, она их не использует вовсе. Для таких случаев есть директива &НаСервереБезКонтекста.
Начальные данные:
1. Платформа 8.2.15
2. Конфигурация самописная для управляемого приложения.
Есть общий модуль, у которого поставлены следующие галки: Клиент, Сервер, Вызов сервера.
В этом модуле расположена следующая функция:
При этом 1с пишет, что функция «Получить()» не обнаружена.
На сколько я понимаю, содержимое общего модуля в соответствии с установленными галками компилируется как на стороне клиента, так и на стороне сервера, при этом инструкцией препроцессора я указал, что функция «Получить()» должна быть скомпилирована только на стороне сервера (на клиенте она мне не нужна), при этом я пытаюсь вызвать ее со стороны клиента на что мне дает право галка «Вызов сервера».
Что я делаю не так, почему 1с не видит эту функцию?
Потому, что инструкцией препроцессора Вы блокировали объявление этой функции на клиенте. Перед вызовом функции с клиента Вам необходимо передать исполнение на сервер.
(2) asved.ru, к сожалению, под рукой у меня сейчас документации по платформе нет, но на сколько я помню, галка «Вызов сервера» управляет доступностью серверных функций, расположенных в общем модуле, для их вызова из клиентских процедур.
Если у общего модуля я уберу галку «Клиент» — серверная функция вызывается без проблем, т.е. тут вопрос в том, почему с установленной галкой «Клиент» функция невидима (т.е. 1с не пытается вызвать ее на сервере, хотя она там присутствует), а при отключенной галке — функция становится видна.
На форумах я единственное что вычитал только то, что это особенность работы модулей форм, и особого внятного ответа на этот вопрос не нашел, т.е. я так понимаю, что в общем модуле с тремя установленными галками «Клиент», «Сервер» и «Вызов сервера» использование инструкций препроцессора и директив компиляции смысла не имеет.
(3) Zigfridish, мои 5 копеек.
Суть галочек в следующем:
Галочки «Клиент» и «Сервер» — означают что общий модуль может вызываться и из клиентской части и из сервеной. И помоему там диркетивы (&Клиент или &Сервер) не важны (просто из соответсвующего места должны вызываться соотвествующие процедуры) и при помоще интсрукции компиляции
разрешаются всякие колизии связанные с вызовом процедур.
Галочка «ВызовСервере» действительно позволяет выполнять вызов процедур из клиентской части, но выполняться они при этом будут на серевере. Т.е. можно поставить галочки Сервер и Вызов и споконо вызывать ее из клиента.
Вобщем попробуй убрть галочку Клиент. Тогда будет вызываться сервер и инстукция отработает нормально
Кажется так, если не путаю (у меня тоже нет документации под рукой
(4) Ягг, если я оставлю только две галки «Сервер» и «Вызов сервера» — смысл использования директив компиляции и инструкций в общем модуле пропадает, т.к. он весь полностью будет скомпилирован на сервере.
Так вот мне и хочется, чтобы в модуле присутствовали как клиентские, так и серверные процедуры, и чтобы я мог их разграничить с помощью инструкций препроцессора (часть из них скомпилировать на сервере, часть — на клиенте, а некоторые из них — на обеих сторонах).
(6) Zigfridish, тогда оставь обе галки, но суть в том что если модуль будет вызываться из клиентсокого контектса, то нужно вызывать только доступные процедуры. и наоборот.
В товвоем случае ты вызываешь общий модуль из клиента, при этом он и считается выполняемым на клиенте. Раз так то инструкция «Если сервер» естесвенно счиатет что это не сервер (это клиентский контекст) и не компилирует кусок.
Вобщем, тогда оставиль Клиент и Сервер и убери инструкцию препроцессора. Но учти, что процедура вэтом случае выполняется имено в клиентском контексте.
(9) Ягг, дело в том, что эта функция общего модуля не может исполняться на клиенте (у меня в ней используется запрос к базе), поэтому я ее и оградил инструкцией, чтобы она присутствовала и исполнялась только на сервере, и чтобы ее можно было вызвать из клиентской части (галка «Вызов сервера»).
Помню даже в какой-то желтой книге видел подобную фразу по последовательности действий, которые выполняет 1с при вызове серверной функции с клиента: «сначала производится поиск вызываемой функции на клиенте, т.к. на клиенте она отсутствует — производится ее поиск на сервере, после чего на сервере происходит ее исполнение и по окончании процесса управление передается на клиента». Вот как то так
(10) Zigfridish, эээ. боюсь так не выйдет. Если стоит галочка «Клиент» и модуль вызывается из клиента, то априори считается что общий модуль выполняется в контексте клиента (система сама определит контекст по месту вызова). Тогда надо переносить какую-ту часть процедуры другой общий модуль. Другому модулю ставить галочку «Сервер» и «Вызов сервера» и на него уже ссылаться.
Может конечно меня кто поправит но по моему так.
ЗЫ. Допишу что бы не было разночтений (еще раз). Если стоят обе галки, о контекст будет определяться по месту вызова.
(12) Zigfridish, вообще, есть объекты «Команды» (Общие команды) она в какой-то степени имеет и серверную и клиентскую часть (место выполнения по директиве &НаСервере и т.д.). Но вобще-то они (КОМАНДЫ) для этого не предназначены и будут заморочки с передачей параметров и прочим.
Но попробуй, может найдется какое-то приемлимое рещение, если очень охото все вместе, но по хорошему лучше разносить
В догонку: можно еще попробовать использовать какую-нибуь «формальную» управляемую форму. С ней пожалуй меньше возьни чем с Командой в данном случае.
(6)Так может правильней сделать два общих модуля с разным набором галочек?
Если запуск инструкций все равно разграничиваешь командами препроцессора.
(5) red80, я эту книгу читал, и насколько помню, то в ней не рассматриваются примеры использования инструкций препроцессора в общих модулях.
Почему же тогда при отключенной галке «Клиент» предварительная передача исполнения на сервер в модуле формы не требуется (я могу напрямую из клиентской процедуры формы обратиться к серверной функции общего модуля)?
когда пытался собрать их конструктором, который там есть для ограничений, то 1с выдала предупреждение: запрос не может быть собран из-за наличия в нем инструкции препроцесору.
т.е. это два реквизита регистра: Контрагент и Организация.. они проверяются на соответствие Контрагенту и организации каким значениям?
не совсем понимаю..
(3) В конфигураторе в ролях есть закладка «Шаблоны». Как это работает можно посмотреть там.
В двух словах. У пользователя назначаются права на доступ к записям. Не назначены права — нет доступа. Права могут быть назначены группе, а пользователь может входить в эту группу или может быть использована схема профилей (УПП). При этом может быть указано по каким объектам выполняется контроль доступа на уровне записей. Т.е. можно контролировать доступ, например, только по организации.
надо подчеркнуть, что с шаблонами ограничения записей нужно быть очень осторожным. если у пользователя назначены две роли и в каждой из них наложены ограничения на уровне записей, могут быть непредсказуемые последствия. 1С немного намутила с этими шаблонами.
Почему не предсказуемые? Все нормально. А везде в запросах для таких пользователей надо использовыть «ВЫБРАТЬ РАЗРЕШЕННЫЕ»
например, если в одной роли для объекта справочника определена следующее ограничение на чтение:
Прочие поля : ГДЕ Ложь
а в другой роли на этот объект наложено ограничение по шаблону, в итоге будем иметь ошибку доступа при попытке програмно обратиться к этому справочнику, чего не наблюдается в регистрах накопления. это как пример.
нужно очень осторожно настраивать роли для пользователя.
>нужно очень осторожно настраивать роли для пользователя.
Трудно не согласиться.
Лучше настраивать 1 роль, чем комбинировать несколько, тем более на RLS
2(9): еще RLS очень «тормозит» динамические списки .
например, у меня была задача, нужно в заказах покупателей показывать, введен ли на основании заказа Счет или Расходная накладная. Вроде бы делаю через КритерииОтбора, но тормоза жуткие, если список фильтруется с помощью RLS.
Обновлено: Очевидно, вы захотите сделать это с помощью шаблонов или базового класса, а не макросов. К сожалению, по разным причинам я не могу использовать ни шаблоны, ни базовый класс.
На данный момент я использую макрос для определения множества полей и методов в различных классах, например:
FIELDS_AND_METHODS — это многострочный макрос, в котором используются операторы преобразования строк и вставки токенов.
Я хотел бы заменить это на следующие вещи
Однако у меня возникают проблемы с «преобразованием в строку» и «вставкой токена» символа препроцессора TYPE_NAME в файл FieldsNMethods.h .
Например, я хочу определить деструктор класса в FieldsNMethods.h , поэтому для этого нужно будет использовать значение TYPE_NAME , как показано ниже:
Но с TYPE_NAME заменено его значение.
Возможно ли то, что я пытаюсь сделать? Я не могу напрямую использовать операторы преобразования строк и вставки токенов, потому что я не участвую в макроопределении.
Пытались ли вы когда-нибудь заполнить веб-форму в области электронной коммерции, которая требует много кликов и выбора? Вас попросят заполнить дату.
Будучи разработчиком веб-приложений, легко впасть в заблуждение, считая, что приложение без JavaScript не имеет права на жизнь. Нам становится удобно.
Если вы ищете пакет для быстрой интеграции календаря с выбором даты в ваше приложения, то библиотека Flatpickr отлично справится с этой задачей.
Клиент для URL-адресов, cURL, позволяет взаимодействовать с множеством различных серверов по множеству различных протоколов с синтаксисом URL.
У каждого из нас бывали случаи, когда нам нужно отцентрировать блочный элемент, но мы не знаем, как это сделать. Даже если мы реализуем какой-то.
Ответы 4
Это требует шаблона.
Прямой ответ на последнюю часть вашего вопроса — «учитывая, что я больше не участвую в макроопределении, как заставить работать операторы вставки и преобразования строк» - это «Вы не можете». Эти операторы работают только в макросах, поэтому вам придется писать вызовы макросов, чтобы заставить их работать.
@mackenir сказал, что «шаблоны не подходят». Почему шаблоны не подходят? Код имитирует шаблоны старомодным предварительным стандартом, предварительно шаблонным способом, и это вызывает много боли и горя. Использование шаблонов позволит избежать этой боли — хотя потребуется операция преобразования.
@mackenir спросил: «Есть ли способ заставить все работать с макросами?» Да, можно, но вам следует использовать шаблоны — они более надежны и удобны в обслуживании. Чтобы он работал с макросами, вам нужно, чтобы имена функций в коде во включенном заголовке были вызовами макросов. Чтобы это работало правильно, вам нужно пройти определенный уровень косвенного обращения:
Этот уровень косвенного обращения часто является необходимой идиомой как для токенизирующих, так и для строковых операторов.
Дополнительные комментарии от @mackenir указывают на продолжающиеся проблемы. Давайте конкретизируем.
At the moment I am using a macro to define a bunch of fields and methods on various classes, like this:
FIELDS_AND_METHODS is a multi-line macro that uses stringizing and token-pasting operators.
I would like to replace this with the following kind of thing
В ПОРЯДКЕ. Чтобы сделать это конкретным, нам нужен макрос FIELDS_AND_METHODS(type) , который является многострочным и использует вставку токенов (я не собираюсь заниматься структурированием — тем не менее, будут применяться те же базовые механизмы).
Если повезет, он объявляет член типа «указатель на тип аргумента», конструктор для этого типа и метод (в данном случае Example_next), который возвращает этот указатель.
Содержимое fieldsNmethods.h становится следующим:
Обратите внимание, что заголовок не будет содержать защиты множественного включения; его смысл в том, чтобы позволить включать его несколько раз. Он также отменяет определение своих вспомогательных макросов, чтобы разрешить множественное включение (ну, поскольку переопределения будут идентичными, они «мягкие» и не вызовут ошибки), и я добавил к ним префикс FNM_ в качестве примитивного элемента управления пространством имен для макросов. Это генерирует код, который я ожидал от препроцессора C. а G ++ не светится, а создает пустой объектный файл (потому что объявленные типы не используются в моем примере кода).
Обратите внимание, что для этого не требуется никаких изменений в вызывающем коде, кроме указанного в вопросе. Я думаю, что вопрос следует улучшить, используя принцип SPOT «Single Point of Truth» (или DRY «Don’t Repeat Yourself»):
Спасибо. Создание шаблона — это не вариант. Итак, вы подразумеваете, что есть способ достичь того же эффекта, что и операторы преобразования строк и вставки токенов в FieldsNMethods.h?
Классы являются общедоступным API, и мы не хотим загрязнять их, создавая шаблоны или имея базовый класс. Кроме того, это классы C++ / CLI, поэтому частное наследование не вариант. Спасибо за дополнительную информацию, я попробую.
«загрязнять» я имею в виду «раскрыть детали реализации таким образом, чтобы они могли запутать пользователей API».
а вы для этого используете макросы? это звучит злобно! Разве вы не можете написать такой фасад, который будет предоставлять клиенту только то, что вы хотите, и иметь внутреннюю поддержку?
Мы не хотим вводить много уровней косвенного обращения, и нам все равно понадобятся макросы для передачи во внутреннюю реализацию (или иначе придется писать много одного и того же кода много раз).
Нет, вы не можете определять определения классов или функций на лету. Они должны быть указаны либо путем непосредственного ввода, либо путем определения в препроцессоре.
Как правило, нет необходимости создавать подобные классы, и определения классов создаются перед компиляцией, будь то путем ввода всего текста или с помощью какой-либо генерации кода. Иногда существует отдельный этап генерации кода (например, в текущей Visual Studio вы можете определить этапы предварительной и последующей обработки).
Теперь, если вам нужно создать разные версии некоторых классов для разных типов данных, вы должны использовать шаблоны. Таким образом нельзя создавать штампы классов с разными именами.
Последний вопрос: зачем вы это делаете? Я никогда не был в ситуации, когда что-то подобное выглядело бы полезным в C++, и на языках, где это имеет смысл, есть средства для этого.
Я храню этот класс в QVector , поэтому, к сожалению, мне нужно добавить конструктор по умолчанию. Что касается дизайна программного обеспечения, это нехорошо для меня (потому что у меня есть ограничение на uiIndex ). Есть ли способ разрешить только QT ( QVector в моем случае) вызывать конструктор по умолчанию? Макрос или инструкция препроцессора?
Как насчет использования std::vector вместо этого? В противном случае стоит подумать о создании истории для std::optional или какого-либо другого типа прокси.
@ FrançoisAndrieux Я не могу, это полноценное приложение Qt.
Напоминает мне очень старый анекдот: «Доктор, мне больно, когда я это делаю (пациент делает очень странный жест рукой и ухом). Что вы можете предложить? И хороший доктор: я предлагаю этого не делать ».
Что означает «полный Qt»? Кто-то заставляет вас использовать QVector?
@Milleras Вы не можете использовать стандартную библиотеку C++?
@ FrançoisAndrieux Это бессмысленно. std::vector отлично подойдет для нестандартного конструктивного типа.
Kuba hasn’t forgotten Monica
@ FrançoisAndrieux std :: optional работает только для C++ 17. К сожалению для меня, мне приходится использовать C++ 14.
Пытались ли вы когда-нибудь заполнить веб-форму в области электронной коммерции, которая требует много кликов и выбора? Вас попросят заполнить дату.
Будучи разработчиком веб-приложений, легко впасть в заблуждение, считая, что приложение без JavaScript не имеет права на жизнь. Нам становится удобно.
Если вы ищете пакет для быстрой интеграции календаря с выбором даты в ваше приложения, то библиотека Flatpickr отлично справится с этой задачей.
Клиент для URL-адресов, cURL, позволяет взаимодействовать с множеством различных серверов по множеству различных протоколов с синтаксисом URL.
У каждого из нас бывали случаи, когда нам нужно отцентрировать блочный элемент, но мы не знаем, как это сделать. Даже если мы реализуем какой-то.
Ответы 2
Вы можете попробовать сделать QVector классным другом.
Рассмотрим следующий пример игрушки:
При этом можно хранить экземпляры Foo в QVector :
Однако следующее будет, например, неудача:
Конструктор без аргументов не обязательно должен быть явным.
Отличная идея! Работает, спасибо. Я добавил InputField() = default; и friend class QVector;
@SergeyA: Спасибо за подсказку Я обновлю ответ.
@Milleras Помните, что это означает, что теперь можно получить доступ к созданным по умолчанию экземплярам с помощью QVector , что означает, что вы все равно можете использовать недопустимый экземпляр. А в нынешнем виде обнаружить этот случай не всегда просто.
Это решение тесно связывает Foo с QVector , не говоря уже о существовании конструктора по умолчанию — возможно, Foo использует нестандартные конструктивные элементы? Цель состоит в том, чтобы сделать так, чтобы QVector мог использовать не устанавливаемый по умолчанию Foo , без каких-либо изменений в Foo . Это ясно указывает на то, каким должно быть решение: специализация членов QVector для некопируемого типа Foo .
Kuba hasn’t forgotten Monica
@ FrançoisAndrieux Да, это хороший аргумент. Но пока другого решения своей проблемы я не вижу
QVector не должен вызывать конструктор по умолчанию; В конце концов, std::vector этого не делает — если только вы не используете один из его методов, которому нужен этот конструктор. Все, что вам нужно, это отключить конструкцию по умолчанию в QVector :
Затем поместите макрос в то же место, где вы поместили Q_DECLARE_METATYPE : прямо там, где объявлен тип:
Затем вы можете использовать QVector с теми же ограничениями, что и std::vector .
Вы предлагаете расширить QVector? Иначе, как я могу использовать ваш макрос?
@JosephGarnier Макрос предоставляет специализации методов QVector . В этом прелесть шаблонных типов: вы можете легко заменить их кусочки и детали в особых обстоятельствах!
Kuba hasn’t forgotten Monica
Вы сделали то, чего я не делал выше, потому что все работает нормально. Напомним, что такие специализации должны происходить в области пространства имен, а не в области класса. Фактически, вам нужно специализироваться на пространстве имен Qt, если таковое имеется. В противном случае в глобальном масштабе.
Kuba hasn’t forgotten Monica
Восстановите свой проект. Как в: удалите папку сборки и снова выполните сборку. Способ устранения ошибок компоновщика всегда начинается с восстановления с чистого листа.
Kuba hasn’t forgotten Monica
Очистить мой проект ничего не изменилось, но я нашел ошибку. Вы должны добавить inline перед возвращаемым типом в ваших функциях. В остальном отлично работает! Благодарить.
Читайте также:
- Карусель из магнитного конструктора как собрать
- Коды на игру lego marvel super heroes
- Конструктор знаток ардуино бейсик
- Боинг 727 из лего
- Поезд лего дупло не заезжает на мост
Обновлено: 23.04.2023
« Как стать программистом 1С » Язык 1С » Препроцессор 1С и компилятор 1С
Препроцессор 1С и компилятор 1С
После написания программы на встроенном языке 1С она сохраняется в конфигурацию в составе модуля. При запуске 1С в режиме 1С Предприятие программа на языке 1С будет выполнена.
Сначала немного терминов:
-
— специальная программа, которая перерабатывает программный код из «вида» удобного для работы программиста, в «вид», удобный для работы копилятора; — специальная программа, которая умеет перерабатывать программный код в «машинный» код — выполняемый непосредственно процессором компьютера; — специальная программа, которая вместо компилирования кода в машинный код для процессора, выполняет его самостоятельно. Интерпретатор с предварительной компиляцией — компилирует программу не в машинный код, а в специальный «байт-код» удобный для последующего выполнения интерпретатором.
Как выполняются программы написанные на встроенном языке 1С?
Программа на языке 1С перед выполнением компилируется – преобразовывается в специальный код.
Выполнение кода на языке 1С производится в три этапа:
- Обработка модулей препроцессором 1С согласно директив препроцессора 1С
- Компиляция в байт-код
- Исполнение
Компиляция производится отдельно на клиенте и отдельно на сервере (даже одного и того же модуля), при первом обращении к нему.
Компилятор 1С на входе получает модуль не в том виде, в каком его видит программист. Препроцессор 1С разрезает модуль на части (вырезая не нужное) и потом соединяет его.
Директива препроцессора 1С — это способ указать препроцессору 1С где будет выполняться указанный участок кода на языке 1С.
Это связано с тем, что выполнение текста программы производится на сервере и на клиенте. Есть функции и процедуры, которые не могут быть выполнены на сервере/клиенте. Например на сервере Вы не можете показать пользователю предупреждение с необходимостью нажатия кнопки ОК.
Поэтому в модуле указывается где должен выполняться код:
- Общий модуль (ветка Общие/Общие модули) – в свойствах модуля указывается может ли он выполняться на сервере и на клиенте
- В остальных модулях – для этого используются директива препроцессора 1С.
Непосредственно в тексте модуля, блоки программного кода, отмечаются директивы препроцессора 1С:
Функция Пример1() //будет выполнена и на клиенте и на сервере
КонецФункции
Если никаких инструкций препроцессору 1С в тексте не указано, и использована функция, которую нельзя выполнять на сервере/клиенте, то в момент компилирования модуля (при первом доступе к нему) в исполняемом режиме будет вызвана ошибка.
«Обертывать» можно не только функции, но и конкретные строки исполняемого кода.
Так как компиляция 1С на данный момент еще не началась, то можно с помощью таких блоков создавать функции с одинаковыми наименованиями (для сервера, для клиента).
В модуле управляемой формы инструкции препроцессору 1С рекомендуется использовать только внутри функций/процедур.
После того, как препроцессор 1С «склеил» модуль, он передает его компилятору 1С, который его компилирует. Далее в режиме исполнения код будет выполнен.
При выполнении кода одного модуля, [может] происходит разовое/множественное переключения выполнения с клиента на сервер и обратно.
Например, если требуется выполнить запрос к базе данных, то выполнение будет переключено на сервер, выполнен запрос, данные переданы на клиент. Таким образом модуль существует на сервере и на клиенте.
Переключение исполнения с клиента на сервер и обратно производится «автоматически».
По умолчанию толстый клиент выполняет весь код на клиенте и иногда вызывает сервер. Тонкий клиент наоборот – все выполняет на сервере и иногда вызывает клиент (хотя в любом случае инициализация первого вызова сервера производится клиентом).
Программист в получившемся «склеенном» модуле может для каждой функции указать, где ее требуется исполнять. Не забываем, что доступ к данным производится на сервере, а инициализация вызова на клиенте. Например:
&НаСервере
Функция ПолучитьДанныеБазыДанных()
Запрос = Новый Запрос(«»);
КонецФункции
Ранее, в толстом клиенте, форма создавалась и была доступна только на клиенте (если не передать ее параметром на сервер, конечно). Управляемая форма создается на сервере и может обрабатываться на клиенте и на сервере.
Поэтому, при выполнении функций модуля, при переключении выполнения с клиента на сервер и обратно, передаются кроме прочего все данные формы (называется «контекст»).
Данных может быть много и передаваться они будут «долго». А в вызываемой функции они могут быть и не нужны, она их не использует вовсе. Для таких случаев есть директива &НаСервереБезКонтекста.
Начальные данные:
1. Платформа 8.2.15
2. Конфигурация самописная для управляемого приложения.
Есть общий модуль, у которого поставлены следующие галки: Клиент, Сервер, Вызов сервера.
В этом модуле расположена следующая функция:
При этом 1с пишет, что функция «Получить()» не обнаружена.
На сколько я понимаю, содержимое общего модуля в соответствии с установленными галками компилируется как на стороне клиента, так и на стороне сервера, при этом инструкцией препроцессора я указал, что функция «Получить()» должна быть скомпилирована только на стороне сервера (на клиенте она мне не нужна), при этом я пытаюсь вызвать ее со стороны клиента на что мне дает право галка «Вызов сервера».
Что я делаю не так, почему 1с не видит эту функцию?
Потому, что инструкцией препроцессора Вы блокировали объявление этой функции на клиенте. Перед вызовом функции с клиента Вам необходимо передать исполнение на сервер.
(2) asved.ru, к сожалению, под рукой у меня сейчас документации по платформе нет, но на сколько я помню, галка «Вызов сервера» управляет доступностью серверных функций, расположенных в общем модуле, для их вызова из клиентских процедур.
Если у общего модуля я уберу галку «Клиент» — серверная функция вызывается без проблем, т.е. тут вопрос в том, почему с установленной галкой «Клиент» функция невидима (т.е. 1с не пытается вызвать ее на сервере, хотя она там присутствует), а при отключенной галке — функция становится видна.
На форумах я единственное что вычитал только то, что это особенность работы модулей форм, и особого внятного ответа на этот вопрос не нашел, т.е. я так понимаю, что в общем модуле с тремя установленными галками «Клиент», «Сервер» и «Вызов сервера» использование инструкций препроцессора и директив компиляции смысла не имеет.
(3) Zigfridish, мои 5 копеек.
Суть галочек в следующем:
Галочки «Клиент» и «Сервер» — означают что общий модуль может вызываться и из клиентской части и из сервеной. И помоему там диркетивы (&Клиент или &Сервер) не важны (просто из соответсвующего места должны вызываться соотвествующие процедуры) и при помоще интсрукции компиляции
разрешаются всякие колизии связанные с вызовом процедур.
Галочка «ВызовСервере» действительно позволяет выполнять вызов процедур из клиентской части, но выполняться они при этом будут на серевере. Т.е. можно поставить галочки Сервер и Вызов и споконо вызывать ее из клиента.
Вобщем попробуй убрть галочку Клиент. Тогда будет вызываться сервер и инстукция отработает нормально
Кажется так, если не путаю (у меня тоже нет документации под рукой
(4) Ягг, если я оставлю только две галки «Сервер» и «Вызов сервера» — смысл использования директив компиляции и инструкций в общем модуле пропадает, т.к. он весь полностью будет скомпилирован на сервере.
Так вот мне и хочется, чтобы в модуле присутствовали как клиентские, так и серверные процедуры, и чтобы я мог их разграничить с помощью инструкций препроцессора (часть из них скомпилировать на сервере, часть — на клиенте, а некоторые из них — на обеих сторонах).
(6) Zigfridish, тогда оставь обе галки, но суть в том что если модуль будет вызываться из клиентсокого контектса, то нужно вызывать только доступные процедуры. и наоборот.
В товвоем случае ты вызываешь общий модуль из клиента, при этом он и считается выполняемым на клиенте. Раз так то инструкция «Если сервер» естесвенно счиатет что это не сервер (это клиентский контекст) и не компилирует кусок.
Вобщем, тогда оставиль Клиент и Сервер и убери инструкцию препроцессора. Но учти, что процедура вэтом случае выполняется имено в клиентском контексте.
(9) Ягг, дело в том, что эта функция общего модуля не может исполняться на клиенте (у меня в ней используется запрос к базе), поэтому я ее и оградил инструкцией, чтобы она присутствовала и исполнялась только на сервере, и чтобы ее можно было вызвать из клиентской части (галка «Вызов сервера»).
Помню даже в какой-то желтой книге видел подобную фразу по последовательности действий, которые выполняет 1с при вызове серверной функции с клиента: «сначала производится поиск вызываемой функции на клиенте, т.к. на клиенте она отсутствует — производится ее поиск на сервере, после чего на сервере происходит ее исполнение и по окончании процесса управление передается на клиента». Вот как то так
(10) Zigfridish, эээ. боюсь так не выйдет. Если стоит галочка «Клиент» и модуль вызывается из клиента, то априори считается что общий модуль выполняется в контексте клиента (система сама определит контекст по месту вызова). Тогда надо переносить какую-ту часть процедуры другой общий модуль. Другому модулю ставить галочку «Сервер» и «Вызов сервера» и на него уже ссылаться.
Может конечно меня кто поправит но по моему так.
ЗЫ. Допишу что бы не было разночтений (еще раз). Если стоят обе галки, о контекст будет определяться по месту вызова.
(12) Zigfridish, вообще, есть объекты «Команды» (Общие команды) она в какой-то степени имеет и серверную и клиентскую часть (место выполнения по директиве &НаСервере и т.д.). Но вобще-то они (КОМАНДЫ) для этого не предназначены и будут заморочки с передачей параметров и прочим.
Но попробуй, может найдется какое-то приемлимое рещение, если очень охото все вместе, но по хорошему лучше разносить
В догонку: можно еще попробовать использовать какую-нибуь «формальную» управляемую форму. С ней пожалуй меньше возьни чем с Командой в данном случае.
(6)Так может правильней сделать два общих модуля с разным набором галочек?
Если запуск инструкций все равно разграничиваешь командами препроцессора.
(5) red80, я эту книгу читал, и насколько помню, то в ней не рассматриваются примеры использования инструкций препроцессора в общих модулях.
Почему же тогда при отключенной галке «Клиент» предварительная передача исполнения на сервер в модуле формы не требуется (я могу напрямую из клиентской процедуры формы обратиться к серверной функции общего модуля)?
когда пытался собрать их конструктором, который там есть для ограничений, то 1с выдала предупреждение: запрос не может быть собран из-за наличия в нем инструкции препроцесору.
т.е. это два реквизита регистра: Контрагент и Организация.. они проверяются на соответствие Контрагенту и организации каким значениям?
не совсем понимаю..
(3) В конфигураторе в ролях есть закладка «Шаблоны». Как это работает можно посмотреть там.
В двух словах. У пользователя назначаются права на доступ к записям. Не назначены права — нет доступа. Права могут быть назначены группе, а пользователь может входить в эту группу или может быть использована схема профилей (УПП). При этом может быть указано по каким объектам выполняется контроль доступа на уровне записей. Т.е. можно контролировать доступ, например, только по организации.
надо подчеркнуть, что с шаблонами ограничения записей нужно быть очень осторожным. если у пользователя назначены две роли и в каждой из них наложены ограничения на уровне записей, могут быть непредсказуемые последствия. 1С немного намутила с этими шаблонами.
Почему не предсказуемые? Все нормально. А везде в запросах для таких пользователей надо использовыть «ВЫБРАТЬ РАЗРЕШЕННЫЕ»
например, если в одной роли для объекта справочника определена следующее ограничение на чтение:
Прочие поля : ГДЕ Ложь
а в другой роли на этот объект наложено ограничение по шаблону, в итоге будем иметь ошибку доступа при попытке програмно обратиться к этому справочнику, чего не наблюдается в регистрах накопления. это как пример.
нужно очень осторожно настраивать роли для пользователя.
>нужно очень осторожно настраивать роли для пользователя.
Трудно не согласиться.
Лучше настраивать 1 роль, чем комбинировать несколько, тем более на RLS
2(9): еще RLS очень «тормозит» динамические списки .
например, у меня была задача, нужно в заказах покупателей показывать, введен ли на основании заказа Счет или Расходная накладная. Вроде бы делаю через КритерииОтбора, но тормоза жуткие, если список фильтруется с помощью RLS.
Обновлено: Очевидно, вы захотите сделать это с помощью шаблонов или базового класса, а не макросов. К сожалению, по разным причинам я не могу использовать ни шаблоны, ни базовый класс.
На данный момент я использую макрос для определения множества полей и методов в различных классах, например:
FIELDS_AND_METHODS — это многострочный макрос, в котором используются операторы преобразования строк и вставки токенов.
Я хотел бы заменить это на следующие вещи
Однако у меня возникают проблемы с «преобразованием в строку» и «вставкой токена» символа препроцессора TYPE_NAME в файл FieldsNMethods.h .
Например, я хочу определить деструктор класса в FieldsNMethods.h , поэтому для этого нужно будет использовать значение TYPE_NAME , как показано ниже:
Но с TYPE_NAME заменено его значение.
Возможно ли то, что я пытаюсь сделать? Я не могу напрямую использовать операторы преобразования строк и вставки токенов, потому что я не участвую в макроопределении.
Пытались ли вы когда-нибудь заполнить веб-форму в области электронной коммерции, которая требует много кликов и выбора? Вас попросят заполнить дату.
Будучи разработчиком веб-приложений, легко впасть в заблуждение, считая, что приложение без JavaScript не имеет права на жизнь. Нам становится удобно.
Если вы ищете пакет для быстрой интеграции календаря с выбором даты в ваше приложения, то библиотека Flatpickr отлично справится с этой задачей.
Клиент для URL-адресов, cURL, позволяет взаимодействовать с множеством различных серверов по множеству различных протоколов с синтаксисом URL.
У каждого из нас бывали случаи, когда нам нужно отцентрировать блочный элемент, но мы не знаем, как это сделать. Даже если мы реализуем какой-то.
Ответы 4
Это требует шаблона.
Прямой ответ на последнюю часть вашего вопроса — «учитывая, что я больше не участвую в макроопределении, как заставить работать операторы вставки и преобразования строк» - это «Вы не можете». Эти операторы работают только в макросах, поэтому вам придется писать вызовы макросов, чтобы заставить их работать.
@mackenir сказал, что «шаблоны не подходят». Почему шаблоны не подходят? Код имитирует шаблоны старомодным предварительным стандартом, предварительно шаблонным способом, и это вызывает много боли и горя. Использование шаблонов позволит избежать этой боли — хотя потребуется операция преобразования.
@mackenir спросил: «Есть ли способ заставить все работать с макросами?» Да, можно, но вам следует использовать шаблоны — они более надежны и удобны в обслуживании. Чтобы он работал с макросами, вам нужно, чтобы имена функций в коде во включенном заголовке были вызовами макросов. Чтобы это работало правильно, вам нужно пройти определенный уровень косвенного обращения:
Этот уровень косвенного обращения часто является необходимой идиомой как для токенизирующих, так и для строковых операторов.
Дополнительные комментарии от @mackenir указывают на продолжающиеся проблемы. Давайте конкретизируем.
At the moment I am using a macro to define a bunch of fields and methods on various classes, like this:
FIELDS_AND_METHODS is a multi-line macro that uses stringizing and token-pasting operators.
I would like to replace this with the following kind of thing
В ПОРЯДКЕ. Чтобы сделать это конкретным, нам нужен макрос FIELDS_AND_METHODS(type) , который является многострочным и использует вставку токенов (я не собираюсь заниматься структурированием — тем не менее, будут применяться те же базовые механизмы).
Если повезет, он объявляет член типа «указатель на тип аргумента», конструктор для этого типа и метод (в данном случае Example_next), который возвращает этот указатель.
Содержимое fieldsNmethods.h становится следующим:
Обратите внимание, что заголовок не будет содержать защиты множественного включения; его смысл в том, чтобы позволить включать его несколько раз. Он также отменяет определение своих вспомогательных макросов, чтобы разрешить множественное включение (ну, поскольку переопределения будут идентичными, они «мягкие» и не вызовут ошибки), и я добавил к ним префикс FNM_ в качестве примитивного элемента управления пространством имен для макросов. Это генерирует код, который я ожидал от препроцессора C. а G ++ не светится, а создает пустой объектный файл (потому что объявленные типы не используются в моем примере кода).
Обратите внимание, что для этого не требуется никаких изменений в вызывающем коде, кроме указанного в вопросе. Я думаю, что вопрос следует улучшить, используя принцип SPOT «Single Point of Truth» (или DRY «Don’t Repeat Yourself»):
Спасибо. Создание шаблона — это не вариант. Итак, вы подразумеваете, что есть способ достичь того же эффекта, что и операторы преобразования строк и вставки токенов в FieldsNMethods.h?
Классы являются общедоступным API, и мы не хотим загрязнять их, создавая шаблоны или имея базовый класс. Кроме того, это классы C++ / CLI, поэтому частное наследование не вариант. Спасибо за дополнительную информацию, я попробую.
«загрязнять» я имею в виду «раскрыть детали реализации таким образом, чтобы они могли запутать пользователей API».
а вы для этого используете макросы? это звучит злобно! Разве вы не можете написать такой фасад, который будет предоставлять клиенту только то, что вы хотите, и иметь внутреннюю поддержку?
Мы не хотим вводить много уровней косвенного обращения, и нам все равно понадобятся макросы для передачи во внутреннюю реализацию (или иначе придется писать много одного и того же кода много раз).
Нет, вы не можете определять определения классов или функций на лету. Они должны быть указаны либо путем непосредственного ввода, либо путем определения в препроцессоре.
Как правило, нет необходимости создавать подобные классы, и определения классов создаются перед компиляцией, будь то путем ввода всего текста или с помощью какой-либо генерации кода. Иногда существует отдельный этап генерации кода (например, в текущей Visual Studio вы можете определить этапы предварительной и последующей обработки).
Теперь, если вам нужно создать разные версии некоторых классов для разных типов данных, вы должны использовать шаблоны. Таким образом нельзя создавать штампы классов с разными именами.
Последний вопрос: зачем вы это делаете? Я никогда не был в ситуации, когда что-то подобное выглядело бы полезным в C++, и на языках, где это имеет смысл, есть средства для этого.
Я храню этот класс в QVector , поэтому, к сожалению, мне нужно добавить конструктор по умолчанию. Что касается дизайна программного обеспечения, это нехорошо для меня (потому что у меня есть ограничение на uiIndex ). Есть ли способ разрешить только QT ( QVector в моем случае) вызывать конструктор по умолчанию? Макрос или инструкция препроцессора?
Как насчет использования std::vector вместо этого? В противном случае стоит подумать о создании истории для std::optional или какого-либо другого типа прокси.
@ FrançoisAndrieux Я не могу, это полноценное приложение Qt.
Напоминает мне очень старый анекдот: «Доктор, мне больно, когда я это делаю (пациент делает очень странный жест рукой и ухом). Что вы можете предложить? И хороший доктор: я предлагаю этого не делать ».
Что означает «полный Qt»? Кто-то заставляет вас использовать QVector?
@Milleras Вы не можете использовать стандартную библиотеку C++?
@ FrançoisAndrieux Это бессмысленно. std::vector отлично подойдет для нестандартного конструктивного типа.
Kuba hasn’t forgotten Monica
@ FrançoisAndrieux std :: optional работает только для C++ 17. К сожалению для меня, мне приходится использовать C++ 14.
Пытались ли вы когда-нибудь заполнить веб-форму в области электронной коммерции, которая требует много кликов и выбора? Вас попросят заполнить дату.
Будучи разработчиком веб-приложений, легко впасть в заблуждение, считая, что приложение без JavaScript не имеет права на жизнь. Нам становится удобно.
Если вы ищете пакет для быстрой интеграции календаря с выбором даты в ваше приложения, то библиотека Flatpickr отлично справится с этой задачей.
Клиент для URL-адресов, cURL, позволяет взаимодействовать с множеством различных серверов по множеству различных протоколов с синтаксисом URL.
У каждого из нас бывали случаи, когда нам нужно отцентрировать блочный элемент, но мы не знаем, как это сделать. Даже если мы реализуем какой-то.
Ответы 2
Вы можете попробовать сделать QVector классным другом.
Рассмотрим следующий пример игрушки:
При этом можно хранить экземпляры Foo в QVector :
Однако следующее будет, например, неудача:
Конструктор без аргументов не обязательно должен быть явным.
Отличная идея! Работает, спасибо. Я добавил InputField() = default; и friend class QVector;
@SergeyA: Спасибо за подсказку Я обновлю ответ.
@Milleras Помните, что это означает, что теперь можно получить доступ к созданным по умолчанию экземплярам с помощью QVector , что означает, что вы все равно можете использовать недопустимый экземпляр. А в нынешнем виде обнаружить этот случай не всегда просто.
Это решение тесно связывает Foo с QVector , не говоря уже о существовании конструктора по умолчанию — возможно, Foo использует нестандартные конструктивные элементы? Цель состоит в том, чтобы сделать так, чтобы QVector мог использовать не устанавливаемый по умолчанию Foo , без каких-либо изменений в Foo . Это ясно указывает на то, каким должно быть решение: специализация членов QVector для некопируемого типа Foo .
Kuba hasn’t forgotten Monica
@ FrançoisAndrieux Да, это хороший аргумент. Но пока другого решения своей проблемы я не вижу
QVector не должен вызывать конструктор по умолчанию; В конце концов, std::vector этого не делает — если только вы не используете один из его методов, которому нужен этот конструктор. Все, что вам нужно, это отключить конструкцию по умолчанию в QVector :
Затем поместите макрос в то же место, где вы поместили Q_DECLARE_METATYPE : прямо там, где объявлен тип:
Затем вы можете использовать QVector с теми же ограничениями, что и std::vector .
Вы предлагаете расширить QVector? Иначе, как я могу использовать ваш макрос?
@JosephGarnier Макрос предоставляет специализации методов QVector . В этом прелесть шаблонных типов: вы можете легко заменить их кусочки и детали в особых обстоятельствах!
Kuba hasn’t forgotten Monica
Вы сделали то, чего я не делал выше, потому что все работает нормально. Напомним, что такие специализации должны происходить в области пространства имен, а не в области класса. Фактически, вам нужно специализироваться на пространстве имен Qt, если таковое имеется. В противном случае в глобальном масштабе.
Kuba hasn’t forgotten Monica
Восстановите свой проект. Как в: удалите папку сборки и снова выполните сборку. Способ устранения ошибок компоновщика всегда начинается с восстановления с чистого листа.
Kuba hasn’t forgotten Monica
Очистить мой проект ничего не изменилось, но я нашел ошибку. Вы должны добавить inline перед возвращаемым типом в ваших функциях. В остальном отлично работает! Благодарить.
Читайте также:
- Карусель из магнитного конструктора как собрать
- Коды на игру lego marvel super heroes
- Конструктор знаток ардуино бейсик
- Боинг 727 из лего
- Поезд лего дупло не заезжает на мост
Роли, права доступа
Объект конфигурации «роль» дает набор прав на операции (действия) над объектами конфигурации.
Роль «Полные права».
Это всего лишь роль (не предопределенная), в которой установлены флажки на все виды прав на все объекты конфигурации.
Отличие ее от остальных ролей – наличие права «Администрирование».
В случае создания хотя бы одного пользователя, система начинает проверять наличие права «Администрирование» — оно должно быть минимум у одного пользователя.
Ограничение доступа на уровне записей
Row Level Security (RLS) – ограничение на уровне записей.
Механизм ограничений доступа к данным позволяет управлять правами доступа не только на уровне объектов метаданных, но и на уровне объектов базы данных. Для ограничения доступа к данным могут быть использованы следующие объекты:
- роли,
- параметры сеанса,
- функциональные опции,
- привилегированные общие модули,
- ключевое слово РАЗРЕШЕННЫЕ в языке запросов.
Механизм предназначен для ограничения доступа к записям таблицы объектов метаданных по произвольным условиям, накладываемым на значения полей строк этих таблиц. Например, чтобы видеть записи только по «своим» контрагентам, организациям и т.д.
1С формирует запрос к СУБД. Кластер серверов добавляет к запросу секцию ГДЕ, в которой содержится текст условия на ограничение доступа по RLS, затем этот запрос отправляется в СУБД, извлеченные данные возвращаются на клиент 1С.
Такой механизм будет работать при любом запросе из клиента:
- в отчетах,
- в динамических списках и в обычных формах списков
- в произвольных запросах.
Подобная реализация механизма сильно влияет на производительность.
Пути обхода ограничений доступа.
В больших ресурсоемких операциях (обработки перепроведения документов, например) часть кода можно выносить в привилегированные модули.
А) Привилегированный модуль — это общий модуль с флагом «Привилегированный» в свойствах.
Его особенность заключается в том, что код в нем исполняется без какого-либо контроля прав доступа, в том числе и RLS.
Б) Также привилегированный режим можно включить для модулей объектов документов. Это делается в свойствах документа, флаг
- Привилегированный режим при проведении
- Привилегированный режим при отмене проведения
В) Метод УстановитьПривилегированныйРежим()
Системная команда, позволяет сделать часть кода любого модуля привилегированной.
Со следующей строки кода будет действовать привилегированный режим исполнения.
Действовать он будет до строки отключения этого режима или до конца процедуры / функции
УстановитьПривилегированныйРежим (Истина);
// любой код тут будет исполнен без контроля прав и RLS
УстановитьПривилегированныйРежим (Ложь); // либо конец процедуры / функции
Количество включений привилегированного режима должно совпадать с количеством выключений. Однако если внутри процедуры или функции происходило включение привилегированного режима (один раз или более), но не происходило его выключение, то система автоматически выполнит выключение столько раз, сколько незавершенных включений было в покидаемой процедуре или функции
Если в процедуре или функции вызовов метода УстановитьПривилегированныйРежим(Ложь) сделано больше, чем вызовов метода УстановитьПривилегированныйРежим(Истина), то будет вызвано исключение
Функция ПривилегированныйРежим() возвращает Истина, если привилегированный режим еще включен, и Ложь, если он полностью выключен. При этом не анализируется количество установок привилегированного режима в конкретной функции.
Все вызванные процедуры и функции также будут исполняться в привилегированном режиме.
Также существует возможность стартовать привилегированный сеанс. Это сеанс, в котором привилегированный режим установлен с самого начала работы системы. При этом во время работы метод ПривилегированныйРежим() будет всегда возвращать Истина, а возможность отключить привилегированный режим не поддерживается. Стартовать привилегированный сеанс может только пользователь, которому доступны административные права (право Администрирование). Запуск сеанса можно выполнить с помощью ключа командной строки запуска клиентского приложения UsePrivilegedMode или параметра строки соединения с информационной базой prmod.
Закономерно возникает вопрос: Зачем тогда вообще настраивать ограничения доступа, если его можно так легко обойти?
Безопасный режим.
Да, можно написать внешнюю обработку с привилегированным режимом исполнения и выгрузить / испортить данные. Для предотвращения этого в системе есть метод глобального контекста
УстановитьБезопасныйРежим().
Безопасный режим кроме прочего игнорирует привилегированный режим.
Его нужно устанавливать перед программным вызовом внешних обработок или экспортных процедур и функций из их модулей.
При выполнении запрещенных операций во время выполнения генерирует исключение.
Кроме этого, для пользователей можно выключить на уровне настройки ролей возможность интерактивного запуска внешних отчетов и обработок.
Настройка ограничения доступа
RLS можно настроить только для прав:
- чтение (select)
- добавление (insert)
- изменение (update)
- удаление (delete)
Для операций чтения и удаления объект, находящийся в базе данных, должен соответствовать ограничению доступа к данным.
Для операции добавления ограничению доступа к данным должен соответствовать объект, который планируется записать в базу данных.
Для операции изменения ограничению доступа к данным должен соответствовать объект как до изменения (чтобы объект был прочитан), так и после изменения (чтобы объект был записан).
Для всех остальных прав такой возможности нет.
Добавим новое ограничение для права «чтение» справочника «Номенклатура». Откроется список полей, для которых можно настроить добавляемое ограничение.
Это означает, что при попытке получить доступ к отмеченным флажками полям, ограничение сработает, а при попытке получить доступ к неотмеченным полям ограничение не сработает.
Если выбрать флаг «Прочие поля», ограничение будет настроено для всех полей таблицы, кроме полей, для которых ограничения заданы явным образом.
*Особенность: для прав добавление, изменение, удаление:
- Ограничение может быть настроено только для всех полей.
- Ограничение может быть только одно.
Для права «Чтение» можно настроить несколько условий, они будут объединяться логическим оператором «И».
В ограничениях на объекты базы данных следующих типов могут быть использованы не все поля основного объекта данных ограничения:
- в регистрах накопления ограничения доступа могут содержать только измерения основного объекта ограничения;
- в регистрах бухгалтерии в ограничениях можно использовать только балансовые измерения основного объекта ограничения
Если в условиях ограничения доступа к данным оборотного регистра накопления используются измерения, не входящие в итоги, то при обращении к виртуальной таблице оборотов не используются хранимые итоги и запрос выполняется полностью по таблице движений.
Механизм наложения ограничений доступа.
Любая операция над данными, хранимыми в базе данных, в «1С:Предприятии» в конечном счете приводит к обращению к базе данных с некоторым запросом на чтение или изменение данных. В процессе исполнения запросов к базе данных внутренние механизмы «1С:Предприятия» выполняют наложение ограничений доступа. При этом:
- Формируется список прав (чтение, добавление, изменение, удаление), список таблиц базы данных и список полей, используемых этим запросом.
- Из всех ролей текущего пользователя выбираются ограничения доступа к данным для всех прав, таблиц и полей, задействованных в запросе. При этом если какая-нибудь роль не содержит ограничений доступа к данным какой-нибудь таблицы или поля, то это значит, что в данной таблице доступны значения требуемых полей из любой записи. Иначе говоря, отсутствие ограничения доступа к данным означает наличие ограничения ГДЕ Истина.
- Получаются текущие значения всех параметров сеанса и функциональных опций, участвующих в выбранных ограничениях.
Для получения значения параметра сеанса или функциональной опции от текущего пользователя не требуется наличие права на получение этого значения. Однако если значение некоторого параметра сеанса не было установлено, то произойдет ошибка и запрос к базе данных выполнен не будет.
Ограничения, полученные из одной роли, объединяются операцией И.
Ограничения, полученные из разных ролей, объединяются операцией ИЛИ.
Построенные условия добавляются к SQL-запросам, с которыми «1С: Предприятие» обращается к СУБД. При обращении к данным со стороны условий ограничения доступа проверка прав не выполняется (ни к объектам метаданных, ни к объектам базы данных). Причем механизм добавления условий зависит от выбранного способа действия ограничений «все» или «разрешенные».
*Особенность: Если пользователю доступны несколько ролей с настроенными ограничениями на уровне записей к одному объекту, то в этом случае условия ограничений складываются логической операцией «ИЛИ». Другими словами полномочия пользователя складываются.
Отсюда вытекает след вывод: не допускать пересечения условия ограничения доступа к одному объекту в разных ролях, т.к в этом случае сильно усложнится текст запроса и это повлияет на производительность.
Способ «Все».
При наложении ограничений способом «все» к SQL-запросам добавляются условия и поля так, чтобы «1С:Предприятие» могло получить информацию о том, были ли в процессе исполнения запроса к базе данных использованы данные, запрещенные для данного пользователя или нет. Если запрещенные данные были использованы, то инициируется аварийное завершение запроса из-за нарушения прав доступа.
Наложение ограничений доступа способом «все» схематически представлено на рисунке:
Способ «Разрешенные».
При наложении ограничений способом «разрешенные» к SQL-запросам добавляются такие условия, чтобы запрещенные текущему пользователю записи не оказывали влияния на результат запроса. Иначе говоря, при наложении ограничений в режиме «разрешенные» запрещенные данному пользователю записи считаются отсутствующими и на результат операции не влияют, что схематически представлено на рисунке:
Ограничения доступа к данным накладываются на объекты базы данных в момент обращения «1С:Предприятия» к базе данных.
В клиент-серверном варианте «1С:Предприятия» наложение ограничений выполняется на сервере «1С:Предприятия».
Однако эта опция (РАЗРЕШЕННЫЕ) не сработает в случае, если мы в запросе обратимся к таблице, для которой не настроены ограничения доступа, но в которой есть ссылки на строки таблицы с настроенными ограничениями. В этом случае результат запроса выдаст «<Объект не найден>……» вместо значения ссылочного поля.
Если вы разрабатываете отчет или обработку с использованием запросов типовой или самописной конфигурации, всегда ставьте флаг «Разрешенные», чтобы отчет работал под любым пользователем с любым набором прав.
В случае объектного чтения данных из базы нет возможности поставить флаг «Разрешенные». Поэтому нужно настраивать отборы для объектного чтения с учетом возможных ограничений прав доступа для пользователя. Средств получения только разрешенных данных в объектной технике не предусмотрено.
Важно, что если в запросе не указано ключевое слово РАЗРЕШЕННЫЕ, то все отборы, заданные в этом запросе, не должны противоречить ни одному из ограничений на чтение объектов базы данных, используемых в запросе. При этом если в запросе используются виртуальные таблицы, то соответствующие отборы должны быть наложены и на сами виртуальные таблицы.
Практика 1. Конструктор запросов в настройках RLS.
Составим текст секции «ГДЕ» в запросе к справочнику. Можно воспользоваться конструктором запросов.
Конструктор имеет урезанный вид.
Закладка «Таблицы»
Основная таблица будет таблицей объекта, для которого настраивается ограничение.
Можно также выбирать и другие таблицы и настраивать между ними различные связи на закладке «Связи».
Закладка «Условия»
Здесь настраиваются собственно условия ограничения доступа
Добавим условия на реквизит «Цена» справочника номенклатура для права на «чтение» ко всем полям таблицы.
«Номенклатура ГДЕ Номенклатура.Цена > 500»
Проверим, как сработает это простое правило. Таблица справочника содержит такие элементы:
После настройки ограничения доступа таблица покажет только элементы, удовлетворяющие условию:
Пропали также и группы. Изменим текст ограничения
«Номенклатура ГДЕ Номенклатура.Цена > 500
ИЛИ Номенклатура.ЭтоГруппа»
Ну вот теперь то, что нужно.
Далее попробуем сделать то же самое для конкретных полей таблицы. Поставим в настройке ограничения флаг для поля «Код».
Если в настройке списка убрать отображение поля «код», будут выведены все элементы справочника, т.е. ограничение не сработало. Если поставить отображение поля «Код», ограничение будет работать.
При этом, несмотря на то, что элемент справочника виден в поле списка, его форму нельзя будет открыть, потому что настроено ограничение на реквизит. То же самое в произвольном запросе: при попытке получить «ограниченный» реквизит, будет ошибка доступа.
Если попытаться получить «ограниченный» реквизит программным образом, также будет вызвана ошибка доступа.
Более того, нельзя будет обратиться к любым полям объекта через ссылку, т.к при получении ссылки система считывает весь объект целиком, и если в нем есть «ограниченные» реквизиты, объект считан не будет.
Поэтому при программной работе с объектами БД нужно иметь в виду возможные ограничения на уровне записей и получать все нужные данные объекта запросом и затем помещать их в структуру или исполнять часть кода в привилегированном модуле.
После настройки ограничения доступа изменилось отображение строки в списке прав – она стала серой и появилась пиктограмма.
Ограничения при настройке доступа (RLS).
- Нет секции Итоги;
- Нельзя обращаться к виртуальным таблицам регистров;
- В явном виде нельзя использовать параметры;
- Во вложенных запросах могут использоваться любые>/span> средства языка запросов, кроме:
- оператора В ИЕРАРХИИ;
- предложения ИТОГИ;
- результаты вложенных запросов не должны содержать табличные части>/span>;
- виртуальных таблиц, в частности ОстаткиИОбороты
Практика 2. Номенклатура с актуальной ценой.
Сделать ограничение доступа, если нужно выводить номенклатуру с актуальной ценой больше определенного значения, например, 100.
Решение:
Добавляем новое правило ограничения доступа для справочника «Номенклатура» на право «чтение».
Выбираем «прочие поля».
В конструкторе добавляем вложенный запрос. В нем выбираем таблицу регистра сведений «Цены номенклатуры».
Вкладки «порядок» нет – это особенность конструктора запросов для построения запроса ограничения доступа.
На вкладке «Дополнительно» ставим «первые 999999999», вкладка «порядок» появилась.
Настраиваем упорядочивание по полю «Период» по убыванию.
Затем настраиваем связь основной таблицы с вложенным запросом по ссылке.
Шаблоны ограничений доступа.
Практика 3. Ограничение на «контрагенты» по значению в константе.
Настроим ограничение доступа для справочника Контрагенты по значению, которое хранится в Константе.
Кроме этого, нужно настроить ограничение и для всех объектов, использующих справочник «Контрагенты» в реквизитах.
Решение
Для справочника «Контрагенты» для права «чтение» настроим ограничение, добавив в секцию «Условия» вложенный запрос к константе. Не забыть ЭтоГруппа.
Видим проблему, справочник Контрагенты фильтруется верно, а документы с реквизитом «Контрагент» отображаются все, некоторые с «битыми» ссылками в реквизите «Контрагент».
Теперь нужно настроить ограничение доступа для всех объектов, использующих ссылку на «Контрагенты». Найдем их сервисом «поиск ссылок на объект».
Скопируем и немного доработаем текст условия RLS из справочника «Контрагенты». Это нужно сделать столько раз, сколько найдено объектов.
Или использовать шаблон ограничений доступа, чтобы избежать проблем дублирования кода.
Шаблоны ограничений доступа настраиваются на уровне роли и могут использоваться для любого объекта в рамках редактируемой роли.
Можно вынести в шаблон любой кусок текста ограничения доступа. Вызов шаблона осуществляется через символ «#». Например, #ШаблонКонтрагент.
Через # в 1С пишутся инструкции препроцессору. В контексте исполнения настроек ограничений доступа платформа заменяет текст вызова шаблона на текст шаблона.
Вынесем в шаблон «ШаблонКонтрагент» текст после слова ГДЕ, кроме текста про ЭтоГруппа.
Параметры в шаблонах ограничений доступа.
Продолжим решение задачи 2.
Проблема заключается теперь в том, что основная таблица в справочнике называется «контрагент», в документе «Приходная накладная». Проверяемое поле в справочнике называется «ссылка», в документе – «Контрагент».
Изменим в тексте шаблона название основной таблицы на «#ТекущаяТаблица»
«#ТекущаяТаблица» — это предопределенный параметр.
И через точку укажем номер входного параметра – «.#Параметр(1)
«#Параметр» — это тоже предопределенное значение. Может содержать произвольное количество входных параметров. Обращение к ним происходит по порядковому номеру.
В тексте ограничения доступа для справочника укажем следующее:
«Контрагенты ГДЕ #ШаблонКонтрагент(«Ссылка») ИЛИ ЭтоГруппа»
Для документа следующее:
«РеализацияТоваров ГДЕ #ШаблонКонтрагент(«Контрагент»)»
При вызове шаблона ограничения доступа параметры в него передавать нужно только как Строка, т.е в кавычках.
Пример.
Основная таблица — Номенклатура
Текст шаблона такой:
#ТекущаяТаблица ГДЕ #ТекущаяТаблица.#Параметр(1) = #Параметр(2)
Вызов | Результирующий текст |
---|---|
#Шаблон(«ЭтоГруппа»,»Истина») | Номенклатура ГДЕ Номенклатура.ЭтоГруппа = Истина |
#Шаблон(«Наименование»,»Стул») | Номенклатура ГДЕ Номенклатура.Наименование = «Стул» |
#Шаблон(«Цена»,»100″) | Номенклатур ГДЕ Номенклатура.Цена = 100 |
Текст шаблона содержит часть текста на языке ограничения доступа к данным и может содержать параметры, которые выделяются при помощи символа «#».
После символа «#» могут следовать:
- Одно из ключевых слов:
- Параметр, после которого в скобках указывается номер параметра в шаблоне;
- ТекущаяТаблица – обозначает вставку в текст полного имени таблицы, для которой строится ограничение;
- ИмяТекущейТаблицы – обозначает вставку в текст полного имени таблицы (как строковое значение, в кавычках), к которой применяется инструкция, на текущем варианте встроенного языка;
- ИмяТекущегоПраваДоступа – содержит имя права, для которого выполняется текущее ограничение: ЧТЕНИЕ/READ, ДОБАВЛЕНИЕ/INSERT, ИЗМЕНЕНИЕ/UPDATE, УДАЛЕНИЕ/DELETE;
- имя параметра шаблона – означает вставку в текст ограничения соответствующего параметра шаблона;
- символ «#» – обозначает вставку в текст одного символа «#».
В выражении ограничения доступа могут содержаться:
- Шаблон ограничения доступа, который указывается в формате #ИмяШаблона(«Значение параметра шаблона 1», «Значение параметра шаблона 2»,…). Каждый параметр шаблона заключается в двойные кавычки. При необходимости указания в тексте параметра символа двойной кавычки следует использовать две двойные кавычки.
- Функция СтрСодержит(ГдеИщем, ЧтоИщем). Функция предназначена для поиска вхождения строки ЧтоИщем в строке ГдеИщем. Возвращает Истина в случае, если вхождение обнаружено и Ложь – в противном случае.
- Оператор + для конкатенации строк.
Для удобства редактирования текста шаблона на закладке Шаблоны ограничений в форме роли нужно нажать кнопку Установить текст шаблона. В открывшемся диалоге ввести текст шаблона и нажать кнопку ОК.
Использование параметров в запросе ограничения доступа
В запросах на ограничение доступа можно использовать параметры &ИмяПараметра.
Однако, это не те параметры в обычном понимании, которые мы используем в отчетах и произвольных запросах.
Их нельзя установить методом УстановитьПараметр() или чем-то подобным.
В качестве параметров в данном случае выступают:
- Параметры сеанса
- Функциональные опции
Чтение параметров сеанса в запросе ограничения доступа происходит в привилегированном режиме, т.е без контроля прав на операции с ними.
Практика 4. Доступ к «своим» контрагентам
Необходимо настроить ограничение доступа текущего пользователя к «своим» контрагентам.
Есть справочник «Пользователи», справочник «Контрагенты», документы с реквизитом «Контрагент».
Текущий пользователь должен видеть данные только по тем контрагентам, для которых с ним установлена связь.
Связь тоже нужно настроить.
Возможные варианты:
Установления связей пользователь + контрагент
- Реквизит в справочнике контрагенты
- Регистр сведений
Возможные решения задачи:
- Хранить пользователя в константе – плохой вариант, константа доступна всем пользователям.
- Хранить в параметрах сеанса фиксированный массив контрагентов текущего пользователя – не очень хороший вариант, контрагентов может быть много
- Хранить в параметрах сеанса текущего пользователя, затем запросом получать список «его» контрагентов – приемлемый вариант.
- Другие варианты.
Решение.
Создадим новый параметр сеанса «ТекущийПользователь» и пропишем его заполнение в модуле сеанса.
Создадим регистр сведений «Соответствие менеджеров и контрагентов»
Создадим новую роль и в ней новое ограничение доступа для документа «ПриходнаяНакладная».
В тексте запроса соединим основную таблицу с регистром сведений по Контрагент = Контрагент и Менеджер = &ТекущийПользователь. Вид соединения Внутреннее.
По возможности лучше избегать вложенных запросов в текстах ограничения доступа, т.к он будет выполняться при каждом чтении данных из этого объекта из БД.
Проверяем – ограничения работают
*Особенность: Если изменить список контрагентов пользователя в регистре ограничения доступа будут действовать сразу без перезапуска сеанса пользователя.
Практика 5. Дата запрета изменений.
Необходимо реализовать ограничение на редактирование данных раньше установленной даты запрета изменений.
Ограничивать нужно для пользователей.
Решение.
Создадим регистр сведений «ДатыЗапретаИзменений» с измерением Пользователь, ресурс ДатаЗапрета.
Построим логику решения таким образом:
- если не указан пользователь, значит, запрет действует для всех пользователей
- если есть ограничение для всех пользователей и ограничение для конкретного пользователя, тогда действует ограничение для конкретного пользователя, а для остальных по общему принципу.
Очевидно, что такое ограничение можно настроить для объектов базы данных, которые имеют некоторую позицию на оси времени. Это могут быть
- Документы
- Периодические регистры сведений
Создадим новую роль «ОраниченияПоДатеЗапретаИзменений».
В ней для документа «ПриходнаяНакладная» для права «изменение» добавим новое ограничение доступа.
Настройку указываем для всех полей.
Текст ограничения такой:
ПриходнаяНакладная ИЗ Документ.ПриходнаяНакладная КАК ПриходнаяНакладная
ВНУТРЕННЕЕ СОЕДИНЕНИЕ (ВЫБРАТЬ
ДатыЗапретаИзменений.ДатаЗапрета КАК ДатаЗапрета
ИЗ
РегистрСведений.ДатыЗапретаИзменений КАК ДатыЗапретаИзменений
ВНУТРЕННЕЕ СОЕДИНЕНИЕ (ВЫБРАТЬ
МАКСИМУМ(ДатыЗапретаИзменений.Пользователь) КАК Пользователь
ИЗ
РегистрСведений.ДатыЗапретаИзменений КАК ДатыЗапретаИзменений
ГДЕ
(ДатыЗапретаИзменений.Пользователь = &ТекущийПользователь
ИЛИ ДатыЗапретаИзменений.Пользователь = ЗНАЧЕНИЕ(Справочник.пользователи.ПустаяСсылка))) КАК ВЗ_Пользователь
ПО ДатыЗапретаИзменений.Пользователь = ВЗ_Пользователь.Пользователь) КАК ВложенныйЗапрос
ПО ПриходнаяНакладная.Дата > ВложенныйЗапрос.ДатаЗапрета
Проверяем – ограничение работает.
Использование инструкций препроцессору
#Если Условие1 #Тогда
Фрагмент запроса 1
#ИначеЕсли Условие2 #Тогда
Фрагмент запроса 2
#Иначе
Фрагмент запроса 3
#КонецЕсли
В условиях можно использовать логические операции (и. или, не и т.д) и обращение к параметрам сеанса.
Такой подход в контексте построения ограничений доступа удобен тем, что в зависимости от условий будет скомпилирован более короткий текст запроса. А более простой запрос меньше нагружает систему.
Минус заключается в том, что конструктор запроса с таким текстом работать не будет.
*Особенность:
В отличие от инструкций препроцессору встроенного языка в текстах ограничения доступа перед оператором Тогда нужно ставить решетку — #Тогда
Практика 6. Переключатель «Использовать RLS»
Дополним нашу систему ограничений переключателем, который включает/выключает использование ограничение на уровне записей.
Для этого добавим Константу и параметр сеанса с именем «ИспользоватьRLS».
Пропишем в Модуле сеанса установку значения параметра сеанса из значения константы.
Добавим во все тексты ограничения доступа такой код:
«#Если &ИспользоватьRLS #Тогда ….. #КонецЕсли»
Проверяем – все работает.
Однако, теперь после включения флага «использовать РЛС» изменения сразу в силу не вступят. Почему?
Потому что параметр сеанса устанавливается при запуске сеанса.
Можно сделать так, чтобы в момент записи нового значения константы переустанавливалось значение параметра сеанса, но это будет работать только для текущего сеанса пользователя. Другим пользователям необходимо выдавать сообщение о необходимости перезапустить систему.
Работа со всеми ролями и ограничениями доступа.
Часто может возникать ситуация когда одинаковое ограничение нужно настроить для нескольких ролей.
Для этого в платформе есть возможность просматривать и редактировать все ограничения доступа.
Дерево метаданных — > Роли — > контекстное меню — > Все ограничения прав.
В этом окне можно:
- просмотреть все имеющиеся в системе ограничения прав доступа
- отредактировать ограничения прав доступа
- добавить новое ограничение сразу для нескольких ролей
- скопировать ограничение прав на другие роли (копирование шаблона нужно будет выполнять вручную)
- удалить сразу несколько ограничений доступа
Решение проблем с RLS
Ограничение доступа к данным
Механизм ограничений доступа к данным (также известный как RLS, Row Level Security) позволяет управлять правами доступа не только на уровне объектов метаданных, но и на уровне объектов базы данных «1С:Предприятия». Для ограничения доступа к данным могут быть использованы следующие объекты «1С:Предприятия»:
● роли,
● параметры сеанса,
● функциональные опции,
● привилегированные общие модули,
● ключевое слово РАЗРЕШЕННЫЕ в языке запросов.
Совместное использование перечисленных объектов позволяет обеспечить максимальную гибкость при необходимости разграничения прав доступа к данным между пользователями, выполняющими различные функции.
Ограничения доступа к данным могут накладываться на следующие операции с данными (права доступа): чтение (право Чтение), добавление (право Добавление), изменение (право Изменение) и удаление (право Удаление). Текущий пользователь будет иметь возможность выполнить требуемую операцию в следующих случаях:
● Для операций чтения и удаления объект, находящийся в базе данных, должен соответствовать ограничению доступа к данным.
● Для операции добавления ограничению доступа к данным должен соответствовать объект, который планируется записать в базу данных.
● Для операции изменения ограничению доступа к данным должен соответствовать объект как до изменения (чтобы объект был прочитан), так и после изменения (чтобы объект был записан).
При наложении ограничений доступа к данным следует помнить, что для операций изменения, добавления и удаления можно задать только одно условие, а для операции чтения можно задать более одного ограничения доступа к данным. Это означает, что для чтения разных полей объекта могут быть заданы разные условия, причем при задании условия можно указать как имя конкретного поля, так и специальное поле Прочие поля. В первом случае условие будет накладываться только в том случае, если в выборке (которой выполняется чтение данных) будет присутствовать поле, для которого задано ограничение, а во втором – ограничение будет накладываться для всех полей объекта, кроме полей, для которых ограничения заданы явным образом.
При задании ограничения на конкретное поле, это поле будет читано в том случае, если ограничение выполняется, а при задании ограничения на Прочие поля, данные объекта будут прочитаны только в том случае, если ограничение выполняется для всех полей объекта, попавших в запрос чтения данных.
Для объектов базы данных следующих видов могут быть наложены различные ограничения на разные виды изменений (добавление, модификацию, удаление):
● Планы обмена,
● Справочники,
● Документы,
● Планы видов характеристик,
● Планы счетов,
● Планы видов расчета,
● Бизнес-процессы,
● Задачи.
Для следующих видов объектов базы данных возможно наложение ограничений на чтение не только всего объекта целиком, но и отдельных его полей:
● Планы обмена,
● Справочники,
● Документы,
● Журналы документов,
● Планы видов характеристик,
● Планы счетов,
● Планы видов расчета,
● Регистры сведений,
● Бизнес-процессы,
● Задачи.
ВНИМАНИЕ! При обращении к полям объектов базы данных посредством свойств прикладных объектов из встроенного языка «1С:Предприятия» выполняется чтение всего объекта целиком, а не только значения используемого поля. Исключением является получение представления, когда будут прочитаны только значения полей, участвующих в формировании представления.
Ограничения доступа содержатся в ролях, они могут быть указаны для большинства объектов метаданных и записываются на специальном языке, являющимся подмножеством языка запросов.
Язык ограничения доступа к данным
Ограничения доступа к данным описываются на специальном языке, являющимся подмножеством языка запросов (подробное описание языка запросов . Язык ограничения доступа к данным имеет следующие изменения относительно языка запросов:
● В запросе ограничения доступа к данным всегда присутствует одна таблица в качестве источника данных – это таблица объекта, на который накладывается ограничение (основной объект ограничения).
● Сокращено описание запроса. Язык ограничения доступа к данным использует только секции ИЗ и ГДЕ языка запросов. Так, описание языка запросов выглядит следующим образом:
ВЫБРАТЬ [РАЗРЕШЕННЫЕ] [РАЗЛИЧНЫЕ] [ПЕРВЫЕ <Количество>]
<Список полей выборки>
[ИЗ <Список источников>]
[ГДЕ <Условие отбора>]
[СГРУППИРОВАТЬ ПО <Поля группировки>]
[ИМЕЮЩИЕ <Условие отбора>]
[ДЛЯ ИЗМЕНЕНИЯ [<Список таблиц верхнего уровня>]]
В то время как описание языка запросов ограничения доступа к данным выглядит следующим образом:
[Псевдоним таблицы основного объекта ограничения]
[ИЗ <Список источников>]
[ГДЕ <Условие отбора>]
Во вложенных запросах, используемых в языке ограничения доступа к данным, ограничен набор допустимых возможностей ;
● В качестве элементов условий можно указывать параметры сеанса и функциональные опции ;
● В любом месте запроса ограничения доступа к данным допустимо использование шаблонов, упрощающих написание ограничений.
Главной частью ограничения является условие, которое вычисляется для каждой записи таблицы базы данных, на которую накладывается ограничение доступа к данным. Запись считается доступной в том случае, если в результате работы условия для одной записи таблицы основного объекта ограничения получена не пустая таблица (т.е. таблица, в которой 1 или более записей). Если в результате работы условия получается пустая таблица – запись, для которой условие исполнилось таким образом, считается недоступной. Причем изменение записи таблицы основного объекта ограничения
считается допустимым, если запись не противоречит ограничению, указанному для права, как до выполнения операции изменения, так и после выполнения этой операции.
Поля таблиц
В ограничениях доступа к данным можно использовать:
● Поля таблиц объекта, для которого описывается ограничение доступа к данным.
Например, если ограничение накладывается на чтение элементов справочника Контрагенты, то в ограничении могут использоваться поля справочника Контрагенты и его табличных частей. В частности, наиболее простые ограничения на чтение элементов справочника Контрагенты могут выглядеть так:
ГДЕ Наименование = “Кирпичный завод”
Или так:
ГДЕ Продукция.Наименование = “Кирпич красный”
Где Продукция – это табличная часть справочника Контрагенты.
● Поля таблиц объектов, доступных по ссылкам в основном объекте ограничения.
Например, если реквизит ОсновнойМенеджер справочника Контрагенты имеет тип ссылки на справочник Пользователи, то ограничение доступа может иметь, например, следующий вид:
ГДЕ ОсновнойМенеджер.Код = “Иванов”
Или:
ГДЕ ОсновнойМенеджер.ФизическоеЛицо.Наименование = “Петровский”
● Поля таблиц объектов, связанных с основным объектом ограничения некоторыми условиями и выражения над ними.
Например, на чтение элементов справочника Контрагенты может быть наложено следующее ограничение:
Контрагенты
ИЗ
Справочник.Контрагенты КАК Контрагенты
ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Пользователи КАК Пользователи
ПО Контрагенты.ОсновнойМенеджер.Наименование = Пользователи.Наименование
ГДЕ Пользователи.ФизическоеЛицо.Наименование = “Петровский”
В этом ограничении используются поля элементов справочника Пользователи, связанных с данным элементом справочника Контрагенты по значению полей Наименование.
Вложенные запросы
Вложенные запросы используются для формирования наборов записей, которые могут использоваться:
● для связывания с таблицей основного объекта ограничения;
● для использования в качестве операнда операций сравнения В или НЕ В.
Во вложенных запросах могут использоваться любые средства языка запросов, кроме:
● оператора В ИЕРАРХИИ;
● предложения ИТОГИ;
● результаты вложенных запросов не должны содержать табличные части;
● некоторых виртуальных таблиц, в частности ОстаткиИОбороты.
В следующем примере ограничения на чтение из справочника Контрагенты, вложенный запрос используется в качестве набора записей для связывания с основным объектом ограничения:
Контрагенты
ИЗ
Справочник.Контрагенты КАК Контрагенты
ЛЕВОЕ СОЕДИНЕНИЕ
(ВЫБРАТЬ
Пользователи.Наименование, Пользователи.ФизическоеЛицо
ИЗ
Справочник.Пользователи КАК Пользователи
ГДЕ
Пользователи.Код > “Петечкин”) КАК Пользователи
ПО Контрагенты.ОсновнойМенеджер.Наименование = Пользователи.Наименование
ГДЕ Пользователи.ФизическоеЛицо.Наименование = “Петровский”
В следующем примере приведено ограничение на чтение из справочника ПаспортныеДанныеФизЛиц, в котором вложенный запрос используется в
качестве операнда операции сравнения В:
ГДЕ
ПаспортныеДанныеФизЛиц.ФизЛицо В
(ВЫБРАТЬ РАЗЛИЧНЫЕ
Работники.ФизЛицо КАК ФизЛицо
ИЗ
РегистрСведений.Работники КАК Работники)
Если во вложенном запросе необходимо получить данные из табличной части, то в разделе ИЗ вложенного запроса необходимо обращаться непосредственно к табличной части. Например, вместо:
ВЫБРАТЬ Ссылка КАК Ссылка,
Продукция.Наименование КАК НаименованиеПродукции
ИЗ Справочник.Контрагенты
в качестве запроса, вложенного в ограничение, следует использовать:
ВЫБРАТЬ Ссылка КАК Ссылка,
Наименование КАК НаименованиеПродукции
ИЗ Справочник.Контрагенты.Продукция
Параметры сеанса
В составе запросов ограничения доступа к данным могут входить параметры сеанса. Например, на чтение элементов справочника ГруппыПисемЭлектроннойПочты может быть задано следующее ограничение доступа:
ГДЕ Владелец.ДоступКУчетнойЗаписи.Пользователь = &ТекущийПользователь
И Владелец.ДоступКУчетнойЗаписи.Администрирование = ИСТИНА
ТекущийПользователь – это параметр сеанса
Функциональные опции
В составе запросов ограничения доступа к данным могут входить функциональные опции. Могут использоваться только не зависящие от параметров функциональные опции. Например, если у справочника Номенклатура есть реквизит ОсновнойСклад, то ограничение на чтение данного реквизита может выглядеть следующим образом:
ГДЕ &УчетПоСкладам = ИСТИНА
Где УчетПоСкладам – это функциональная опция
Особенности использования
В ограничениях на объекты базы данных следующих типов могут быть использованы не все поля основного объекта данных ограничения:
● в регистрах накопления ограничения доступа могут содержать только измерения основного объекта ограничения;
● в регистрах бухгалтерии в ограничениях можно использовать только балансовые измерения основного объекта ограничения.
ПРИМЕЧАНИЕ. Если в условиях ограничения доступа к данным оборотного регистра накопления используются измерения, не входящие в итоги, то
при обращении к виртуальной таблице оборотов не используются хранимые итоги и запрос выполняется полностью по таблице движений.
Действия ограничения доступа
Ограничения доступа проверяются при любом выполнении соответствующих операций над объектами базы данных (из диалогов, из встроенного языка, посредством запросов) и могут действовать одним из двух способов:
● Все. Способ «все» подразумевает, что некоторая операция над данными (из диалогов, из встроенного языка или посредством запросов) должна быть выполнена над всеми подразумеваемыми данной операцией объектами базы данных. Если при выполнении такой операции должны быть прочитаны или изменены объекты базы данных, для которых не выполняются соответствующие ограничения доступа, то операция завершается
аварийно из-за нарушения прав доступа.
● Разрешенные. Способ «разрешенные» подразумевает, что при выполнении операции над данными должны быть прочитаны только те объекты базы данных, которые удовлетворяют соответствующим ограничениям доступа. Объекты базы данных, не удовлетворяющие ограничениям доступа, при выполнении такой операции считаются отсутствующими и на результат операции не влияют.
Ограничения доступа к данным накладываются на объекты базы данных в момент обращения «1С:Предприятия» к базе данных. В клиент-серверном варианте «1С:Предприятия» наложение ограничений выполняется на сервере «1С:Предприятия».
Способ действия ограничений, выбираемый для выполнения каждой операции над данными, определяется назначением этой операции и степенью ответственности ее результатов. В частности, способ «разрешенные» используется при отображении динамических списков и некоторых других интерактивных действиях. Способ «все» используется при выполнении любых операций с прикладными объектами из встроенного языка «1С:Предприятия», в том числе при любых изменениях объектов базы данных. Поэтому, например, могут возникнуть затруднения при построении отбора для метода Выбрать() менеджеров справочников, документов и других с последующим обходом результата в том случае, если на соответствующий объект установлено достаточно сложное ограничение, поскольку не всякое условие в ограничении прав доступа может быть адекватно представлено в виде отбора для метода Выбрать().
В запросах способом действия ограничений доступа к данным можно управлять. Для этого в языке запросов предусмотрено ключевое слово РАЗРЕШЕННЫЕ. Если в запросе не указано РАЗРЕШЕННЫЕ, то ограничения действуют способом «все». Если слово РАЗРЕШЕННЫЕ указано, то выбирается способ «разрешенные».
Важно, что если в запросе не указано ключевое слово РАЗРЕШЕННЫЕ, то все отборы, заданные в этом запросе, не должны противоречить ни одному из ограничений на чтение объектов базы данных, используемых в запросе. При этом если в запросе используются виртуальные таблицы, то соответствующие отборы должны быть наложены и на сами виртуальные таблицы.
Пример:
ВЫБРАТЬ
КонтактнаяИнформацияСрезПервых.Представление
ИЗ РегистрСведений.КонтактнаяИнформация.СрезПоследних(, Тип = &Тип)
КАК КонтактнаяИнформацияСрезПервых
ГДЕ
КонтактнаяИнформацияСрезПервых.Тип = &Тип
При использовании объектной техники не поддерживается получение доступа к данным в режиме РАЗРЕШЕННЫЕ. Предполагается, что объектная техника используется для наиболее ответственных операций над данными, в том числе для их изменения. Для получения при помощи объектной техники всех данных, независимо от установленных ограничений, можно выполнять необходимые действия в привилегированном модуле или от имени пользователя с полными правами. Средств получения только разрешенных данных в объектной технике не предусмотрено.
Механизм наложения ограничений
Любая операция над данными, хранимыми в базе данных, в «1С:Предприятии» в конечном счете приводит к обращению к базе данных с некоторым
запросом на чтение или изменение данных. В процессе исполнения запросов к базе данных внутренние механизмы «1С:Предприятия» выполняют наложение ограничений доступа. При этом:
● Формируется список прав (чтение, добавление, изменение, удаление), список таблиц базы данных и список полей, используемых этим запросом.
● Из всех ролей текущего пользователя выбираются ограничения доступа к данным для всех прав, таблиц и полей, задействованных в запросе. При этом если какая-нибудь роль не содержит ограничений доступа к данным какой-нибудь таблицы или поля, то это значит, что в данной таблице доступны значения требуемых полей из любой записи. Иначе говоря, отсутствие ограничения доступа к данным означает наличие ограничения
ГДЕ Истина.
● Получаются текущие значения всех параметров сеанса и функциональных опций, участвующих в выбранных ограничениях.
Для получения значения параметра сеанса от текущего пользователя не требуется наличие права на получение этого значения. Однако если значение некоторого параметра сеанса не было установлено, то произойдет ошибка и запрос к базе данных выполнен не будет.
На получение функциональных опций оказывает влияние свойство функциональной опции Привилегированный режим при получении .
Если это свойство сброшено, то текущий пользователь должен обладать правами на чтение объекта, в котором хранится функциональная опция.
● Ограничения, полученные из одной роли, объединяются операцией И.
● Ограничения, полученные из разных ролей, объединяются операцией ИЛИ.
● Построенные условия добавляются к SQL-запросам, с которыми «1С:Предприятие» обращается к СУБД. При обращении к данным со стороны условий ограничения доступа проверка прав не выполняется (ни к объектам метаданных, ни к объектам базы данных). Причем механизм добавления условий зависит от выбранного способа действия ограничений «все» или «разрешенные».
Способ «все»
При наложении ограничений способом «все» к SQL-запросам добавляются условия и поля так, чтобы «1С:Предприятие» могло получить информацию о том, были ли в процессе исполнения запроса к базе данных использованы данные, запрещенные для данного пользователя или нет. Если запрещенные данные были использованы, то инициируется аварийное завершение запроса. Наложение ограничений доступа способом «все» схематически представлено на рис. 1:
Способ «разрешенные»
При наложении ограничений способом «разрешенные» к SQL-запросам добавляются такие условия, чтобы запрещенные текущему пользователю записи не оказывали влияния на результат запроса. Иначе говоря, при наложении ограничений в режиме «разрешенные» запрещенные данному пользователю записи считаются отсутствующими,что схематически представлено на рис 3
Другие объекты, связанные с ограничениями доступа к данным
При разработке конфигураций с использованием ограничений доступа к данным могут оказаться полезными такие объекты метаданных, как параметры сеанса, функциональные опции и общие модули с флажком Привилегированный.
Параметры сеанса
Параметры сеанса могут использоваться в ограничениях доступа к данным аналогично тому, как в запросе могут использоваться параметры запроса.
Функциональные опции
Не зависящие от параметров функциональные опции могут использоваться в ограничениях доступа к данным аналогично тому, как в запросе могут использоваться параметры запроса.
Привилегированные общие модули
Если для общего модуля установлен флажок Привилегированный, то исполнение процедур и функций этого модуля приобретает важную специфику:
● В клиент-серверном варианте «1С:Предприятия» привилегированным может быть только тот модуль, который исполняется на сервере.
● Исполнение процедур и функций привилегированного модуля и всего, что из них вызвано, выполняется при выключенной системе ограничения
прав, как к объектам метаданных, так и к данным. Таким образом, из привилегированного модуля может быть выполнена любая операция над
любыми объектами даже в том случае, если текущий пользователь не имеет соответствующих прав.
Привилегированные модули предназначены для начальной установки значений параметров сеанса, используемых в ограничениях доступа к данным.
Еще общие модули могут быть использованы для некоторых целостных действий над данными со стороны пользователя с ограниченными правами.
Например, если в функции пользователя входит ввод и проведение документов, но пользователь не должен иметь доступа к данным, на которые влияет проведение документа, то выполнение операции проведения может быть вынесено в привилегированный модуль. Это позволит пользователю проводить документы без предоставления ему прав на другую информацию (регистры, например).
Привилегированный режим
Имеется возможность программной установки привилегированного режима при работе с данными. Программная установка привилегированного режима
может потребоваться в случае массированных операций с данными информационной базы, и при этом нет смысла проверять права доступа к данным.
Описание привилегированного режима см. здесь.
Использование препроцессора
При редактировании текста ограничения доступа к данным возможно использование инструкций препроцессора. Доступны следующие инструкции:
#ЕСЛИ <Выражение> #ТОГДА
#ИНАЧЕЕСЛИ <Выражение> #ТОГДА
#ИНАЧЕ
#КОНЕЦЕСЛИ
<Выражение> – произвольное логическое выражение на встроенном языке, результат которого имеет тип Булево. Выражение может содержать:
● операции сравнения <, >, <=, >= , =, <>;
● логические операции И, ИЛИ, НЕ;
● параметры сеанса – используется синтаксис &Параметр, где Параметр – имя параметра сеанса.
Если результатом выражения инструкции #ЕСЛИ или #ИНАЧЕЕСЛИ является значение Истина, то в результирующий текст инструкции ограничения доступа помещается текст, расположенный после ключевого слова #ТОГДА. Если же результатом выражения является значение Ложь, то текст, расположенный после ключевого слова #ТОГДА, не помещается в текст инструкции ограничения доступа. Текст, расположенный после инструкции #ИНАЧЕ, будет помещен в результирующий текст ограничения доступа, если ни одно из ранних условий не было выполнено.
ПРИМЕЧАНИЕ. Если текст ограничения доступа к данным содержит инструкции препроцессора, то такое ограничение не проходит проверку синтаксиса при редактировании и не может быть изменено при помощи конструктора.
Пример:
#ЕСЛИ &ТекущийПользователь <> “Климова” #ТОГДА
<текст ограничения доступа>
#КОНЕЦЕСЛИ
Здесь ТекущийПользователь – параметр сеанса типа СправочникСсылка.Пользователи.
Такая конструкция означает, что условие для установки ограничения доступа будет проверяться для всех пользователей из справочника, кроме пользователя Климовой.
Шаблоны текста ограничения доступа
Роль может содержать список шаблонов ограничения доступа, которые описываются на закладке Шаблоны ограничений формы роли. Также шаблоны ограничения доступа можно редактировать в редакторе группового редактирования ограничений доступа и шаблонов .
Каждый шаблон ограничения доступа имеет имя и текст. Имя шаблона подчиняется обычным правилам для имен, принятых в системе «1С:Предприятие».
Текст шаблона содержит часть текста на языке ограничения доступа к данным и может содержать параметры, которые выделяются при помощи символа
“#”.
После символа “#” могут следовать:
● Одно из ключевых слов:
● Параметр, после которого в скобках указывается номер параметра в шаблоне;
● ТекущаяТаблица – обозначает вставку в текст полного имени таблицы, для которой строится ограничение;
● ИмяТекущейТаблицы – обозначает вставку в текст полного имени таблицы (как строковое значение, в кавычках), к которой применяется инструкция, на текущем варианте встроенного языка;
● ИмяТекущегоПраваДоступа – содержит имя права, для которого выполняется текущее ограничение: ЧТЕНИЕ/READ, ДОБАВЛЕНИЕ/INSERT, ИЗМЕНЕНИЕ/
UPDATE, УДАЛЕНИЕ/DELETE;
● имя параметра шаблона – означает вставку в текст ограничения соответствующего параметра шаблона;
● символ “#” – обозначает вставку в текст одного символа “#”.
В выражении ограничения доступа могут содержаться:
● Шаблон ограничения доступа, который указывается в формате
#ИмяШаблона(“Значение параметра шаблона 1”, “Значение параметра шаблона 2”, …). Каждый параметр шаблона заключается в двойные кавычки. При необходимости указания в тексте параметра символа двойной кавычки следует использовать две двойные кавычки.
● Функция СтрСодержит(ГдеИщем, ЧтоИщем). Функция предназначена для поиска вхождения строки ЧтоИщем в строке ГдеИщем. Возвращает Истина в случае, если вхождение обнаружено и Ложь – в противном случае.
● Оператор + для конкатенации строк.
Для удобства редактирования текста шаблона на закладке Шаблоны ограничений в форме роли нужно нажать кнопку Установить текст шаблона. В открывшемся диалоге ввести текст шаблона и нажать кнопку ОК.
Система «1С:Предприятие» выполняет проверку синтаксиса текстов шаблонов, проверку синтаксиса использования шаблонов и макроподстановку текстов шаблонов ограничения доступа роли в текст запроса.
Макроподстановка шаблона заключается:
● в замене вхождений параметров в тексте шаблона на значения параметров из выражения использования шаблона в тексте ограничения;
● в замене выражения использования шаблона в тексте запроса на получившийся текст шаблона.
При вызове конструктора запроса для условия, содержащего шаблоны ограничения доступа, выдается предупреждение о замене всех шаблонов.
Далее приведены примеры шаблонов ограничений:
Общие рекомендации по ограничению прав
Чтобы гибко управлять доступом пользователей к данным в соответствии с функциями при установке ограничений доступа к данным, рекомендуется
придерживаться следующих принципов:
● Нужно выбрать совокупность информации (может быть зависимой от текущего пользователя), для которой целесообразна предварительная подготовка. Выбранная информация должна, с одной стороны, максимально упростить ограничения доступа к данным, а с другой стороны, не должна иметь слишком большой объем. Распределить ее по параметрам сеанса.
● Установить значения параметров сеанса в обработчике УстановкаПараметровСеанса() модуля сеанса.
● Задать ограничения доступа к тем данным, для которых это оправданно (данные являются секретными или наиболее важными для сохранения целостности системы). Необходимо иметь в виду, что установка ограничения доступа может привести к замедлению любого обращения к этим данным. Излишняя сложность ограничений также может привести к замедлению.
● При необходимости обеспечить выполнение некоторого ограниченного количества операций над данными со стороны пользователя, которому полный доступ к этим данным давать нецелесообразно, вынести эти действия в привилегированные модули или явно включать и выключать привилегированный режим в соответствующих местах программного кода.
● Доступ к данным при различных проверках, выполняемых системой при записи объектов, выполняется в привилегированном режиме.
Это позволяет не отключать ограничения в правах на уровне записей для соответствующих полей, если работа конфигурации с этими данными
планируется только в управляемом режиме:
● для справочников при проверке родителя, владельца и уникальности кода;
● для документов, бизнес-процессов и задач при проверке уникальности номера;
● для планов обмена отключена при проверке уникальности кода;
● для планов счетов и планов видов характеристик при проверке родителя и уникальности кода.
При создании запроса ограничения к данным следует помнить о некоторых ограничениях и особенностях:
● Если для объектной таблицы заданы ограничения доступа к данным и в запросе к данным используется объединение с такой таблицей, то в условии соединения (секция запроса ПО) не допускается использование табличной части объекта с заданным ограничением доступа.
● Если в запросе указана таблица, у которой в запросе не используется ни одного поля, то на эту таблицу накладываются все ограничения доступа к данным. Например, запрос ВЫБРАТЬ КОЛИЧЕСТВО(*) ИЗ Справочник.Контрагенты будет исполнен с учетом всех ограничений доступа, заданными для справочника Тест. Ограничения накладываются «по ИЛИ». Это значит, что будут доступны все записи, доступные хотя бы по одному условию. Если для каких-то полей не задано условий, то запрос будет выполнен для всех записей таблицы.
Если в запросе используется таблица верхнего уровня, то ограничения, заданные для колонок вложенных таблиц, не накладываются.
Если в запросе используется вложенная таблица, то накладываются ограничения как для вложенной таблицы, так и для таблицы верхнего уровня.
Например, запрос ВЫБРАТЬ КОЛИЧЕСТВО(*) ИЗ Справочник.Контрагенты.Договора будет исполнен с учетом всех ограничений для справочника Контрагенты, а также с учетом ограничений, относящихся к табличной части Договора.
● Если доступ к полям, необходимым для получения представления ссылочного объекта метаданных, запрещен с помощью ограничений доступа к
данным или доступ к объекту запрещен на уровне прав доступа, то получение представления такого объекта не влияет на ход текущей транзакции.
Конструктор ограничения доступа к данным
Для вызова конструктора в табличном поле Ограничения доступа к данным в колонке Ограничение доступа нужно перейти в режим редактирования и
нажать кнопку выбора, а в открывшейся форме нажать кнопку Конструктор запроса….
На экран выводится форма конструктора:
С его помощью производится формирование условий для установки ограничения доступа к данным.
На закладке Таблицы и поля следует выбрать нужные объекты в списке База данных и перенести их в список Таблицы. Если указано несколько таблиц, то в форме конструктора добавляется закладка Связи.
На закладке Связи формируются условия, которые накладываются на связи между полями таблиц. Для ввода нового условия нужно нажать кнопку Добавить и в колонке Таблица1 выбрать одну из таблиц. В колонке Таблица2 выбрать таблицу, поля которой связаны с полями первой. Ниже списка условий расположены элементы управления, с помощью которых формируется условие связи таблиц.
Если выбран простой тип условия, то в Поле1 и Поле2 выбираются связанные поля указанных таблиц и задается условие сравнения. Если выбраны поля, сравнение которых не производится, то в строке списка условий в колонке Условие связи выводится текст: Неверно заполненное условие.
На закладке Условия, если требуется, нужно указать условия, по которым будет выполняться отбор исходных данных.
По каждому выбранному полю необходимо выбрать вид условия и указать наименование параметра. В качестве параметра допускается использование параметра сеанса. Разрешается указывать несколько условий. В этом случае в колонке Условие табличного поля условий текст условия выводится в несколько строк.
В любой момент создания запроса текст запроса можно просмотреть, нажав кнопку Запрос.
Групповое редактирование ограничений прав доступа и шаблонов
Режим группового редактирования ограничений прав доступа и шаблонов вызывается командой Все ограничения доступа контекстного меню ветки Роли. В открывшейся форме присутствуют две закладки: Ограничения доступа и Шаблоны ограничений.
На закладке Ограничения доступа можно просматривать все введенные ограничения доступа в общем списке (по всем ролям, объектам, правам,комбинациям полей).
Существует возможность добавлять ограничение доступа сразу для нескольких ролей, объектов, прав и комбинаций ролей.
Можно фильтровать список по различным критериям.
Режим группового редактирования позволяет удалять выделенные в списке ограничения.
Существует возможность редактировать выделенные ограничения. При этом можно заменять состав полей и/или ограничение доступа.
Режим группового редактирования позволяет также копировать выделенные ограничения в другие роли.
На закладке Шаблоны ограничений можно видеть все шаблоны ограничения доступа, присутствующие в прикладном решении, при этом из собственно текста шаблона в таблице отображаются только первые 10 строк, которые завершаются символом “…”, если текст шаблона более 10 строк. В окне редактирования шаблона будет отображаться полный текст шаблона.
Существует возможность добавлять шаблон ограничения доступа сразу для нескольких ролей.
Имеется возможность отбирать необходимые шаблоны с помощью набора критериев, а также по значению текущей колонки.
При необходимости имеется возможность выполнить копирование одного или нескольких шаблонов в другие роли.
Роли, права доступа
Объект конфигурации «роль» дает набор прав на операции (действия) над объектами конфигурации.
Роль «Полные права».
Это всего лишь роль (не предопределенная), в которой установлены флажки на все виды прав на все объекты конфигурации.
Отличие ее от остальных ролей – наличие права «Администрирование».
В случае создания хотя бы одного пользователя, система начинает проверять наличие права «Администрирование» — оно должно быть минимум у одного пользователя.
Ограничение доступа на уровне записей
Row Level Security (RLS) – ограничение на уровне записей.
Механизм ограничений доступа к данным позволяет управлять правами доступа не только на уровне объектов метаданных, но и на уровне объектов базы данных. Для ограничения доступа к данным могут быть использованы следующие объекты:
- роли,
- параметры сеанса,
- функциональные опции,
- привилегированные общие модули,
- ключевое слово РАЗРЕШЕННЫЕ в языке запросов.
Механизм предназначен для ограничения доступа к записям таблицы объектов метаданных по произвольным условиям, накладываемым на значения полей строк этих таблиц. Например, чтобы видеть записи только по «своим» контрагентам, организациям и т.д.
1С формирует запрос к СУБД. Кластер серверов добавляет к запросу секцию ГДЕ, в которой содержится текст условия на ограничение доступа по RLS, затем этот запрос отправляется в СУБД, извлеченные данные возвращаются на клиент 1С.
Ограничение доступа к данным
Механизм ограничений доступа к данным (также известный как RLS, Row Level Security) позволяет управлять правами доступа не только на уровне объектов метаданных, но и на уровне объектов базы данных «1С:Предприятия». Для ограничения доступа к данным могут быть использованы следующие объекты «1С:Предприятия»:
● роли,
● параметры сеанса,
● функциональные опции,
● привилегированные общие модули,
● ключевое слово РАЗРЕШЕННЫЕ в языке запросов.
Совместное использование перечисленных объектов позволяет обеспечить максимальную гибкость при необходимости разграничения прав доступа к данным между пользователями, выполняющими различные функции.
Ограничения доступа к данным могут накладываться на следующие операции с данными (права доступа): чтение (право Чтение), добавление (право Добавление), изменение (право Изменение) и удаление (право Удаление). Текущий пользователь будет иметь возможность выполнить требуемую операцию в следующих случаях:
● Для операций чтения и удаления объект, находящийся в базе данных, должен соответствовать ограничению доступа к данным.
● Для операции добавления ограничению доступа к данным должен соответствовать объект, который планируется записать в базу данных.
● Для операции изменения ограничению доступа к данным должен соответствовать объект как до изменения (чтобы объект был прочитан), так и после изменения (чтобы объект был записан).
При наложении ограничений доступа к данным следует помнить, что для операций изменения, добавления и удаления можно задать только одно условие, а для операции чтения можно задать более одного ограничения доступа к данным. Это означает, что для чтения разных полей объекта могут быть заданы разные условия, причем при задании условия можно указать как имя конкретного поля, так и специальное поле Прочие поля. В первом случае условие будет накладываться только в том случае, если в выборке (которой выполняется чтение данных) будет присутствовать поле, для которого задано ограничение, а во втором – ограничение будет накладываться для всех полей объекта, кроме полей, для которых ограничения заданы явным образом.
При задании ограничения на конкретное поле, это поле будет читано в том случае, если ограничение выполняется, а при задании ограничения на Прочие поля, данные объекта будут прочитаны только в том случае, если ограничение выполняется для всех полей объекта, попавших в запрос чтения данных.
Для объектов базы данных следующих видов могут быть наложены различные ограничения на разные виды изменений (добавление, модификацию, удаление):
● Планы обмена,
● Справочники,
● Документы,
● Планы видов характеристик,
● Планы счетов,
● Планы видов расчета,
● Бизнес-процессы,
● Задачи.
Для следующих видов объектов базы данных возможно наложение ограничений на чтение не только всего объекта целиком, но и отдельных его полей:
● Планы обмена,
● Справочники,
● Документы,
● Журналы документов,
● Планы видов характеристик,
● Планы счетов,
● Планы видов расчета,
● Регистры сведений,
● Бизнес-процессы,
● Задачи.
ВНИМАНИЕ! При обращении к полям объектов базы данных посредством свойств прикладных объектов из встроенного языка «1С:Предприятия» выполняется чтение всего объекта целиком, а не только значения используемого поля. Исключением является получение представления, когда будут прочитаны только значения полей, участвующих в формировании представления.
Ограничения доступа содержатся в ролях, они могут быть указаны для большинства объектов метаданных и записываются на специальном языке, являющимся подмножеством языка запросов.
Язык ограничения доступа к данным
Ограничения доступа к данным описываются на специальном языке, являющимся подмножеством языка запросов (подробное описание языка запросов . Язык ограничения доступа к данным имеет следующие изменения относительно языка запросов:
● В запросе ограничения доступа к данным всегда присутствует одна таблица в качестве источника данных – это таблица объекта, на который накладывается ограничение (основной объект ограничения).
● Сокращено описание запроса. Язык ограничения доступа к данным использует только секции ИЗ и ГДЕ языка запросов. Так, описание языка запросов выглядит следующим образом:
ВЫБРАТЬ [РАЗРЕШЕННЫЕ] [РАЗЛИЧНЫЕ] [ПЕРВЫЕ <Количество>]
<Список полей выборки>
[ИЗ <Список источников>]
[ГДЕ <Условие отбора>]
[СГРУППИРОВАТЬ ПО <Поля группировки>]
[ИМЕЮЩИЕ <Условие отбора>]
[ДЛЯ ИЗМЕНЕНИЯ [<Список таблиц верхнего уровня>]]
В то время как описание языка запросов ограничения доступа к данным выглядит следующим образом:
[Псевдоним таблицы основного объекта ограничения]
[ИЗ <Список источников>]
[ГДЕ <Условие отбора>]
Во вложенных запросах, используемых в языке ограничения доступа к данным, ограничен набор допустимых возможностей ;
● В качестве элементов условий можно указывать параметры сеанса и функциональные опции ;
● В любом месте запроса ограничения доступа к данным допустимо использование шаблонов, упрощающих написание ограничений.
Главной частью ограничения является условие, которое вычисляется для каждой записи таблицы базы данных, на которую накладывается ограничение доступа к данным. Запись считается доступной в том случае, если в результате работы условия для одной записи таблицы основного объекта ограничения получена не пустая таблица (т.е. таблица, в которой 1 или более записей). Если в результате работы условия получается пустая таблица – запись, для которой условие исполнилось таким образом, считается недоступной. Причем изменение записи таблицы основного объекта ограничения
считается допустимым, если запись не противоречит ограничению, указанному для права, как до выполнения операции изменения, так и после выполнения этой операции.
Поля таблиц
В ограничениях доступа к данным можно использовать:
● Поля таблиц объекта, для которого описывается ограничение доступа к данным.
Например, если ограничение накладывается на чтение элементов справочника Контрагенты, то в ограничении могут использоваться поля справочника Контрагенты и его табличных частей. В частности, наиболее простые ограничения на чтение элементов справочника Контрагенты могут выглядеть так:
ГДЕ Наименование = “Кирпичный завод”
Или так:
ГДЕ Продукция.Наименование = “Кирпич красный”
Где Продукция – это табличная часть справочника Контрагенты.
● Поля таблиц объектов, доступных по ссылкам в основном объекте ограничения.
Например, если реквизит ОсновнойМенеджер справочника Контрагенты имеет тип ссылки на справочник Пользователи, то ограничение доступа может иметь, например, следующий вид:
ГДЕ ОсновнойМенеджер.Код = “Иванов”
Или:
ГДЕ ОсновнойМенеджер.ФизическоеЛицо.Наименование = “Петровский”
● Поля таблиц объектов, связанных с основным объектом ограничения некоторыми условиями и выражения над ними.
Например, на чтение элементов справочника Контрагенты может быть наложено следующее ограничение:
Контрагенты
ИЗ
Справочник.Контрагенты КАК Контрагенты
ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Пользователи КАК Пользователи
ПО Контрагенты.ОсновнойМенеджер.Наименование = Пользователи.Наименование
ГДЕ Пользователи.ФизическоеЛицо.Наименование = “Петровский”
В этом ограничении используются поля элементов справочника Пользователи, связанных с данным элементом справочника Контрагенты по значению полей Наименование.
Вложенные запросы
Вложенные запросы используются для формирования наборов записей, которые могут использоваться:
● для связывания с таблицей основного объекта ограничения;
● для использования в качестве операнда операций сравнения В или НЕ В.
Во вложенных запросах могут использоваться любые средства языка запросов, кроме:
● оператора В ИЕРАРХИИ;
● предложения ИТОГИ;
● результаты вложенных запросов не должны содержать табличные части;
● некоторых виртуальных таблиц, в частности ОстаткиИОбороты.
В следующем примере ограничения на чтение из справочника Контрагенты, вложенный запрос используется в качестве набора записей для связывания с основным объектом ограничения:
Контрагенты
ИЗ
Справочник.Контрагенты КАК Контрагенты
ЛЕВОЕ СОЕДИНЕНИЕ
(ВЫБРАТЬ
Пользователи.Наименование, Пользователи.ФизическоеЛицо
ИЗ
Справочник.Пользователи КАК Пользователи
ГДЕ
Пользователи.Код > “Петечкин”) КАК Пользователи
ПО Контрагенты.ОсновнойМенеджер.Наименование = Пользователи.Наименование
ГДЕ Пользователи.ФизическоеЛицо.Наименование = “Петровский”
В следующем примере приведено ограничение на чтение из справочника ПаспортныеДанныеФизЛиц, в котором вложенный запрос используется в
качестве операнда операции сравнения В:
ГДЕ
ПаспортныеДанныеФизЛиц.ФизЛицо В
(ВЫБРАТЬ РАЗЛИЧНЫЕ
Работники.ФизЛицо КАК ФизЛицо
ИЗ
РегистрСведений.Работники КАК Работники)
Если во вложенном запросе необходимо получить данные из табличной части, то в разделе ИЗ вложенного запроса необходимо обращаться непосредственно к табличной части. Например, вместо:
ВЫБРАТЬ Ссылка КАК Ссылка,
Продукция.Наименование КАК НаименованиеПродукции
ИЗ Справочник.Контрагенты
в качестве запроса, вложенного в ограничение, следует использовать:
ВЫБРАТЬ Ссылка КАК Ссылка,
Наименование КАК НаименованиеПродукции
ИЗ Справочник.Контрагенты.Продукция
Параметры сеанса
В составе запросов ограничения доступа к данным могут входить параметры сеанса. Например, на чтение элементов справочника ГруппыПисемЭлектроннойПочты может быть задано следующее ограничение доступа:
ГДЕ Владелец.ДоступКУчетнойЗаписи.Пользователь = &ТекущийПользователь
И Владелец.ДоступКУчетнойЗаписи.Администрирование = ИСТИНА
ТекущийПользователь – это параметр сеанса
Функциональные опции
В составе запросов ограничения доступа к данным могут входить функциональные опции. Могут использоваться только не зависящие от параметров функциональные опции. Например, если у справочника Номенклатура есть реквизит ОсновнойСклад, то ограничение на чтение данного реквизита может выглядеть следующим образом:
ГДЕ &УчетПоСкладам = ИСТИНА
Где УчетПоСкладам – это функциональная опция
Особенности использования
В ограничениях на объекты базы данных следующих типов могут быть использованы не все поля основного объекта данных ограничения:
● в регистрах накопления ограничения доступа могут содержать только измерения основного объекта ограничения;
● в регистрах бухгалтерии в ограничениях можно использовать только балансовые измерения основного объекта ограничения.
ПРИМЕЧАНИЕ. Если в условиях ограничения доступа к данным оборотного регистра накопления используются измерения, не входящие в итоги, то
при обращении к виртуальной таблице оборотов не используются хранимые итоги и запрос выполняется полностью по таблице движений.
Действия ограничения доступа
Ограничения доступа проверяются при любом выполнении соответствующих операций над объектами базы данных (из диалогов, из встроенного языка, посредством запросов) и могут действовать одним из двух способов:
● Все. Способ «все» подразумевает, что некоторая операция над данными (из диалогов, из встроенного языка или посредством запросов) должна быть выполнена над всеми подразумеваемыми данной операцией объектами базы данных. Если при выполнении такой операции должны быть прочитаны или изменены объекты базы данных, для которых не выполняются соответствующие ограничения доступа, то операция завершается
аварийно из-за нарушения прав доступа.
● Разрешенные. Способ «разрешенные» подразумевает, что при выполнении операции над данными должны быть прочитаны только те объекты базы данных, которые удовлетворяют соответствующим ограничениям доступа. Объекты базы данных, не удовлетворяющие ограничениям доступа, при выполнении такой операции считаются отсутствующими и на результат операции не влияют.
Ограничения доступа к данным накладываются на объекты базы данных в момент обращения «1С:Предприятия» к базе данных. В клиент-серверном варианте «1С:Предприятия» наложение ограничений выполняется на сервере «1С:Предприятия».
Способ действия ограничений, выбираемый для выполнения каждой операции над данными, определяется назначением этой операции и степенью ответственности ее результатов. В частности, способ «разрешенные» используется при отображении динамических списков и некоторых других интерактивных действиях. Способ «все» используется при выполнении любых операций с прикладными объектами из встроенного языка «1С:Предприятия», в том числе при любых изменениях объектов базы данных. Поэтому, например, могут возникнуть затруднения при построении отбора для метода Выбрать() менеджеров справочников, документов и других с последующим обходом результата в том случае, если на соответствующий объект установлено достаточно сложное ограничение, поскольку не всякое условие в ограничении прав доступа может быть адекватно представлено в виде отбора для метода Выбрать().
В запросах способом действия ограничений доступа к данным можно управлять. Для этого в языке запросов предусмотрено ключевое слово РАЗРЕШЕННЫЕ. Если в запросе не указано РАЗРЕШЕННЫЕ, то ограничения действуют способом «все». Если слово РАЗРЕШЕННЫЕ указано, то выбирается способ «разрешенные».
Важно, что если в запросе не указано ключевое слово РАЗРЕШЕННЫЕ, то все отборы, заданные в этом запросе, не должны противоречить ни одному из ограничений на чтение объектов базы данных, используемых в запросе. При этом если в запросе используются виртуальные таблицы, то соответствующие отборы должны быть наложены и на сами виртуальные таблицы.
Пример:
ВЫБРАТЬ
КонтактнаяИнформацияСрезПервых.Представление
ИЗ РегистрСведений.КонтактнаяИнформация.СрезПоследних(, Тип = &Тип)
КАК КонтактнаяИнформацияСрезПервых
ГДЕ
КонтактнаяИнформацияСрезПервых.Тип = &Тип
При использовании объектной техники не поддерживается получение доступа к данным в режиме РАЗРЕШЕННЫЕ. Предполагается, что объектная техника используется для наиболее ответственных операций над данными, в том числе для их изменения. Для получения при помощи объектной техники всех данных, независимо от установленных ограничений, можно выполнять необходимые действия в привилегированном модуле или от имени пользователя с полными правами. Средств получения только разрешенных данных в объектной технике не предусмотрено.
Механизм наложения ограничений
Любая операция над данными, хранимыми в базе данных, в «1С:Предприятии» в конечном счете приводит к обращению к базе данных с некоторым
запросом на чтение или изменение данных. В процессе исполнения запросов к базе данных внутренние механизмы «1С:Предприятия» выполняют наложение ограничений доступа. При этом:
● Формируется список прав (чтение, добавление, изменение, удаление), список таблиц базы данных и список полей, используемых этим запросом.
● Из всех ролей текущего пользователя выбираются ограничения доступа к данным для всех прав, таблиц и полей, задействованных в запросе. При этом если какая-нибудь роль не содержит ограничений доступа к данным какой-нибудь таблицы или поля, то это значит, что в данной таблице доступны значения требуемых полей из любой записи. Иначе говоря, отсутствие ограничения доступа к данным означает наличие ограничения
ГДЕ Истина.
● Получаются текущие значения всех параметров сеанса и функциональных опций, участвующих в выбранных ограничениях.
Для получения значения параметра сеанса от текущего пользователя не требуется наличие права на получение этого значения. Однако если значение некоторого параметра сеанса не было установлено, то произойдет ошибка и запрос к базе данных выполнен не будет.
На получение функциональных опций оказывает влияние свойство функциональной опции Привилегированный режим при получении .
Если это свойство сброшено, то текущий пользователь должен обладать правами на чтение объекта, в котором хранится функциональная опция.
● Ограничения, полученные из одной роли, объединяются операцией И.
● Ограничения, полученные из разных ролей, объединяются операцией ИЛИ.
● Построенные условия добавляются к SQL-запросам, с которыми «1С:Предприятие» обращается к СУБД. При обращении к данным со стороны условий ограничения доступа проверка прав не выполняется (ни к объектам метаданных, ни к объектам базы данных). Причем механизм добавления условий зависит от выбранного способа действия ограничений «все» или «разрешенные».
Способ «все»
При наложении ограничений способом «все» к SQL-запросам добавляются условия и поля так, чтобы «1С:Предприятие» могло получить информацию о том, были ли в процессе исполнения запроса к базе данных использованы данные, запрещенные для данного пользователя или нет. Если запрещенные данные были использованы, то инициируется аварийное завершение запроса. Наложение ограничений доступа способом «все» схематически представлено на рис. 1:
Способ «разрешенные»
При наложении ограничений способом «разрешенные» к SQL-запросам добавляются такие условия, чтобы запрещенные текущему пользователю записи не оказывали влияния на результат запроса. Иначе говоря, при наложении ограничений в режиме «разрешенные» запрещенные данному пользователю записи считаются отсутствующими,что схематически представлено на рис 3
Другие объекты, связанные с ограничениями доступа к данным
При разработке конфигураций с использованием ограничений доступа к данным могут оказаться полезными такие объекты метаданных, как параметры сеанса, функциональные опции и общие модули с флажком Привилегированный.
Параметры сеанса
Параметры сеанса могут использоваться в ограничениях доступа к данным аналогично тому, как в запросе могут использоваться параметры запроса.
Функциональные опции
Не зависящие от параметров функциональные опции могут использоваться в ограничениях доступа к данным аналогично тому, как в запросе могут использоваться параметры запроса.
Привилегированные общие модули
Если для общего модуля установлен флажок Привилегированный, то исполнение процедур и функций этого модуля приобретает важную специфику:
● В клиент-серверном варианте «1С:Предприятия» привилегированным может быть только тот модуль, который исполняется на сервере.
● Исполнение процедур и функций привилегированного модуля и всего, что из них вызвано, выполняется при выключенной системе ограничения
прав, как к объектам метаданных, так и к данным. Таким образом, из привилегированного модуля может быть выполнена любая операция над
любыми объектами даже в том случае, если текущий пользователь не имеет соответствующих прав.
Привилегированные модули предназначены для начальной установки значений параметров сеанса, используемых в ограничениях доступа к данным.
Еще общие модули могут быть использованы для некоторых целостных действий над данными со стороны пользователя с ограниченными правами.
Например, если в функции пользователя входит ввод и проведение документов, но пользователь не должен иметь доступа к данным, на которые влияет проведение документа, то выполнение операции проведения может быть вынесено в привилегированный модуль. Это позволит пользователю проводить документы без предоставления ему прав на другую информацию (регистры, например).
Привилегированный режим
Имеется возможность программной установки привилегированного режима при работе с данными. Программная установка привилегированного режима
может потребоваться в случае массированных операций с данными информационной базы, и при этом нет смысла проверять права доступа к данным.
Описание привилегированного режима см. здесь.
Использование препроцессора
При редактировании текста ограничения доступа к данным возможно использование инструкций препроцессора. Доступны следующие инструкции:
#ЕСЛИ <Выражение> #ТОГДА
#ИНАЧЕЕСЛИ <Выражение> #ТОГДА
#ИНАЧЕ
#КОНЕЦЕСЛИ
<Выражение> – произвольное логическое выражение на встроенном языке, результат которого имеет тип Булево. Выражение может содержать:
● операции сравнения <, >, <=, >= , =, <>;
● логические операции И, ИЛИ, НЕ;
● параметры сеанса – используется синтаксис &Параметр, где Параметр – имя параметра сеанса.
Если результатом выражения инструкции #ЕСЛИ или #ИНАЧЕЕСЛИ является значение Истина, то в результирующий текст инструкции ограничения доступа помещается текст, расположенный после ключевого слова #ТОГДА. Если же результатом выражения является значение Ложь, то текст, расположенный после ключевого слова #ТОГДА, не помещается в текст инструкции ограничения доступа. Текст, расположенный после инструкции #ИНАЧЕ, будет помещен в результирующий текст ограничения доступа, если ни одно из ранних условий не было выполнено.
ПРИМЕЧАНИЕ. Если текст ограничения доступа к данным содержит инструкции препроцессора, то такое ограничение не проходит проверку синтаксиса при редактировании и не может быть изменено при помощи конструктора.
Пример:
#ЕСЛИ &ТекущийПользователь <> “Климова” #ТОГДА
<текст ограничения доступа>
#КОНЕЦЕСЛИ
Здесь ТекущийПользователь – параметр сеанса типа СправочникСсылка.Пользователи.
Такая конструкция означает, что условие для установки ограничения доступа будет проверяться для всех пользователей из справочника, кроме пользователя Климовой.
Шаблоны текста ограничения доступа
Роль может содержать список шаблонов ограничения доступа, которые описываются на закладке Шаблоны ограничений формы роли. Также шаблоны ограничения доступа можно редактировать в редакторе группового редактирования ограничений доступа и шаблонов .
Каждый шаблон ограничения доступа имеет имя и текст. Имя шаблона подчиняется обычным правилам для имен, принятых в системе «1С:Предприятие».
Текст шаблона содержит часть текста на языке ограничения доступа к данным и может содержать параметры, которые выделяются при помощи символа
“#”.
После символа “#” могут следовать:
● Одно из ключевых слов:
● Параметр, после которого в скобках указывается номер параметра в шаблоне;
● ТекущаяТаблица – обозначает вставку в текст полного имени таблицы, для которой строится ограничение;
● ИмяТекущейТаблицы – обозначает вставку в текст полного имени таблицы (как строковое значение, в кавычках), к которой применяется инструкция, на текущем варианте встроенного языка;
● ИмяТекущегоПраваДоступа – содержит имя права, для которого выполняется текущее ограничение: ЧТЕНИЕ/READ, ДОБАВЛЕНИЕ/INSERT, ИЗМЕНЕНИЕ/
UPDATE, УДАЛЕНИЕ/DELETE;
● имя параметра шаблона – означает вставку в текст ограничения соответствующего параметра шаблона;
● символ “#” – обозначает вставку в текст одного символа “#”.
В выражении ограничения доступа могут содержаться:
● Шаблон ограничения доступа, который указывается в формате
#ИмяШаблона(“Значение параметра шаблона 1”, “Значение параметра шаблона 2”, …). Каждый параметр шаблона заключается в двойные кавычки. При необходимости указания в тексте параметра символа двойной кавычки следует использовать две двойные кавычки.
● Функция СтрСодержит(ГдеИщем, ЧтоИщем). Функция предназначена для поиска вхождения строки ЧтоИщем в строке ГдеИщем. Возвращает Истина в случае, если вхождение обнаружено и Ложь – в противном случае.
● Оператор + для конкатенации строк.
Для удобства редактирования текста шаблона на закладке Шаблоны ограничений в форме роли нужно нажать кнопку Установить текст шаблона. В открывшемся диалоге ввести текст шаблона и нажать кнопку ОК.
Система «1С:Предприятие» выполняет проверку синтаксиса текстов шаблонов, проверку синтаксиса использования шаблонов и макроподстановку текстов шаблонов ограничения доступа роли в текст запроса.
Макроподстановка шаблона заключается:
● в замене вхождений параметров в тексте шаблона на значения параметров из выражения использования шаблона в тексте ограничения;
● в замене выражения использования шаблона в тексте запроса на получившийся текст шаблона.
При вызове конструктора запроса для условия, содержащего шаблоны ограничения доступа, выдается предупреждение о замене всех шаблонов.
Далее приведены примеры шаблонов ограничений:
Общие рекомендации по ограничению прав
Чтобы гибко управлять доступом пользователей к данным в соответствии с функциями при установке ограничений доступа к данным, рекомендуется
придерживаться следующих принципов:
● Нужно выбрать совокупность информации (может быть зависимой от текущего пользователя), для которой целесообразна предварительная подготовка. Выбранная информация должна, с одной стороны, максимально упростить ограничения доступа к данным, а с другой стороны, не должна иметь слишком большой объем. Распределить ее по параметрам сеанса.
● Установить значения параметров сеанса в обработчике УстановкаПараметровСеанса() модуля сеанса.
● Задать ограничения доступа к тем данным, для которых это оправданно (данные являются секретными или наиболее важными для сохранения целостности системы). Необходимо иметь в виду, что установка ограничения доступа может привести к замедлению любого обращения к этим данным. Излишняя сложность ограничений также может привести к замедлению.
● При необходимости обеспечить выполнение некоторого ограниченного количества операций над данными со стороны пользователя, которому полный доступ к этим данным давать нецелесообразно, вынести эти действия в привилегированные модули или явно включать и выключать привилегированный режим в соответствующих местах программного кода.
● Доступ к данным при различных проверках, выполняемых системой при записи объектов, выполняется в привилегированном режиме.
Это позволяет не отключать ограничения в правах на уровне записей для соответствующих полей, если работа конфигурации с этими данными
планируется только в управляемом режиме:
● для справочников при проверке родителя, владельца и уникальности кода;
● для документов, бизнес-процессов и задач при проверке уникальности номера;
● для планов обмена отключена при проверке уникальности кода;
● для планов счетов и планов видов характеристик при проверке родителя и уникальности кода.
При создании запроса ограничения к данным следует помнить о некоторых ограничениях и особенностях:
● Если для объектной таблицы заданы ограничения доступа к данным и в запросе к данным используется объединение с такой таблицей, то в условии соединения (секция запроса ПО) не допускается использование табличной части объекта с заданным ограничением доступа.
● Если в запросе указана таблица, у которой в запросе не используется ни одного поля, то на эту таблицу накладываются все ограничения доступа к данным. Например, запрос ВЫБРАТЬ КОЛИЧЕСТВО(*) ИЗ Справочник.Контрагенты будет исполнен с учетом всех ограничений доступа, заданными для справочника Тест. Ограничения накладываются «по ИЛИ». Это значит, что будут доступны все записи, доступные хотя бы по одному условию. Если для каких-то полей не задано условий, то запрос будет выполнен для всех записей таблицы.
Если в запросе используется таблица верхнего уровня, то ограничения, заданные для колонок вложенных таблиц, не накладываются.
Если в запросе используется вложенная таблица, то накладываются ограничения как для вложенной таблицы, так и для таблицы верхнего уровня.
Например, запрос ВЫБРАТЬ КОЛИЧЕСТВО(*) ИЗ Справочник.Контрагенты.Договора будет исполнен с учетом всех ограничений для справочника Контрагенты, а также с учетом ограничений, относящихся к табличной части Договора.
● Если доступ к полям, необходимым для получения представления ссылочного объекта метаданных, запрещен с помощью ограничений доступа к
данным или доступ к объекту запрещен на уровне прав доступа, то получение представления такого объекта не влияет на ход текущей транзакции.
Конструктор ограничения доступа к данным
Для вызова конструктора в табличном поле Ограничения доступа к данным в колонке Ограничение доступа нужно перейти в режим редактирования и
нажать кнопку выбора, а в открывшейся форме нажать кнопку Конструктор запроса….
На экран выводится форма конструктора:
С его помощью производится формирование условий для установки ограничения доступа к данным.
На закладке Таблицы и поля следует выбрать нужные объекты в списке База данных и перенести их в список Таблицы. Если указано несколько таблиц, то в форме конструктора добавляется закладка Связи.
На закладке Связи формируются условия, которые накладываются на связи между полями таблиц. Для ввода нового условия нужно нажать кнопку Добавить и в колонке Таблица1 выбрать одну из таблиц. В колонке Таблица2 выбрать таблицу, поля которой связаны с полями первой. Ниже списка условий расположены элементы управления, с помощью которых формируется условие связи таблиц.
Если выбран простой тип условия, то в Поле1 и Поле2 выбираются связанные поля указанных таблиц и задается условие сравнения. Если выбраны поля, сравнение которых не производится, то в строке списка условий в колонке Условие связи выводится текст: Неверно заполненное условие.
На закладке Условия, если требуется, нужно указать условия, по которым будет выполняться отбор исходных данных.
По каждому выбранному полю необходимо выбрать вид условия и указать наименование параметра. В качестве параметра допускается использование параметра сеанса. Разрешается указывать несколько условий. В этом случае в колонке Условие табличного поля условий текст условия выводится в несколько строк.
В любой момент создания запроса текст запроса можно просмотреть, нажав кнопку Запрос.
Групповое редактирование ограничений прав доступа и шаблонов
Режим группового редактирования ограничений прав доступа и шаблонов вызывается командой Все ограничения доступа контекстного меню ветки Роли. В открывшейся форме присутствуют две закладки: Ограничения доступа и Шаблоны ограничений.
На закладке Ограничения доступа можно просматривать все введенные ограничения доступа в общем списке (по всем ролям, объектам, правам,комбинациям полей).
Существует возможность добавлять ограничение доступа сразу для нескольких ролей, объектов, прав и комбинаций ролей.
Можно фильтровать список по различным критериям.
Режим группового редактирования позволяет удалять выделенные в списке ограничения.
Существует возможность редактировать выделенные ограничения. При этом можно заменять состав полей и/или ограничение доступа.
Режим группового редактирования позволяет также копировать выделенные ограничения в другие роли.
На закладке Шаблоны ограничений можно видеть все шаблоны ограничения доступа, присутствующие в прикладном решении, при этом из собственно текста шаблона в таблице отображаются только первые 10 строк, которые завершаются символом “…”, если текст шаблона более 10 строк. В окне редактирования шаблона будет отображаться полный текст шаблона.
Существует возможность добавлять шаблон ограничения доступа сразу для нескольких ролей.
Имеется возможность отбирать необходимые шаблоны с помощью набора критериев, а также по значению текущей колонки.
При необходимости имеется возможность выполнить копирование одного или нескольких шаблонов в другие роли.
Название проверки
Серверный код не заключен в инструкцию препроцессора: "#Если Сервер Или ТолстыйКлиентОбычноеПриложение Или ВнешнееСоединение Тогда...".
Английское название проверки
??
Правило анализа кода/метаданных
2. При этом разработка конфигураций, рассчитанных на режим управляемого
приложения, как правило, ведется исходя из того, что в клиент-серверной
архитектуре код следующих модулей компилируется и выполняется только на
сервере
- модуль менеджера;
- модуль объекта;
- модуль сеанса.
В частности, в указанных модулях может встречаться обращение к общим
модулям, доступным только на сервере.
Однако в толстом клиенте, в режиме управляемого приложения,
клиент-сервер, возможны ситуации, когда указанные модули могут начать
компилироваться и выполняться на стороне клиента, в частности:
- если объект (справочник, документ и т.п.) явно создается и
вызывается в клиентском коде; - когда платформа 1С:Предприятие неявно обращается к модулям
менеджеров и модулю сеанса для вызова их обработчиков событий на
клиенте.
Компиляция и выполнение таких модулей на клиенте могут приводить к
ошибкам. По этой причине режим проверки конфигурации для режима толстый
клиент, управляемое приложение, может находить ошибки в указанных
модулях.
Для того чтобы избежать незапланированной компиляции и исполнения
указанных модулей на клиенте, а также чтобы избежать лишних сообщений
режима проверки конфигурации, следует:
- полностью исключить из клиентского контекста код модулей объектов
(наборов записей и т.п.), заключив его в инструкцию препроцессора и
дополнив вызовом исключения, которое предотвращает
несанкционированную попытку использования объекта на клиенте:
#Если Сервер Или ТолстыйКлиентОбычноеПриложение Или ВнешнееСоединение
Тогда
…
#Иначе
ВызватьИсключение НСтр(«ru = ‘Недопустимый вызов объекта на
клиенте.'»);
#КонецЕсли
- полностью исключить из клиентского контекста код модуля сеанса,
заключив его в инструкцию препроцессора (так как параметры сеанса
требуются для работы серверного, а не клиентского кода
конфигурации):
#Если Сервер Или ТолстыйКлиентОбычноеПриложение Или ВнешнееСоединение
Тогда
…
#КонецЕсли
- полностью исключить из клиентского контекста код модулей менеджеров
всех видов объектов метаданных, заключив его в инструкцию
препроцессора:
#Если Сервер Или ТолстыйКлиентОбычноеПриложение Или ВнешнееСоединение
Тогда
…
#КонецЕсли
В последнем случае также будет действовать следующее ограничение: если
представление объектов формируется обработчиками событий модуля
менеджера ОбработкаПолученияПредставления и ОбработкаПолученияПолейПредставления,
то в толстом клиенте, в режиме управляемого приложения, клиент-сервер,
представление будет формироваться по умолчанию, без вызова этих
обработчиков, и тем самым будет отличаться от остальных режимов работы.
(При этом оставшиеся два обработчика модуля
менеджера ОбработкаПолученияДанныхВыбора и ОбработкаПолученияФормы вызываются
всегда только на сервере, поэтому указанное ограничение на них не
распространяется.)
Мета-информация (пожалуйста, заполните если знаете):
- Номер стандарта:
680
- Код проверки:
??my-check-id
- Тип ошибки:
ERROR
SECURITY
PERFORMANCE
WARNING
PORTABILITY
LIBRARY_DEVELOPMENT_AND_USAGE
CODE_STYLE
UI_STYLE
SPELLING
- Критичность:
BLOCKER
CRITICAL
MAJOR
MINOR
TRIVIAL
- Код ошибки АПК:
361
Параметры проверки
- NA
Текст ошибки
Серверный код не заключен в инструкцию препроцессора: "#Если Сервер Или ТолстыйКлиентОбычноеПриложение Или ВнешнееСоединение Тогда...".
Пример некорректного решения
- NA
Описание, почему так делать нельзя
Пример корректного решения
- NA
Дополнительные материалы
- Поддержка толстого клиента, управляемое приложение, клиент-сервер (Раздел обновлен!)