Работа с запросами в 1С:Предприятие — одна из ключевых задач разработчика, и правильное использование условия ГДЕ (WHERE) определяет не только корректность результата, но и производительность системы. Даже опытные программисты иногда сталкиваются с нюансами: почему запрос возвращает лишние строки, как оптимизировать фильтрацию по датам или как избежать ошибок при работе с NULL?

В этой статье разберём все аспекты условия ГДЕ — от базового синтаксиса до сложных конструкций с вложенными запросами и параметрами. Вы узнаете, как правильно комбинировать операторы (=, >, В, ПОДОБНО), работать с датами и ссылками, а также избегать типичных ошибок, которые тормозят систему. Особое внимание уделим недокументированным особенностям платформы 8.3, которые влияют на выполнение условий в больших базах данных.

1. Базовый синтаксис условия ГДЕ в 1С

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

ВЫБРАТЬ

Поля

ИЗ

Таблица

ГДЕ

Условие1 [И|ИЛИ Условие2]

Примеры простых условий:

  • 🔹 ГДЕ Дата >= &ДатаНачала — выборка записей начиная с определённой даты.
  • 🔹 ГДЕ СуммаДокумента < 10000 И Валюта = &ВалютаБазовая — комбинированное условие.
  • 🔹 ГДЕ НОМЕР ПОДОБНО "А-%" — поиск по шаблону (начинается с "А-").
📊 Как часто вы используете сложные условия в запросах 1С?
Постоянно
Иногда
Редеко
Никогда

2. Операторы сравнения и логические связки

В условиях ГДЕ доступны стандартные операторы сравнения и логические операторы для комбинирования условий. Их правильное использование критично для корректности запроса.

Оператор Описание Пример
= Равенство ГДЕ Статус = "Оплачен"
<> или != Не равно ГДЕ ТипДокумента <> "ЗаказПокупателя"
>, >=, <, <= Больше/меньше ГДЕ Сумма > 10000
В Принадлежность списку ГДЕ Контрагент В (&СписокКонтрагентов)
ПОДОБНО Поиск по шаблону (с поддержкой % и _) ГДЕ Наименование ПОДОБНО "Компьютер%"

Логические операторы И (AND) и ИЛИ (OR) позволяют комбинировать условия. Приоритет операторов стандартный: И выполняется раньше ИЛИ. Для изменения порядка используйте скобки:

ГДЕ

(Дата >= &ДатаНачала И Дата <= &ДатаОкончания)

ИЛИ

Статус = "Важный"

⚠️ Внимание: При использовании оператора В с большими списками (более 1000 элементов) запрос может тормозить. В таких случаях лучше использовать временные таблицы или подзапросы.

3. Работа с параметрами и динамическими условиями

Параметры в условиях ГДЕ позволяют сделать запросы гибкими. Они обозначаются символом & и могут передаваться из кода . Примеры:

ГДЕ

ДатаДокумента >= &НачалоПериода

И ДатаДокумента <= &КонецПериода

И Организация = &ТекущаяОрганизация

Особенности работы с параметрами:

  • 🔹 Параметры могут быть любых типов: дата, число, строка, ссылка на справочник.
  • 🔹 Если параметр не задан, запрос вернёт ошибку. Всегда проверяйте заполненность перед выполнением.
  • 🔹 Для оптимизации используйте РАЗРЕШЕННЫЕ и РАЗЛИЧНЫЕ при работе со ссылками.

Пример динамического формирования условия в коде:

Условие = "";

Если ЗначениеЗаполнено(Фильтр.Контрагент) Тогда

Условие = "И Контрагент = &Контрагент";

КонецЕсли;

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

ВЫБРАТЬ

Номер,

Дата

ИЗ

Документ.ЗаказПокупателя

ГДЕ

Дата >= &ДатаНачала" + Условие;

💡

Для отладки сложных условий используйте конструкцию Сообщить(ТекстЗапроса) перед выполнением — это поможет увидеть финальный SQL-запрос.

