К статье
Практический материал

Разработка и Конфигурация · 11 мин

Как работает критерий отбора в 1С

Как устроен критерий отбора в 1С: состав, типы данных, запросы к критерию, примеры кода, типичные ошибки и способы проверить результат работы.

Критерий отбора в 1С — это объект метаданных, который объединяет несколько видов документов (и других объектов) по общему реквизиту и позволяет одним действием получить все объекты, где этот реквизит имеет заданное значение. Классический пример — критерий «Взаиморасчеты с контрагентом»: пользователь указывает контрагента и сразу видит все заказы, накладные, счета и акты, где он фигурирует, не открывая каждый журнал по отдельности.

Механизм работает на уровне платформы: разработчик один раз описывает состав критерия в конфигураторе, а платформа сама строит нужные запросы к базе данных. Для пользователя это выглядит как журнал с полем отбора, для программиста — как менеджер КритерииОтбора с методом Найти(). Ниже разберём устройство критерия, настройку в конфигураторе, работу из кода и типичные проблемы производительности.

Как устроен критерий отбора: состав и тип значения

У критерия отбора два ключевых свойства. Первое — Тип: тип данных значения отбора, например СправочникСсылка.Контрагенты или СправочникСсылка.Номенклатура. Это то значение, которое пользователь или код передаёт в отбор. Второе — Состав: перечень реквизитов конкретных объектов метаданных, которые участвуют в критерии. Тип каждого такого реквизита должен содержать тип критерия, иначе платформа не даст включить реквизит в состав.

Например, критерий «Документы по контрагенту» имеет тип «СправочникСсылка.Контрагенты», а в его состав входят реквизиты «Контрагент» документов «ЗаказПокупателя», «РеализацияТоваровУслуг», «ПоступлениеТоваровУслуг», «ПлатежноеПоручение» и так далее. Когда выполняется поиск по контрагенту, платформа фактически выполняет объединённый запрос по всем таблицам документов из состава.

Важно понимать: критерий отбора не хранит данные. Это «виртуальный» объект, который в момент обращения собирает результат из таблиц входящих в состав объектов. Поэтому удаление критерия не удаляет документы, а добавление нового документа в состав не требует перезаписи данных.

Настройка критерия отбора в конфигураторе

Создание критерия выполняется в ветке «Общие» → «Критерии отбора» дерева конфигурации. Порядок действий несложный, но есть нюансы с типами данных.

Порядок действий
  1. 1
    Откройте конфигуратор, ветка Общие → Критерии отбора, добавьте новый критерий и задайте имя, например «ДокументыПоКонтрагенту».
  2. 2
    В свойстве «Тип» укажите тип значения отбора — например, СправочникСсылка.Контрагенты.
  3. 3
    Перейдите на закладку «Данные» (состав) и отметьте флажками реквизиты документов, которые должны участвовать в поиске. Платформа покажет только совместимые по типу реквизиты.
  4. 4
    При необходимости создайте форму списка критерия или добавьте критерий в командный интерфейс подсистемы.
  5. 5
    Обновите конфигурацию базы данных и проверьте отбор на тестовом контрагенте с несколькими документами.

Если нужный реквизит документа не отображается в списке доступных для включения в состав, проверьте его тип: он должен включать тип критерия. Составной тип реквизита (например, «Контрагенты, Организации») допустим, если тип критерия входит в него.

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

Использование критерия отбора из встроенного языка

Программно результат критерия получают через менеджер КритерииОтбора. Метод Найти() возвращает таблицу значений со ссылками на найденные объекты.

bsl
// Поиск всех документов по контрагенту
НайденныеДокументы = КритерииОтбора.ДокументыПоКонтрагенту.Найти(КонтрагентСсылка);

Для Каждого Строка Из НайденныеДокументы Цикл
    Сообщить(Строка.Ссылка);
КонецЦикла;

Метод Найти() принимает значение отбора (ссылку соответствующего типа) и возвращает таблицу значений, в которой минимум есть колонка «Ссылка». Дальше эту таблицу можно обойти, выгрузить в список значений или использовать для заполнения динамического списка.

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

Критерий отбора в запросах и динамических списках

В языке запросов критерий отбора выступает как виртуальная таблица. Обращение выглядит так: КритерийОтбора.ДокументыПоКонтрагенту(&Контрагент), где параметр — значение отбора. Результат можно соединять с таблицами документов, чтобы вытащить дополнительные поля — дату, сумму, ответственного.

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

Такой запрос платформа транслирует в объединение выборок по всем таблицам состава критерия. Чем больше видов документов входит в состав, тем тяжелее итоговый запрос. Если в критерий включено двадцать видов документов, СУБД выполнит объединение двадцати выборок — на больших базах это заметно нагружает сервер.

Производительность и ограничения

