Как в запросе 1С выбрать документы определенного типа из критерия отбора?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

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

Постановка задачи и анализ ситуации

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


ВЫБРАТЬ
    СвязанныеДокументы.Ссылка КАК Ссылка
ИЗ
    КритерийОтбора.СвязанныеДокументы(&Значение1) КАК СвязанныеДокументы
ГДЕ
    СвязанныеДокументы.Ссылка.Проведен

Этот запрос вернет нам все проведенные документы, связанные с параметром &Значение1. Если в системе настроено много связей, список может быть огромным. Наша цель — оставить в выборке только документы определенного вида, например, Документ.РезервированиеТоваров.

Разберем типичную ошибку новичка

Часто разработчики пытаются применить проверку типа прямо в списке выбора (секция ВЫБРАТЬ). Проанализируем, к чему это приводит:


ВЫБРАТЬ
    СвязанныеДокументы.Ссылка ССЫЛКА Документ.РезервированиеТоваров КАК ЭтоРезервирование
ИЗ
    КритерийОтбора.СвязанныеДокументы(&Значение1) КАК СвязанныеДокументы

В данном случае оператор ССЫЛКА вернет логическое значение (Булево): Истина, если документ является резервированием, и Ложь в противном случае. Сама ссылка на документ при этом не фильтруется, и мы получаем список из "Да" и "Нет", что не решает нашу задачу получения конкретного объекта.

Правильное использование оператора ССЫЛКА в секции ГДЕ

Для того чтобы ограничить выборку на уровне СУБД и получить только нужные нам документы, необходимо перенести условие проверки типа в секцию ГДЕ. Выясним причину, почему это важно: платформа 1С транслирует такой запрос в SQL-код, который эффективно отсекает ненужные таблицы еще на этапе выполнения запроса к базе данных.

Рассмотрим правильный пример кода:


ВЫБРАТЬ
    СвязанныеДокументы.Ссылка КАК Ссылка
ИЗ
    КритерийОтбора.СвязанныеДокументы(&Значение1) КАК СвязанныеДокументы
ГДЕ
    СвязанныеДокументы.Ссылка ССЫЛКА Документ.РезервированиеТоваров
    И СвязанныеДокументы.Ссылка.Проведен

Здесь мы четко указываем системе: "Выбери только те ссылки, тип которых соответствует документу Резервирование товаров". Это самый быстрый и правильный способ фильтрации по типу в языке запросов 1С.

Как получить данные конкретного типа через ВЫРАЗИТЬ

После того как мы отфильтровали документы, нам часто нужно получить их специфические реквизиты. Например, у документа РезервированиеТоваров есть реквизит Склад, которого нет у других связанных документов. Если мы просто напишем Ссылка.Склад, система может выполнить неоптимальное соединение со всеми таблицами. Посмотрим на пример использования функции ВЫРАЗИТЬ:


ВЫБРАТЬ
    ВЫРАЗИТЬ(СвязанныеДокументы.Ссылка КАК Документ.РезервированиеТоваров).Склад КАК Склад,
    СвязанныеДокументы.Ссылка КАК Ссылка
ИЗ
    КритерийОтбора.СвязанныеДокументы(&Значение1) КАК СвязанныеДокументы
ГДЕ
    СвязанныеДокументы.Ссылка ССЫЛКА Документ.РезервированиеТоваров

Использование ВЫРАЗИТЬ помогает системе жестко типизировать поле. Это не только позволяет обращаться к реквизитам конкретного типа, но и повышает производительность, так как оптимизатор запросов точно знает, к какой физической таблице обращаться за данными.

Выбор нескольких типов документов одновременно

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


ГДЕ
    (СвязанныеДокументы.Ссылка ССЫЛКА Документ.РеализацияТоваровУслуг
    ИЛИ СвязанныеДокументы.Ссылка ССЫЛКА Документ.АктВыполненныхРабот)

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

Получение только одного (самого актуального) документа

Если ваша задача — выбрать из множества связанных документов только один (например, последний созданный), проанализируем ситуацию с использованием конструкций ПЕРВЫЕ и УПОРЯДОЧИТЬ ПО. Без сортировки запрос может вернуть любую случайную запись, подходящую под условия.


ВЫБРАТЬ ПЕРВЫЕ 1
    СвязанныеДокументы.Ссылка КАК Ссылка
ИЗ
    КритерийОтбора.СвязанныеДокументы(&Значение1) КАК СвязанныеДокументы
ГДЕ
    СвязанныеДокументы.Ссылка ССЫЛКА Документ.РезервированиеТоваров
УПОРЯДОЧИТЬ ПО
    СвязанныеДокументы.Ссылка.Дата УБЫВ

В данном примере мы получим самый свежий документ резервирования, связанный с нашим объектом.

Особенности работы критериев отбора в базе данных

Нам важно понимать, что КритерийОтбора — это виртуальная таблица. На уровне СУБД она представляет собой объединение (UNION ALL) всех таблиц, входящих в состав критерия. Если в состав критерия входит 50 видов документов, а вам нужен только один, фильтрация через ССЫЛКА в ГДЕ критически важна для производительности. Это позволяет платформе исключить лишние 49 таблиц из процесса поиска.

Также стоит помнить о возможности наличия "битых ссылок" (объектов, удаленных непосредственно из базы данных без контроля ссылочной целостности). Обращение к реквизитам через точку, такое как Ссылка.Проведен, эффективно отсеивает такие ссылки, так как для несуществующего объекта значение реквизита будет равно NULL, и условие в ГДЕ не будет выполнено.

Итоги

Подведем итог нашему разбору. Для эффективной работы с критериями отбора в 1С:

  1. Всегда используйте оператор ССЫЛКА в секции ГДЕ для фильтрации по типу объекта.
  2. Используйте ВЫРАЗИТЬ для безопасного и быстрого обращения к специфическим реквизитам конкретного типа документа.
  3. Для получения единственного документа не забывайте про ВЫБРАТЬ ПЕРВЫЕ 1 и обязательную сортировку УПОРЯДОЧИТЬ ПО.
  4. Помните, что правильная фильтрация в запросе значительно снижает нагрузку на сервер 1С и СУБД.
← На главную