Как ограничить поля отбора в динамическом списке и ничего не сломать

06.05.20

Разработка - Механизмы платформы 1С

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

Динамические списки - это один из базовых объектов для разработок на базе 1С. 

Однако, долгое время разработчики не имели возможность запрещать пользователям делать отборы по конкретным полям и их реквизитам. Такое бывает необходимо, чтобы не дать возможность "положить" списки со сложными запросами или с большим количеством данных.

И вот с версии 8.3.10 в платформе появился метод УстановитьОграниченияИспользованияВОтборе()

 
 СП

 

Здесь нас интересует этот пункт:

 

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

Это означает, что метод можно вызывать повторно, настраивая доступность полей в зависимости от каких-то событий. Но нужно понимать нюансы работы.

Обычно метод применяют в одном событии формы - ПриСозданииНаСервере(). Когда платформа ещё не приступила к непосредственному открытию формы и всячески к этому готовится. В такие моменты разработчик отбирает у пользователей возможность фильтрации по каким-то полям. А что если менять состав полей несколько раз?

Приведём такой пример. Есть динамический список с документами. Необходимо запретить пользователям делать фильтры по полям, если в шапке формы пустой параметр "Организация". Возьмём для нашего эксперимента форму журнала документов продажи из демо базы ERP 2.4:

 

Для этого добавим форму в расширение:

Подключимся к обработчику изменения организации:

 

И вставим такой простой код:


&НаСервере
&После("УстановитьОтборПоОрганизации")
Процедура ЖурналДокументовПродажи_УстановитьОтборПоОрганизации()
	
	ЗапрещенныеВОтбореПоля = Новый Массив;
	Если НЕ ЗначениеЗаполнено(Организация) Тогда
		ЗапрещенныеВОтбореПоля.Добавить("Подразделение");
	КонецЕсли;
	
	СписокДокументыПродажи.УстановитьОграниченияИспользованияВОтборе(ЗапрещенныеВОтбореПоля);
	
	ОтключитьНедоступныеОтборы(СписокДокументыПродажи.КомпоновщикНастроек.ПользовательскиеНастройки.Элементы);
	
КонецПроцедуры

 

Обновим базу и откроем форму в режиме предприятия. Сразу видим, что в контекстном меню по полю "Подразделение" нет возможности поиска:

 

Расширенный поиск не позволяет выбирать подразделение:

 

Так же отбор недоступен и в форме настройки списка:

 

А теперь заполним организацию:

 

И появилась возможность фильтровать в расширенном поиске:

 

Ну и настройка динамического списка заработала:

 

А значит теперь мы можем наложить отбор на подразделение. Давайте так и сделаем.

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

 

Установим отбор по подразделению "Дирекция" при помощи Ctrl+Alt+F

 

Всё хорошо. Но что будет, если мы сейчас очистим организацию в шапке формы, тем самым запретив отбирать по подразделению?

 

Странно, да? Отбор отключился. Но надпись осталась. Да, её не трудно закрыть крестиком вручную, но пользователю будет непонятно, почему показан отбор, который не работает.

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

Ну хорошо, допустим мы свыклись с тем, что надпись не обновляется и отключили её. Но что с отбором через "Настроить список" ?

Для начала снова выберем организацию в шапке формы и установим отбор по подразделению:

 

Результат такой:

 

Хорошо, а теперь очистим организацию в шапке:

 

Мы установили ограничение на отбор, но существующий при этом не сбросился. А в настройке списка наш отбор помечен красным и более недоступен:

Как же так? Понять это поможет другая статья, в которой рассказывается принцип того, как СКД (на которой и базируются динамические списки) работает с ограничениями полей:
Ограничения полей, или как обмануть СКД?.
Прочитав её, станет понятно, что ограничения полей в отборах полноценно влияют только на пользовательскую доступность полей, но не на логику выборки данных. То есть, пользовательские настройки обходят ограничения полей.

Интересно, что решение, которое было предложено в статье, в данной ситуации не работает. Если использовать КомпоновщикНастроек.Восстановить(), то пользовательские отборы всё равно остаются на месте.

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

 
Вот такой пример кода на нашем расширении. 

 

