Критерии отбора

24.09.15

Разработка - Математика и алгоритмы

Статья посвящена объекту конфигурации - критерий отбора. Поговорим о сущности этого объекта и о методах работы с ним.

В составе метаданных 1С:Предприятия 8 существует объект Критерий отбора. 

Этот объект, в отличие от большинства прикладных объектов конфигурации, не описывает каких-либо самостоятельных данных, которые будут храниться в информационной базе 1С:Предприятия. Критерий отбора предназначен для того, чтобы описать условия отбора по некоторым объектам. Например, можно указать, что критерий отбора строится по типу данных СправочникСсылка.Номенклатура, и в этот критерий входят документы "ПоступлениеТоваровУслуг" и "РеализацияТоваровУслуг". Конечно, все отборы мы можем делать с помощью запроса.

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

Критерий отбора является прикладным объектом, для него, в частности, можно создать форму, которая будет отображаться в пользовательском режиме. Однако находится он в ветке "Общие" из-за того, что имеет узкоспециализированное назначение. Особенностью Критерия отбора является то, что он не входит в глобальный командный интерфейс.


     

Рассмотрим особенности критерия отбора на примере. Создадим новый критерий отбора "Документы с номенклатурой". Настроим закладки "Данные" и "Состав". На закладке "Данные" указывается тот тип данных, по которому будет осуществляться отбор. Причем тип данных может быть составным. Итак, выберем тип данных - СправочникСсылка.Номенклатура. На закладке состав мы выбираем объекты, которые будут являться результатом выполнения нашего отбора. Система предлагает нам отметить флажками интересующие нас объекты из списка, в который она включает все объекты, содержащие ссылку на справочник "Номенклатура". На закладке формы мы можем для критерия отбора указать ФормуСписка, которая будет содержать динамический список объектов, удовлетворяющих нашему критерию. Кроме того, на закладке Права мы можем настроить "Просмотр" для определенных ролей. Следует отметить, что в пользовательском интерфейсе существует возможность просмотра результата отбора, т.е. ФормыСписка критерия отбора. В нашем случае это будет форма справочника "Номенклатура", но, чтобы это работало, необходимо перейти в командный интерфейс ФормыЭлемента справочника "Номенклатура" и поставить флаг в колонке "Видимость" напротив "Документы с номенклатурой (Объект.Ссылка).


     

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

Запрос.Текст = 
		"ВЫБРАТЬ
		|	ДокументыСНоменклатурой.Ссылка
		|ИЗ
		|	КритерийОтбора.ДокументыСНоменклатурой(&Номенклатура) КАК ДокументыСНоменклатурой";
	
	Запрос.УстановитьПараметр("Номенклатура", Номенклатура);
	
	РезультатЗапроса = Запрос.Выполнить();

Мы получим документы, в которых содержится интересующая нас номенклатура.

Также следует отметить, что, несмотря на то, что при включении в конфигурацию критерия отбора система не создает никаких таблиц, однако для оптимизации поиска создается индекс по каждому реквизиту, который указан в составе критериев отбора. Индексы будут использоваться для оптимизации получения выборки при использовании критерия отбора. Таким образом, при описании критерия отбора нужно учитывать, что система будет тратить дополнительные ресурсы на поддержание необходимых индексов. Кстати, процесс "заполнения индекса поиска" можно увидеть, если мы просто переименуем созданный ранее критерий отбора. Сам процесс длится около минуты. А далее система выдает сообщение "Код модулей содержит возможные использования ссылки на изменяемый объект. Продолжить операцию переименования?" И если мы соглашаемся, то выдает нам ссылки на код, где встречаются упоминания нашего критерия отбора. Причем рядом с каждой ссылкой появляется команда "заменить", при нажатии на которую автоматически происходит замена старого наименования критерия отбора на новое.