Главный фактор скорости — наличие индексов по реквизитам, входящим в состав критерия. Реквизиты шапки документов, по которым строится критерий, обычно индексируются, если у них установлено свойство «Индексировать» или они входят в критерий отбора (платформа может учитывать это при построении индексов). Если отбор работает медленно, первым делом проверьте индексацию реквизитов.

Ещё одно ограничение — критерий отбора работает только по равенству значения. Нельзя задать условия вида «контрагент в группе», «дата больше заданной» или «сумма свыше порога». Для таких сценариев нужны произвольные запросы или динамические списки с отборами.

Критерий отбора или альтернативы: что выбрать

Сравнение вариантов

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

Подходит для типового отбора «все объекты по значению реквизита». Минус: только равенство, нагрузка растёт с числом видов документов.

Динамический список с произвольным запросом

Гибкие условия, любые соединения и отборы. Минус: запрос нужно писать и сопровождать вручную.

Отчёт на СКД

Подходит для аналитики по нескольким объектам с группировками. Минус: не даёт интерактивного журнала «открыть документ» из коробки без настройки.

Общий журнал документов

Простой способ объединить несколько видов документов в одном списке. Минус: отбор только по графам журнала, без единого ключа поиска.

Правило выбора простое: если задача — «показать пользователю все документы по контрагенту/номенклатуре/договору» с возможностью открыть любой из них, критерий отбора — самое экономичное решение. Если нужны сложные условия, агрегация или фильтры по нескольким полям, переходите на динамический список или СКД.

Маршрут решения

Как выбрать действие

Нужен отбор по одному значению реквизита в нескольких видах документовСоздайте критерий отбора и журнал на его основе
Нужны условия «больше/меньше», отбор по нескольким полям или группировкиИспользуйте динамический список с произвольным запросом или СКД
Отбор работает медленно на большой базеПроверьте индексацию реквизитов состава и сократите число видов документов в критерии

Проверка результата и типичные ошибки

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

Контрольные точки

Как проверить результат

Полнота выборки
Норма

Все документы с нужным значением реквизита присутствуют в списке

Тревожный признак

Часть документов отсутствует — реквизит не включён в состав критерия

Отсутствие лишних записей
Норма

Документы с другим значением реквизита не попадают в результат

Тревожный признак

Попадают посторонние объекты — проверьте тип критерия и состав

Скорость отбора
Норма

Список открывается за приемлемое время на рабочем объёме данных

Тревожный признак

Длительное ожидание — нет индексов или слишком широкий состав

Типичные ошибки
01
Реквизит документа не добавлен в состав критерия — документы этого вида не находятся, и разработчик долго ищет причину в коде, хотя проблема в метаданных.
02
Несовпадение типов: тип реквизита не включает тип критерия, поэтому реквизит недоступен для выбора в составе.
03
Ожидание сложных условий от критерия: попытка отобрать «по списку контрагентов» или «по периоду» через критерий обречена — он работает только на равенство одному значению.
04
Включение в состав всех документов конфигурации «на всякий случай» — отбор начинает тормозить на больших базах.
05
Забытое обновление конфигурации базы данных: критерий создан в конфигураторе, но в режиме предприятия недоступен.

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

Если критерий отбора нужен только для одного отчёта, часто выгоднее не создавать объект метаданных, а написать запрос с ОБЪЕДИНИТЬ ВСЕ по нужным таблицам документов — так меньше объектов в конфигурации и проще сопровождение. Критерий оправдан, когда отбор используется в нескольких местах и нужен интерактивный журнал.
ПЗ
Практическое замечание

FAQ: частые вопросы о критериях отбора в 1С

Чем критерий отбора отличается от журнала документов?

Журнал объединяет несколько видов документов в общий список с общими графами (дата, номер, контрагент). Критерий отбора решает другую задачу — находит все объекты по конкретному значению реквизита. При этом на базе критерия можно построить форму списка, похожую на журнал, но с обязательным полем отбора.

Можно ли включить в критерий реквизит табличной части документа?

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

Почему в результате отбора нет части документов?

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

Можно ли отобрать по критерию сразу несколько значений, например список контрагентов?

Нет, метод Найти() и виртуальная таблица критерия принимают одно значение. Для списка значений обойдите его в цикле с вызовом Найти() для каждого элемента или напишите собственный запрос с условием В(&Список) — второй вариант обычно быстрее.

Влияет ли удаление критерия отбора на сами документы?

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

Работает ли критерий отбора в мобильном клиенте и веб-клиенте?

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

Итог

Что важно запомнить

Критерий отбора объединяет реквизиты разных объектов по общему типу и ищет объекты только по равенству заданному значению. Настраивается через состав в конфигураторе, вызывается через КритерииОтбора.<Имя>.Найти() или виртуальную таблицу в запросе. Следите за индексацией реквизитов и не расширяйте состав без необходимости — это главные факторы скорости работы.