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

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

Как сделать отбор в запросе 1С

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

Отбор в запросе 1С — это условие, по которому из таблицы выбираются только нужные строки. Без отбора запрос вернёт всё содержимое таблицы: на больших базах это тысячи и миллионы записей, лишняя нагрузка на сервер и медленная работа отчётов. Правильно построенный отбор сокращает выборку до необходимого минимума ещё на уровне СУБД.

Основной инструмент отбора — оператор ГДЕ (аналог WHERE в SQL). Он записывается после указания источника данных и содержит логическое условие: сравнение поля со значением, с параметром, с другим полем или с результатом вложенного запроса. Дополнительно отборы можно задавать в параметрах виртуальных таблиц, в конструкторе запроса и в объединениях.

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

Базовый синтаксис оператора ГДЕ

Конструкция ГДЕ ставится после предложения ИЗ, в котором указан источник данных. Условие состоит из поля, оператора сравнения и значения. Простейший пример — выбрать контрагентов с конкретным наименованием:

ВЫБРАТЬ

Контрагенты.Ссылка,

Контрагенты.Наименование

ИЗ

Справочник.Контрагенты КАК Контрагенты

ГДЕ

Контрагенты.Наименование = "ООО Ромашка"

Доступные операторы сравнения: =, <> (не равно), >, <, >=, <=. Несколько условий объединяются логическими операторами И, ИЛИ, НЕ. Приоритет можно задавать скобками — их стоит ставить всегда, когда смешиваются И и ИЛИ, иначе логика может оказаться не той, что ожидалась.

Пример составного условия — документы одного контрагента за период:

ВЫБРАТЬ

Реализация.Ссылка,

Реализация.СуммаДокумента

ИЗ

Документ.РеализацияТоваровУслуг КАК Реализация

ГДЕ

Реализация.Контрагент = &Контрагент

И Реализация.Дата МЕЖДУ &НачалоПериода И &КонецПериода

И Реализация.Проведен

Отбор через параметры запроса

Подставлять значения прямо в текст запроса — плохая практика: значения с типом «Дата» или «Ссылка» так вообще не задать, а конкатенация строк чревата ошибками и нечитаемым кодом. Правильный способ — параметры. В тексте запроса параметр начинается с символа &, а значение ему присваивается в коде модуля:

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| Номенклатура.Ссылка

|ИЗ

| Справочник.Номенклатура КАК Номенклатура

|ГДЕ

| Номенклатура.Родитель = &Группа";

Запрос.УстановитьПараметр("Группа", ГруппаТоваров);

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

Имя параметра в УстановитьПараметр пишется без символа &. Один и тот же параметр можно использовать в условии несколько раз — значение задаётся один раз. Если параметр не установлен, при выполнении запроса возникнет ошибка, поэтому полезно проверять заполнение значений до вызова Выполнить().

Отбор по датам и периодам

Даты — самый частый источник ошибок в отборах. Условие Дата = &Дата сравнивает с точностью до секунды, поэтому документы за день так не отберешь. Для периода используйте оператор МЕЖДУ или пару условий:

ГДЕ

Документ.Дата МЕЖДУ &НачалоДня И &КонецДня

Конец периода нужно задавать как конец дня — функцией КонецПериода(Дата, День) в коде или КОНЕЦПЕРИОДА(&Дата, ДЕНЬ) прямо в запросе. Если передать просто дату без времени, она будет означать 00:00:00, и документы, созданные в течение дня, в выборку не попадут.

Для документов есть нюанс: у поля Дата хранится и время. Если нужно сравнить только дату без времени, используйте конструкцию НАЧАЛОПЕРИОДА(Документ.Дата, ДЕНЬ) = &Дата. Но помните: применение функции к полю в условии мешает использованию индекса и замедляет запрос на больших таблицах.

Отбор по списку значений: оператор В

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

ГДЕ

Номенклатура.Ссылка В (&СписокНоменклатуры)

В коде параметру присваивается массив или список значений. Для проверки вхождения в иерархию справочника используется вариант В ИЕРАРХИИ — он отберёт элементы самой группы и всех её подгрупп любого уровня вложенности:

ГДЕ

Номенклатура.Родитель В ИЕРАРХИИ(&Группа)

Обратное условие — НЕ В (...). С ним будьте внимательны: если поле может содержать NULL (например, при левом соединении), строки с NULL не попадут в результат ни при В, ни при НЕ В, потому что сравнение с NULL не даёт ни истины, ни лжи.

Отбор по табличной части документа

Частая задача — найти документы, в которых в табличной части есть определённая номенклатура. Табличная часть подключается как отдельная таблица через точку:

ВЫБРАТЬ РАЗЛИЧНЫЕ

Товары.Ссылка

ИЗ

Документ.РеализацияТоваровУслуг.Товары КАК Товары

ГДЕ

Товары.Номенклатура = &Номенклатура

Ключевое слово РАЗЛИЧНЫЕ здесь обязательно: если товар встречается в документе в нескольких строках, без него документ попадёт в результат несколько раз. Альтернатива — сгруппировать по ссылке.

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

Порядок действий
  1. 1
    Откройте консоль запросов или конструктор запроса в конфигураторе
  2. 2
    Выберите источник данных и нужные поля
  3. 3
    Добавьте условие в секцию ГДЕ, используя параметры вместо литералов
  4. 4
    Установите значения параметров через УстановитьПараметр
  5. 5
    Выполните запрос и проверьте результат на контрольном примере