Каким же образом система получает искомый результат? Дело в том, что она формирует запрос для поиска объектов, которые включают искомое значение, и формирует выборку, состоящую из найденных ссылок на объекты. Формируемый запрос представляет собой объединение запросов по каждой таблице, в которой нужно осуществить поиск. Запросы формируются только к тем данным (таблицам), из числа описанных в критерии отбора, у которых в реквизите может быть значение того типа, значение которого в данный момент ищется. Например, критерий отбора включает ссылки на справочник физических лиц и справочник организаций, а в конкретном реквизите конкретного документа может быть ссылка только на справочник физических лиц. Тогда запрос по этому документу будет выполняться, только если в данный момент поиск выполняется по физическому лицу. Важно учитывать, что критерий отбора всегда выбирает все искомые данные. Ни в списке, ни в других режимах не поддерживается динамическая выборка, так как информация выбирается путем объединения данных из разных таблиц. Формируемый для критерия отбора индекс позволяет сделать это достаточно быстро, но если данных в выборке окажется очень много, то выборка не будет формироваться эффективно. Поэтому целесообразно создавать критерии отбора по данным, имеющим большой разброс значений, чтобы выборки получались не очень большие.  В противном случае теряется смысл такого отбора и снижается его эффективность.

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

     Поговорим о программной работе с критерием отбора. В синтакс-помощнике в ветке "Прикладные объекты" находится ветка "Критерии отбора". Мы видим, что количество типов данных здесь не очень большое. Во-первых, это менеджер критериев отбора - КритерииОтбораМенеджер (FilterCriteriaManager). Это свойство глобального контекста, которое позволяет через точку обратиться к конкретному критерию отбора. Далее мы получаем КритерийОтбораМенеджер.<Имя критерия> (FilterCriterionManager.<Имя критерия>), у которого есть два метода - Найти(<ЗначениеПоиска>) и ПолучитьФорму(<Форма>, <Владелец>, <КлючУникальности>). И еще один тип данных - КритерийОтбораСписок.<Имя критерия> (FilterCriterionList.<Имя критерия>). Он предназначен для управления списком отобранных документов и/или элементов справочников, отображаемых в табличном поле (списком критерия отбора). Как видим, методов для програмной работы не очень много, поэтому гораздо удобнее работать с критерием отбора при помощи запроса.
     Рассмотрим на примере, как отобразить результат работы критерия отбора в форме. Для этого можно создать обработку.

Итак, создаем обработку и управляемую форму для неё. У формы будет два реквизита. Это "Номенклатура" - СправочникСсылка.Номенклатуры и "Список", тип которого - "ДинамическийСписок". В свойствах реквизита "Список" заполним "ОсновнаяТаблица" значением - "КритерийОтбора.ДокументыСНоменклатурой". Перетаскиваем оба реквизита на форму. Кроме того, нам необходимо установить параметр "Значение" для нашего динамического списка. У динамического списка есть свойство "Параметры", тип значения которого: ЗначенияПараметровДанныхКомпоновкиДанных. У которого в свою очередь есть метод: УстановитьЗначениеПараметра(<Параметр>, <Значение>). Итак, в модуле формы у нас будет следующий код:

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
	Список.Параметры.УстановитьЗначениеПараметра("Значение",Номенклатура);
КонецПроцедуры

&НаКлиенте
Процедура НоменклатураПриИзменении(Элемент)
	Список.Параметры.УстановитьЗначениеПараметра("Значение",Номенклатура);
КонецПроцедуры

Сохраняем обработку и запускаем в пользовательском режиме.

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

 &НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
	Список.Параметры.УстановитьЗначениеПараметра("Значение",Номенклатура);
КонецПроцедуры

&НаКлиенте
Процедура НоменклатураПриИзменении(Элемент)
	Список.Параметры.УстановитьЗначениеПараметра("Значение",Номенклатура);
КонецПроцедуры

&НаКлиенте
Процедура ОткрытьФ(Команда)
	ОткрытьФорму("КритерийОтбора.ДокументыПоДоговоруКонтрагента.ФормаСписка");
КонецПроцедуры