4. Фильтрация по датам и временным интервалам

Условия по датам — одни из самых распространённых в . Здесь важно учитывать формат хранения дат и особенности сравнения. Примеры:

-- Интервал дат (включительно)

ГДЕ Дата >= &ДатаНачала И Дата <= &ДатаОкончания

-- Текущий день

ГДЕ Дата >= НАЧАЛОДНЯ(ТЕКУЩАЯДАТА())

И Дата < КОНЕЦДНЯ(ТЕКУЩАЯДАТА())

-- Последний месяц

ГДЕ Дата >= НАЧАЛОМЕСЯЦА(ДОБАВИТЬМЕСЯЦ(ТЕКУЩАЯДАТА(), -1))

И Дата < КОНЕЦМЕСЯЦА(ДОБАВИТЬМЕСЯЦ(ТЕКУЩАЯДАТА(), -1))

Ошибки при работе с датами:

  • 🔹 Использование = для сравнения с текущей датой без учёта времени (например, Дата = ТЕКУЩАЯДАТА() не сработает для документов, созданных сегодня днём).
  • 🔹 Забывают про НАЧАЛОДНЯ()/КОНЕЦДНЯ() при фильтрации по календарным дням.
⚠️ Внимание: В больших базах условие ГДЕ Дата >=.. без индекса по полю Дата может приводить к полному сканированию таблицы. Проверьте план выполнения запроса в консоли!
Как ускорить запросы по датам?

Используйте составные индексы (например, по полям Дата + Организация) и избегайте функций над полями в условиях (например, ГДЕ ГОД(Дата) = 2023 тормозит, лучше ГДЕ Дата >= '20230101' И Дата < '20260101').

5. Работа с NULL и пустыми значениями

В поле может содержать NULL (неопределённое значение) или пустую строку/ссылку. Для проверки используйте специальные функции:

-- Проверка на NULL

ГДЕ Контрагент ЕСТЬ NULL

-- Проверка на НЕ NULL

ГДЕ Контрагент НЕ ЕСТЬ NULL

-- Проверка на пустую строку

ГДЕ Наименование = ""

Типичные ошибки:

  • 🔹 Использование = NULL вместо ЕСТЬ NULL (не сработает!).
  • 🔹 Путаница между NULL и пустой ссылкой (например, для справочников).

Пример корректной фильтрации по заполненным полям:

ГДЕ

(Контрагент НЕ ЕСТЬ NULL И Контрагент.Наименование <> "")

И (Сумма > 0)

6. Сложные условия: вложенные запросы и EXISTS

Для сложной фильтрации используют вложенные запросы или оператор СУЩЕСТВУЕТ (EXISTS). Это позволяет проверять существование связанных записей без объединений (СОЕДИНЕНИЕ).

Пример с В (IN):

ГДЕ Контрагент В (

ВЫБРАТЬ

Контрагент

ИЗ

Документ.Договор

ГДЕ

ДатаОкончания > ТЕКУЩАЯДАТА()

)

Пример с СУЩЕСТВУЕТ:

ГДЕ СУЩЕСТВУЕТ (

ВЫБРАТЬ

1

ИЗ

Документ.Оплата

ГДЕ

Оплата.Заказ = Ссылка

И Оплата.Статус = "Оплачено"

)

Когда использовать СУЩЕСТВУЕТ:

  • 🔹 Когда нужно проверить наличие хотя бы одной связанной записи.
  • 🔹 Когда вложенный запрос возвращает большое количество строк (оптимизирует производительность).

Убедиться, что индексы покрывают условия вложенного запроса

Проверить план выполнения на наличие полного сканирования

Ограничить количество возвращаемых полей (например, выбрать только 1 или ключевое поле)

-->

7. Оптимизация условий для производительности

