Пост

Ограничения полей, или как обмануть СКД?

Каждое из ограничений полей можно обойти. Рассмотрим варианты обхода и способы обезопасить свой отчет.


Каждый одинэсник знает, что такое СКД. И каждый видел (а может, даже и использовал) эти замечательные галочки ограничений у полей.

Скрин

Ограничивать поля иногда приходится, чтобы не дать пользователям нагрузить базу сложными условиями, увидеть “лишнее” или даже исказить результат запроса (с СКД такое бывает).

Но мало кто знает, что эти ограничения можно обойти. Давайте проведём эксперимент?

Делаем простой отчет. Для теста возьмём демо-базу ERP 2.4 (но конфигурация не важна). И платформу 8.3.16.1030. На разных версиях платформы могут отличаться нюансы, однако, в общем, описанное ниже будет работать везде.

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

Скрин

Пока никаких ограничений у полей делать не будем и просто выведем все поля в отчет. А в отбор добавим Организация.ИНН и выведем его в быстрый доступ:

Скрин

А в ПриКомпоновкеРезультата() добавим код, который будет нам выводить текст выполняемого запроса.

Скрин

Открываем отчет и выполняем. Как видим, в демо-базе есть несколько документов на организации, у которых не указан ИНН.

Скрин

Отбор прекрасно сработал

Глянем выполняемый СКД запрос. СКД любит делать параметры с именем “П” =)

Скрин

Всё работает как надо. А теперь поставим ограничение на использование реквизитов поля “Огранизация” в отборах:

Скрин

В настройках видно, что наш отбор помечен красным крестиком.

Скрин

Не будем его удалять, а просто попробуем открыть отчет в базе. Уже на этом этапе можно заметить, что в быстрых настройках отбор всё равно виден:

Скрин

Но пусть, главное же, что он не сработает. Или же…

Скрин

Как видим, отбор сработал. Может мы что-то перепутали? Давайте откроем здесь же в предприятии наш вариант по кнопке “Изменить вариант отчета”

Скрин

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

Скрин

А что же стало с наши запросом?

Скрин

Действительно, отбор сработал. И наложился на запрос, несмотря на ограничения.

А что если мы ограничим не только реквизиты поля, но и самого его?

Скрин

Выполняем отчет

Скрин

Отбор опять сработал. А что с остальными ограничениями?

Возьмёмся за ограничение выбора. Сначала выведем в отчет ИНН организации. Ну и для наглядности уберем из запроса ПЕРВЫЕ 10.

Скрин

Сделаем вывод реквизитов отдельной колонкой и посмотрим на результат

Скрин

Всё хорошо. Теперь запретим пользователям выбирать реквизиты поля “Организация”:

Скрин

И попробуем выполнить отчет снова:

Скрин

Как видим, ИНН не выводится. Хоть в настройках он и остался:

Скрин

Но есть одна хитрость… Давайте для начала снова снимем ограничения реквизитов у организации.

Скрин

Перейдём в пользовательские поля и добавим новое поле выражение:

Скрин

И выведем его в отчет

Скрин

Проверим результат в базе

Скрин

А теперь снова установим ограничение на выбор реквизитов организации

Скрин

И проверим результат

Скрин

Поле выводится! А что с запросом?

Скрин

Да, поле попало в запрос. А что, если запретить выбор самого поля “Организация”?

Скрин

Формируем отчет:

Скрин

Поле вывелось. Организация пропала, а пользовательское поле всё равно работает. А что в запросе?

Скрин

Мы успешно обошли ограничения. Примерно так же обстоят дела и с ограничением на группировки и сортировки. И даже параметры. А ведь на них часто разработчики завязывают логику отчета.

А если снять Автозаполнение?

Есть возможность в СКД отключить галку “автозаполнение” и в запросе полностью описать разрешенные поля.

На этом примере мы в доступных для отбора полях не указали “Организация”

Скрин

Но это тоже не помогает и отбор сработает:

Скрин

Но, что интересно, запрос такой:

Скрин

Заметьте, отбора в запросе нет. Но есть выборка Организация.ИНН. А это значит, что фильтрация произойдёт не на уровне SQL, а на Сервере Приложений 1С. (интересно, как это скажется на скорости)

Установка ограничений на поля в самой СКД опять же не помогает

Скрин

Но попробуем доработать запрос и убрать у него реквизиты организации из списка доступных к выбору полей. Для этого просто уберём “.*” :

Скрин

Что теперь будет?

Скрин

Отбор всё равно сработал. Но интересно, что в запросе нет выбора ИНН организации. Как же 1С фильтрует записи? На самом деле нужно копнуть глубже, а для этого глянем макет компоновки:

Скрин

Теперь в наборах данных появился набор “ОрганизацияРеквизиты”. А в нём такой запрос

Скрин

СКД усердно старается выполнить условие, которое должно игнорироваться. Какая сила воли!

Остаётся ещё один вариант - вообще убрать поле “Организация” из доступных к выбору. В этом запросе, оно не указано в {} (хоть и указано в основном запросе).

Скрин

И что теперь?

Скрин

Наконец-то! Теперь уж точно пользователи не смогут наложить отбор. Правда и поле вывести… И, конечно, это не решение проблемы. Но эксперимент мы провели)