Сохраняем нашу обработку, в пользовательском режиме нажимаем на кнопку "ОткрытьФ", наша ФормаСписка открывается, но система при этом выдает ошибку. Дело в том, что система не может понять, по какому объекту ей нужно сделать отбор. Нам необходимо заполнить параметр Значение нашего динамического списка. В принципе, мы можем сделать это интерактивно. Для этого перейдем в ФормуСписка нашего критерия отбора, раскроем ветку "Список", найдем там "Параметры" и перетащим их на нашу ФормуСписка критерия отбора. Теперь в пользовательском режиме мы можем поставить флажок перед параметром "Значение" в истину, ну и, собственно, заполнить и сам параметр "Значение". Но лучше это сделать программно при открытии ФормыСписка критерия отбора. Программную установку мы будем делать в процедуре "ПриСозданииНаСервере()". Если мы поставим точку останова в этой процедуре, то при отладке мы увидим: в параметрах нашего динамического списка есть коллекция "Элементы", и у элемента "Использование" стоит значение "Ложь". Чтобы установить его в истину, можно использовать следующий код, поскольку "Элементы" - это коллекция значений:

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
	Список.Параметры.Элементы[0].Использование = Истина;
КонецПроцедуры

     Мы можем также использовать обращение по имени параметра. Для этого мы можем использовать метод "Найти()":

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
	Список.Параметры.Элементы.Найти("Значение").Использование = Истина;
КонецПроцедуры

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

 

&НаКлиенте
Процедура ОткрытьФ(Команда)
	ОткрытьФорму("КритерийОтбора.ДокументыСНоменклатурой.ФормаСписка", новый Структура("Номенклатура", Номенклатура);
КонецПроцедуры

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

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
	Список.Параметры.Элементы.Найти("Значение").Использование = Истина;
	Список.Параметры.Элементы.Найти("Значение").Значение = Параметры.Номенклатура;
КонецПроцедуры

     Далее запускаем нашу обработку в пользовательском режиме, заполняем реквизит "Номенклатура" и нажимаем кнопку "ОткрытьФ". В результате откроется ФормаСписка критерия отбора с переданным значением "Номенклатуры" из формы вызывающей, а также сформируется результат отбора.

     На этом заканчиваем, надеюсь, материал будет полезен для понимания сути объекта "Критерий отбора". Всем пока и удачи)

Критерии отбора.

См. также

Математика и алгоритмы Программист Платформа 1C v8.2 Конфигурации 1cv8 Россия Абонемент ($m)

На написание данной работы меня вдохновила работа @glassman «Переход на ClickHouse для анализа метрик». Автор анализирует большой объем данных, много миллионов строк, и убедительно доказывает, что ClickHouse справляется лучше PostgreSQL. Я же покажу как можно сократить объем данных в 49.9 раз при этом: 1. Сохранить значения локальных экстремумов 2. Отклонения от реальных значений имеют наперед заданную допустимую погрешность.

1 стартмани

30.01.2024    2316    stopa85    12    

34

Математика и алгоритмы Бесплатно (free)

Разработка алгоритма, построенного на модели симплекс-метода, для нахождения оптимального раскроя.

19.10.2023    5699    user1959478    50    

35

Математика и алгоритмы Разное Платформа 1С v8.3 Конфигурации 1cv8 Россия Абонемент ($m)

Расширение (+ обработка) представляют собою математический тренажер. Ваш ребенок сможет проверить свои знание на математические вычисление до 100.

2 стартмани

29.09.2023    2251    maksa2005    8    

24

Математика и алгоритмы Инструментарий разработчика Программист Платформа 1С v8.3 Мобильная платформа Россия Абонемент ($m)

Что ж... лучше поздно, чем никогда. Подсистема 1С для работы с регулярными выражениями: разбор выражения, проверка на соответствие шаблону, поиск вхождений в тексте.

1 стартмани

09.06.2023    8938    7    SpaceOfMyHead    17    

60

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

Три задачи - три идеи - три решения. Мало кода, много смысла. Мини-статья.

03.04.2023    3526    RustIG    7    

25

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

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

23.11.2022    2612    gzharkoj    14    

24

Математика и алгоритмы Программист Платформа 1С v8.3 Россия Абонемент ($m)