Отборы в виртуальных таблицах регистров

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

ВЫБРАТЬ

Остатки.Номенклатура,

Остатки.КоличествоОстаток

ИЗ

РегистрНакопления.ТоварыНаСкладах.Остатки(

&Период,

Склад = &Склад

И Номенклатура В (&СписокНоменклатуры)) КАК Остатки

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

Для СрезПоследних отбор в параметрах особенно важен: без него платформа строит срез по всей таблице регистра сведений, что на больших базах приводит к заметным паузам. Условие в ГДЕ поверх виртуальной таблицы фильтрует уже готовый результат и не снижает объём вычислений.

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

Отбор в параметрах виртуальной таблицы

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

Отбор в ГДЕ

Универсален: любые поля, функции, вложенные запросы, связи нескольких таблиц. Минус — фильтрация после формирования выборки, что медленнее на виртуальных таблицах.

Отбор через вложенный запрос во временную таблицу

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

Нестандартные условия: ПОДОБНО, NULL и ссылки

Для поиска по части строки применяется оператор ПОДОБНО с шаблоном: символ % заменяет любую последовательность символов, _ — один символ. Пример: Контрагенты.Наименование ПОДОБНО "%ромашка%". Учтите, что поиск с ведущим % не использует индекс и на больших справочниках работает медленно.

Проверка на незаполненное значение делается через ЕСТЬ NULL и НЕ ЕСТЬ NULL. Сравнение = NULL в языке запросов не работает — такое условие никогда не будет истинным. Для подмены NULL значением по умолчанию используйте функцию ЕСТЬNULL(Поле, 0).

Для сравнения с пустой ссылкой конкретного типа есть функция ЗНАЧЕНИЕ(Справочник.Номенклатура.ПустаяСсылка). А ЗНАЧЕНИЕ(Перечисление.ВидыОпераций.Продажа) позволяет отбирать по значению перечисления без параметра. Проверить тип поля составного типа можно функцией ТИПЗНАЧЕНИЯ(Поле) = ТИП(Документ.РеализацияТоваровУслуг).

Типичные ошибки
01
Сравнение даты без учёта времени: условие Дата <= &Дата отсекает документы последнего дня — используйте КОНЕЦПЕРИОДА
02
Условие = NULL вместо ЕСТЬ NULL: запрос молча возвращает пустой результат
03
Отбор виртуальной таблицы в ГДЕ вместо параметров: на больших регистрах запрос выполняется в разы дольше
04
Конкатенация значений в текст запроса вместо параметров: ошибки с типами и нечитаемый код
05
Отсутствие РАЗЛИЧНЫЕ при отборе по табличной части: документы дублируются в результате

Как проверить, что отбор работает правильно

Надёжный способ — консоль запросов (внешняя обработка или встроенная в режиме предприятия для некоторых конфигураций). В ней запрос выполняется интерактивно: можно менять параметры и сразу видеть результат, не перезапуская код.

Методика проверки: возьмите 2–3 записи, которые заведомо должны попасть в выборку, и 2–3, которые не должны. Выполните запрос и убедитесь, что состав результатов совпадает с ожиданием. Затем проверьте граничные случаи: пустой параметр, граница периода, запись с NULL в отбираемом поле.

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

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

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

Количество строк в выборке
Норма

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

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

Запрос вернул больше (дубли) или меньше (отсеклись нужные записи)

Границы периода
Норма

Документы первой и последней секунды периода присутствуют

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

Пропали документы последнего дня — не задан конец дня

Поведение при пустом параметре
Норма

Ожидаемое: либо пустой результат, либо все записи — по логике задачи

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

Запрос падает с ошибкой неустановленного параметра

Частые вопросы по отборам в запросах 1С

Как отобрать записи, где поле не заполнено?

Используйте условие Поле ЕСТЬ NULL для соединений или сравнение с пустым значением: пустой ссылкой через ЗНАЧЕНИЕ(Справочник.Имя.ПустаяСсылка), пустой строкой "" или нулём — в зависимости от типа поля. Сравнение = NULL не работает.

Чем отличается ГДЕ от ИМЕЮЩИЕ?

ГДЕ фильтрует строки до группировки, ИМЕЮЩИЕ — уже сгруппированные результаты по значениям агрегатных функций. Например, «контрагенты с суммой продаж больше миллиона» — это ИМЕЮЩИЕ СУММА(Сумма) > 1000000.

Можно ли в отборе использовать результат другого запроса?

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

Почему отбор по параметру-списку не работает?

Проверьте, что параметру присвоен именно массив или список значений, а не одиночное значение, и что типы элементов совпадают с типом поля. Также убедитесь, что список не пуст — пустой список в условии В не даст ни одной строки.

Как отобрать элементы справочника вместе с подгруппами?

Используйте условие Родитель В ИЕРАРХИИ(&Группа) для отбора по конкретной группе или Ссылка В ИЕРАРХИИ(&Группа), если нужно включить саму группу-элемент. Это работает только для иерархических справочников.

Итог

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

Отбор задаётся оператором ГДЕ с параметрами через УстановитьПараметр. Для виртуальных таблиц регистров отбор эффективнее указывать в параметрах таблицы. Проверяйте границы дат, используйте ЕСТЬ NULL вместо = NULL и тестируйте запрос в консоли на контрольных данных.