Ну и зачем нам всё это знать?

Скрин

Теперь мы знаем, что все ограничения полей в СКД можно обойти настройками. Ну и зачем нам это?

Во-первых, для понимания, как работает СКД. Ограничения влияют на пользовательскую доступность, а не на логику отчета. Частично, СКД проверяет и обрезает поля при формировании. Но не всегда, не везде и не совсем =)

Во-вторых, когда вы столкнётесь со странной ситуацией, вы вспомните об этой статье.

Да, в наших примерах мы специально создавали такую ситуацию. Но она может возникнуть (и возникает) и без вашего желания.

Пример из жизни. Жил да был сложный отчет с большим запросом. И пользователи любили в этом отчете выводить реквизиты регистратора. И реквизиты реквизитов регистратора. И делать на них отборы (да ещё и на табличные части). И сильно нагружали этим базу. Аналитики поговорили с пользователями, уточнили все их нужды и разработчик доработал запрос отчета так, чтобы он удовлетворял потребностям пользователей, но при этом меньше нагружал базу. А на поле “Регистратор” наложил ограничения реквизитов. Всё вроде бы хорошо, но в базе осталось множество пользовательских вариантов отчетов, которые содержали отборы типа “Регистратор.Реквизит.Реквизит”. И, несмотря на ограничения в СКД, отчет всё равно нагружал базу, ведь отборы работали.

А есть ещё один интересный способ. Ведь у нас есть возможность сохранить настройки в файл.

Скрин

И загрузить из файла 😉

Скрин

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

А ещё однажды попался такой умный (и упрямый) пользователь, который любил ковыряться в 1С, лазить в структуре файлов и так далее. В общем, хобби такое у человека. И когда разработчики наложили в одном отчете ограничение на отбор по реквизитам, он воспринял это как вызов. Сохранил настройки в файл, отредактировал их в XML и загрузил обратно. Ну и продолжил нагружать базу своими хитровычурными отборами дальше.

Вот так выглядит наш отбор по ИНН в XML:

Скрин

А однажды мы нашли ситуацию, когда пользовательский вариант отчета накладывал значение на скрытый параметр. А от него зависела логика варианта отчета. Так что всякое в жизни случается =)

Хотите ещё один способ нарушить правила?

В режиме предприятия заходим в “Изменить вариант”. Как видите, наложить отбор ни на ИНН ни на Организацию нельзя:

Скрин

Нажимаем волшебную кнопку “Изменить форму”

Скрин

В элементах находим “Доступные поля полей” и переносим на закладку с отборами:

Скрин

Теперь у нас слева таблица с доступными к выбору полями, по центру с доступными к отбору, а справа сам отбор.

Скрин

А сейчас просто мышкой переносим поле Организация.ИНН с самой левой таблицы в самую правую. Как вам результат?)

Скрин

Да, поле с красным крестиком. Но отбор всё равно сработает.

Скрин

И что же теперь делать? Вот мы приблизились к решению. И оно простое:

Скрин

Этот метод хорош и будет спасать нас в большинстве случаев. Если в ПриКомпоновкеРезультата() вы вставите этот метод, то убережёте себя от большинства таких проблем. Просто, не правда ли? Но крайне редко такое делается.

Однако, не все ситуации он обрабатывает. И, к сожалению, он не работает с той ситуацией, которая позволяет пользователю легко нарушать ограничения отборов:

Помните пользовательские поля? Давайте поиграем. Возьмем такой запрос:

Скрин

У нас нет возможности фильтровать ни по организации, ни по её реквизитам. А теперь добавляем новое пользовательское поле (даже в режиме предприятия).

Скрин

И делаем на него отбор

Скрин

И что получится?

Скрин

Вуаля! Мы обошли запреты.

При этом в доступных к отбору полях организации нет.

Скрин

И вишенка на торте. КомпоновщикНастроек.Восстановить() НЕ ПОМОГАЕТ.

В данной ситуации, пользовательское поле не является запрещенным. И при его помощи можно наложить и отборы. Можно наложить отборы и сложнее:

Скрин

Вот такой при этом будет запрос

Скрин

Какие выводы?

Скрин

У СКД нет жёстких ограничений.

Но если вдруг нам очень уж нужно, то:

  • Используйте КомпоновщикНастроек.Восстановить()
  • Снимайте галку “Автозаполнение” (вы ещё ей пользуетесь?)
  • При обновлении отчётов, обрабатывайте пользовательские варианты
  • Ограничивать не только отбор подчиненных, но и выбор Таким образом вы сможете минимизировать вероятность того, что пользователь обойдет ваши запреты.

UPDATE: поддержка 1С ответила следующее:

Описанное в статье поведение СКД является штатным, то есть ограничения полей влияют только на новую настройку отборов пользователя в интерактивном режиме, старые настройки пользователей (в т.ч., загруженные из файла, или программно установленные отборы) будут работать как и ранее.

Посему ожидать какой-то доработки штатной логики ограничений СКД не стоит. Продолжаем самостоятельно выполнять пункты из выводов статьи =)

Авторский пост защищен лицензией CC BY 4.0 .