Обычно под распределением понимают определение сумм пропорционально коэффициентам. Предлагаю включить сюда также распределение по порядку (FIFO, LIFO) и повысить уровень размерности до 2-х. 1-ое означает, что распределение может быть не только пропорциональным, но и по порядку, а 2-ое - это вариант реализации матричного распределения: по строкам и столбцам. Возможно вас заинтересует также необычное решение этой задачи через создание DSL на базе реализации текучего интерфейса

1 стартмани

21.03.2022    8384    7    kalyaka    11    

44
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. gradi 5 30.09.15 16:54 Сейчас в теме
Спасибо за подробный разбор темы.
2. DrAku1a 1731 01.10.15 03:53 Сейчас в теме
А далее система выдает сообщение "Код модулей содержит возможные использования ссылки на изменяемый объект. Продолжить операцию переименования?" И если мы соглашаемся, то выдает нам ссылки на код, где встречаются упоминания нашего критерия отбора. Причем рядом с каждой ссылкой появляется команда "заменить", при нажатии на которую автоматически происходит замена старого наименования критерия отбора на новое.

Это стандартное поведение новой платформы (8.3) при переименовании объектов конфигурации (Справочники, Документы, Регистры). Прямого отношения к критериям отбора не имеет.
neo-ti; k268kk; alur; E-rsh-p; pavlo; Бывалый77; echo77; Danil.Potapov; frkbvfnjh; Sardukar; +10 Ответить
3. Sardukar 58 18.01.17 03:41 Сейчас в теме
В подготовительных материалах к "1С Профессионал" говорится - "В управляемых формах с реквизитом типа "динамический список" правило отбора настраивается через настройки списка в режимах Конфигуратор и 1С:Предприятие. Поля реквизитов табличных частей доступны в правилах отбора динамических списков без необходимости создания произвольного запроса". Я к тому, что может быть более подходящим для демонстрации критериев отбора мог быть пример на обычной форме, а не управляемой. При всем уважении к автору.
4. Поручик 4683 10.03.17 21:18 Сейчас в теме
А недостатком (большим) критерия отбора является то, что в запросе ему невозможно передать список или массив ссылок для построения выборки. А иногда надо. Приходится извращаться. Несколько раз сталкивался.
chng; Serg243; klinval; Thalt; SagittariusA; Manticor; Yashazz; alur; +8 Ответить
5. echo77 1865 11.03.17 13:23 Сейчас в теме
(4) В итоге, как вы решили эту задачу? Можете поделиться?
Я решал подобную задачу: переписывал форму структуры подчиненности на СКД - запрос из кучи объединений писал сам
6. Поручик 4683 11.03.17 20:33 Сейчас в теме
(5) Вы никому не говорите. Запрос к критерию отбора в цикле. Одно из творчеств буду переписывать, уж очень тормозно.
krestyaninov; +1 Ответить
7. pavlo 23.03.17 10:14 Сейчас в теме
(6) Ну к сожалению механизм хороший, но не имение возможности передать список часто просто убивает пользу. В итоге и остается имхо только или не слабый свой запрос из объединений или цикл :(
10. German_Tagil 43 03.10.17 13:48 Сейчас в теме
(6) А можно поподробнее?


Запрос к критерию отбора в цикле.




Сделал как мог - в ЗаказеПоставщику в Форме списка


Процедура СписокПриАктивизацииСтроки(Элемент)
    
        ПараметрОтборПоЗначению=эТАФОРМА.Отбор.Номенклатура.Значение;
        
    Если типЗнч(ПараметрОтборПоЗначению)= тип ("Строка") Тогда

        

        

               //{{КОНСТРУКТОР_ЗАПРОСА_С_ОБРАБОТКОЙ_РЕЗУЛЬТАТА
    // Данный фрагмент построен конструктором.
    // При повторном использовании конструктора, внесенные вручную изменения будут утеряны!!!

    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ
        |    Номенклатура.Наименование,
        |    Номенклатура.Ссылка,
        |    Номенклатура.НаименованиеПолное
        |ИЗ
        |    Справочник.Номенклатура КАК Номенклатура
        |ГДЕ
        |    Номенклатура.НаименованиеПолное ПОДОБНО   &НаименованиеПолное   ";

    Запрос.УстановитьПараметр("НаименованиеПолное", "%"+ ПараметрОтборПоЗначению + "%");

    Результат = Запрос.Выполнить();

    ВыборкаДетальныеЗаписи = Результат.Выбрать();

    Номенклатура = Новый СписокЗначений;
    
    
    Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
        Номенклатура.Добавить(ВыборкаДетальныеЗаписи.ссылка);
        сообщить("ВыборкаДетальныеЗаписи " + ВыборкаДетальныеЗаписи.ссылка);
        // Вставить обработку выборки ВыборкаДетальныеЗаписи
    КонецЦикла;
    

    
    ЭтаФорма.Отбор.Номенклатура.ВидСравнения = ВидСравнения.ВСписке;

    ЭтаФорма.Отбор.Номенклатура.Значение = Номенклатура;
    ЭтаФорма.Отбор.Номенклатура.Использование=Истина;
    
    //}}КОНСТРУКТОР_ЗАПРОСА_С_ОБРАБОТКОЙ_РЕЗУЛЬТАТА

        
        
КонецЕсли; 
    
        
        
        
        
    // Вставить содержимое обработчика.
КонецПроцедуры
Показать
8. German_Tagil 43 28.08.17 10:00 Сейчас в теме
Вопрос - как передать критерий обора из документа к примеру "Заказ поставщику" отбор по значению в текущей колонке
в отбор списка документов
критерий отбора в списке по номенклатуре доделан.
хотелось бы сразу отбор из документа по списку делать
9. German_Tagil 43 28.08.17 13:51 Сейчас в теме
в общем так
не могу понять как проверить отбор по товарам - те была ли нажата кнопочка


а так напрашивается
ДокументСписок.Отбор.Номенклатура.Значение = ДанныеСтроки.Номенклатура;
ДокументСписок.Отбор.Номенклатура.Использование = Истина;
ДокументСписок.Обновить();
11. dj_tol 104 29.03.18 10:26 Сейчас в теме
А можно как нибудь со списком поработать чет я не могу ни как сообразить. Есть запрос который перебирает последние поступления по товару, так вот в этом запросе как сделать выборку по подчиненным документам.

ВЫБРАТЬ
	Закупки.ИсточникГФУНоменклатуры КАК ИсточникГФУНоменклатуры,
	Закупки.Регистратор КАК Регистратор,
	СУММА(ВременнаяТаблицаТоваров.ВНаличииОстаток) КАК ВНаличииОстаток,
	СУММА(ВЫРАЗИТЬ(Закупки.Сумма / Закупки.Количество КАК ЧИСЛО(15, 2))) КАК Цена,
	СвязанныеДокументы.Ссылка КАК СвязанныеДокументы
ИЗ
	РегистрНакопления.Закупки КАК Закупки
		ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВременнаяТаблицаПоследних КАК ВременнаяТаблицаПоследних
		ПО (ВременнаяТаблицаПоследних.Ссылка = Закупки.Регистратор)
		ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВременнаяТаблицаТоваров КАК ВременнаяТаблицаТоваров
		ПО (ВременнаяТаблицаТоваров.Номенклатура.Ссылка = Закупки.ИсточникГФУНоменклатуры)
		ВНУТРЕННЕЕ СОЕДИНЕНИЕ КритерийОтбора.СвязанныеДокументы() КАК СвязанныеДокументы
		ПО Закупки.Регистратор.Ссылка = СвязанныеДокументы.Ссылка

СГРУППИРОВАТЬ ПО
	Закупки.ИсточникГФУНоменклатуры,
	Закупки.Регистратор,
	СвязанныеДокументы.Ссылка
Показать
12. СергейК 51 24.06.18 17:46 Сейчас в теме
(11) Подскажите, не получилось вставить КритерийОтбора в СОЕДИНЕНИЕ ?
13. Stanislav1993 13.03.19 09:03 Сейчас в теме
Крутая статья! Спасибо, добрый человек! =)
Оставьте свое сообщение