Теперь когда пользователь очищает поле "Организация", то и наш "неправильный" отбор отключается.

 

Можно заметить, что при этом поле остаётся. И самое интересное, что если пользователь вручную нажмёт его использование, то и, несмотря на ограничения отборов, фильтрация применится:

 

Но что же делать? Придётся не отключать использование отбора, а просто удалять его.

 
 Подправим наш код в расширении

 

Теперь при очистке организации, так же удаляются и "запрещенные" отборы:

 

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

Хорошо, мы разобрались с ограничениями отборов в динамическом списке. Но как обстоят дела с другими ограничениями? Добавим запреты на группировку и сортировку:


&НаСервере
&После("УстановитьОтборПоОрганизации")
Процедура ЖурналДокументовПродажи_УстановитьОтборПоОрганизации()
	
	ЗапрещенныеПоля = Новый Массив;
	Если НЕ ЗначениеЗаполнено(Организация) Тогда
		ЗапрещенныеПоля.Добавить("Подразделение");
	КонецЕсли;
	
	СписокДокументыПродажи.УстановитьОграниченияИспользованияВОтборе(ЗапрещенныеПоля);
	СписокДокументыПродажи.УстановитьОграниченияИспользованияВГруппировке(ЗапрещенныеПоля);
	СписокДокументыПродажи.УстановитьОграниченияИспользованияВПорядке(ЗапрещенныеПоля);
	
	ОтключитьНедоступныеОтборы(СписокДокументыПродажи.КомпоновщикНастроек.ПользовательскиеНастройки.Элементы);
	
КонецПроцедуры

 

Открываем форму с пустой организацией и видим, что подразделения нет в доступных к группировке полей. Всё хорошо. 

 

Теперь выберем организацию и добавим группировку:

 

Всё хорошо применилось:

 

А теперь очистим организацию. После очистки, наш код запрещает использование поля Подразделение в группировках.

И вот мы видим такую ошибку:

 

На группировку 1С поругалась. И форма теперь показывает пустой список:

 

То же самое и с ограничением по сортировке.

Выходит, что платформа позволяет блокировать такие действия. Но с отборами это не работает. Хорошо, что мы написали свой метод по обработке этого?

 

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

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

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

 

А напоследок, давайте вспомним один из хитрых методов обхода ограничений по отборам из статьи Ограничения полей, или как обмануть СКД? .

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

&НаСервере
&После("УстановитьОтборПоОрганизации")
Процедура ЖурналДокументовПродажи_УстановитьОтборПоОрганизации()
	
	ЗапрещенныеПоля = Новый Массив;
	Если НЕ ЗначениеЗаполнено(Организация) Тогда
		ЗапрещенныеПоля.Добавить("Сумма");
		ЗапрещенныеПоля.Добавить("СуммаДокумента");
	КонецЕсли;
	
	СписокДокументыПродажи.УстановитьОграниченияИспользованияВОтборе(ЗапрещенныеПоля);
	
	ОтключитьНедоступныеОтборы(СписокДокументыПродажи.КомпоновщикНастроек.ПользовательскиеНастройки.Элементы);
	
КонецПроцедуры

 

 

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

 

А теперь нажмём "Ещё" -> "Изменить форму"

 

И перенесем доступные к сортировке поля в группу с отборами:

 

Вуаля!

Организация у нас пустая, но поле Сумма теперь доступно. И мы можем сделать своё грязное дело - перенести поле в отбор:

 

Фильтр применился. Несмотря на ограничения. 

 

 

Да, этот способ обхода замудрён, но работает. И к сожалению, события по изменению отборов в 1С нет...

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

 

Выводы:

Ограничения отборов в динамическом списке автоматически обрабатываются недостаточно, поэтому:

1. Дополнительно программно обходите настройки

а) при установки ограничений

б) при загрузке пользовательских настроек

 
 Пример кода из статьи

 

2. Если запрещаете отборы, то запрещайте и группировку\сортировку.