Неправильно составленные условия могут тормозить систему, особенно в больших базах. Основные правила оптимизации:

  1. 🔸 Используйте индексированные поля в условиях (проверьте в конфигураторе).
  2. 🔸 Избегайте функций над полями в условиях (например, ГОД(Дата) = 2023).
  3. 🔸 Для больших списков значений используйте временные таблицы.
  4. 🔸 Ограничивайте диапазоны дат (не используйте Дата < '30000101').

Пример неоптимального и оптимизированного запроса:

Неоптимально Оптимизировано
ГДЕ ПОДСТРОКА(Номер, 1, 3) = "АБВ" ГДЕ Номер ПОДОБНО "АБВ%"
ГДЕ ГОД(Дата) = 2023 ГДЕ Дата >= '20230101' И Дата < '20260101'
⚠️ Внимание: В последних версиях платформы 1С:Предприятие 8.3 оптимизатор запросов стал умнее, но некоторые конструкции (например, ВЫРАЗИТЬ(Дата КАК СТРОКА) в условиях) по-прежнему тормозят выполнение.
💡

Всегда проверяйте план выполнения запроса в консоли отладки (кнопка "План" в окне результата). Если видите "Полное сканирование", пересмотрите условия.

8. Типичные ошибки и как их избежать

Даже опытные разработчики допускают ошибки в условиях ГДЕ. Рассмотрим самые распространённые:

  • 🔹 Сравнение разных типов: ГДЕ Сумма = "1000" (строка vs число) не сработает. Всегда приводите типы явно.
  • 🔹 Неучтённые NULL: Условие ГДЕ Статус <> "Отменён" не вернёт строки, где Статус = NULL.
  • 🔹 Ошибки с датами: ГДЕ Дата = ТЕКУЩАЯДАТА() пропустит документы, созданные сегодня после полуночи.
  • 🔹 Лишние скобки: ГДЕ (А И Б) И (В) — скобки вокруг В избыточны.

Пример исправления типичной ошибки:

-- Неправильно (пропускает NULL)

ГДЕ Статус <> "Отменён"

-- Правильно

ГДЕ (Статус <> "Отменён" ИЛИ Статус ЕСТЬ NULL)

Для отладки сложных условий используйте:

  • 🔹 Сообщить(ТекстЗапроса) — вывод финального текста запроса.
  • 🔹 Консоль запросов в режиме отладки (проверка плана выполнения).
  • 🔹 Логирование временных таблиц для промежуточных результатов.

FAQ: Частые вопросы по условиям ГДЕ в 1С

Как проверить, что поле не пустое и не NULL?

Используйте комбинацию:

ГДЕ (Поле <> "" И Поле НЕ ЕСТЬ NULL)

Для ссылочных полей (справочники, документы):

ГДЕ (Поле.Ссылка НЕ ЕСТЬ NULL)
Почему запрос с условием по дате работает медленно?

Вероятные причины:

  1. Отсутствует индекс по полю Дата.
  2. Используются функции над полем (например, ГОД(Дата)).
  3. Диапазон дат слишком широкий (например, Дата > '20000101').

Решение: сузьте диапазон, проверьте индексы, избегайте функций.

Можно ли использовать параметры в условиях с оператором В?

Да, но с осторожностью. Пример:

ГДЕ Контрагент В (&СписокКонтрагентов)

Ограничения:

  • Список параметров не должен превышать 1000 элементов (иначе ошибка).
  • Для больших списков лучше использовать временные таблицы.
Как фильтровать по нескольким значениям одного поля?

Используйте оператор В:

ГДЕ Статус В ("Новый", "В работе", "Одобрен")

Или через ИЛИ:

ГДЕ Статус = "Новый" ИЛИ Статус = "В работе"

Первый вариант предпочтительнее для производительности.

Что делать, если условие с ПОДОБНО не находит нужные строки?

Проверьте:

  • Регистр символов (по умолчанию поиск регистронезависимый, но зависит от СУБД).
  • Наличие пробелов или спецсимволов в данных.
  • Используйте % для обозначения любых символов: ПОДОБНО "%текст%".