3. Если планируете включать\отключать ограничения и у вас платформа меньше 8.3.16, то отключите отображения поля состояния просмотра, чтобы оно не вводило пользователя в заблуждение.

 

Понравилась статья?

Подайте знак автору =) Поставьте плюс, оставляйте комментарий и переходите к другим публикациям:


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

Сортируем ДанныеФормыДерево на клиенте

"Меньше копипаста!", или как Вася универсальную процедуру писал

Динамический список СКД УстановитьОграниченияИспользованияВОтборе платформа разработка обход

См. также

Поинтегрируем: сервисы интеграции – новый стандарт или просто коннектор?

Обмен между базами 1C Администрирование СУБД Механизмы платформы 1С Платформа 1С v8.3 Бесплатно (free)

В платформе 8.3.17 появился замечательный механизм «Сервисы интеграции». Многие считают, что это просто коннектор 1С:Шины. Так ли это?

11.03.2024    4538    dsdred    53    

72

Как готовить и есть массивы

Механизмы платформы 1С Платформа 1С v8.3 Бесплатно (free)

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

24.01.2024    5295    YA_418728146    25    

63

Планы обмена VS История данных

Обмен между базами 1C Механизмы платформы 1С Платформа 1С v8.3 Бесплатно (free)

Вы все еще регистрируете изменения только на Планах обмена и Регистрах сведений?

11.12.2023    6410    dsdred    36    

112

1С-ная магия

Механизмы платформы 1С Бесплатно (free)

Язык программирования 1С содержит много нюансов и особенностей, которые могут приводить к неожиданным для разработчика результатам. Сталкиваясь с ними, программист начинает лучше понимать логику платформы, а значит, быстрее выявлять ошибки и видеть потенциальные узкие места своего кода там, где позже можно было бы ещё долго медитировать с отладчиком в поисках источника проблемы. Мы рассмотрим разные примеры поведения кода 1С. Разберём результаты выполнения и ответим на вопросы «Почему?», «Как же так?» и «Зачем нам это знать?». 

06.10.2023    18475    SeiOkami    46    

118

Дефрагментация и реиндексация после перехода на платформу 8.3.22

Механизмы платформы 1С Платформа 1С v8.3 Бесплатно (free)

Начиная с версии платформы 8.3.22 1С снимает стандартные блокировки БД на уровне страниц. Делаем рабочий скрипт, как раньше.

14.09.2023    12089    human_new    27    

74

Валидация JSON через XDTO (включая массивы)

WEB-интеграция Универсальные функции Механизмы платформы 1С Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

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

28.08.2023    8824    YA_418728146    6    

141

Внешние компоненты Native API на языке Rust - Просто!

Механизмы платформы 1С Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Внешние компоненты для 1С можно разработывать очень просто, пользуясь всеми преимуществами языка Rust - от безопасности и кроссплатформенности до удобного менеджера библиотек.

20.08.2023    6279    sebekerga    54    

94

Все скопируем и вставим! (Буфер обмена в 1С 8.3.24)

Механизмы платформы 1С Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Рассмотрим новую возможность 8.3.24 и как её можно эффективно использовать

27.06.2023    15986    SeiOkami    31    

103
Комментарии
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. timeforlive 15 08.05.20 09:11 Сейчас в теме
Познавательно. Спасибо, автор.
Bob_Dobr; fredly_nightly; +2 Ответить
2. kaiman_fedor_yandex 61 09.05.20 11:56 Сейчас в теме
3. 7504010 14.05.20 08:44 Сейчас в теме
4. KORTEZ 14.07.22 10:22 Сейчас в теме
5. fatman78 17 27.07.23 08:58 Сейчас в теме
Скоро переписывать, когда режим совместимости в типовых поднимется выше 8.3.18 Источник: , т.к. метод УстановитьОграниченияИспользованияВОтборе() и аналогичные - 1С признан устаревшим...
6. Rasdag 159 08.03.24 18:05 Сейчас в теме
Как запретить пользователю менять отбор который ему до этого установили в самой программе?
Оставьте свое сообщение