Работа с запросами в 1С:Предприятие — одна из ключевых задач разработчика, и правильное использование условия ГДЕ (WHERE) определяет не только корректность результата, но и производительность системы. Даже опытные программисты иногда сталкиваются с нюансами: почему запрос возвращает лишние строки, как оптимизировать фильтрацию по датам или как избежать ошибок при работе с NULL?
В этой статье разберём все аспекты условия ГДЕ — от базового синтаксиса до сложных конструкций с вложенными запросами и параметрами. Вы узнаете, как правильно комбинировать операторы (=, >, В, ПОДОБНО), работать с датами и ссылками, а также избегать типичных ошибок, которые тормозят систему. Особое внимание уделим недокументированным особенностям платформы 8.3, которые влияют на выполнение условий в больших базах данных.
1. Базовый синтаксис условия ГДЕ в 1С
Условие ГДЕ в запросах 1С аналогично WHERE в SQL, но имеет специфические особенности. Оно позволяет отфильтровать данные по одному или нескольким критериям. Основная структура:
ВЫБРАТЬ
Поля
ИЗ
Таблица
ГДЕ
Условие1 [И|ИЛИ Условие2]
Примеры простых условий:
- 🔹
ГДЕ Дата >= &ДатаНачала— выборка записей начиная с определённой даты. - 🔹
ГДЕ СуммаДокумента < 10000 И Валюта = &ВалютаБазовая— комбинированное условие. - 🔹
ГДЕ НОМЕР ПОДОБНО "А-%"— поиск по шаблону (начинается с "А-").
2. Операторы сравнения и логические связки
В условиях ГДЕ доступны стандартные операторы сравнения и логические операторы для комбинирования условий. Их правильное использование критично для корректности запроса.
| Оператор | Описание | Пример |
|---|---|---|
= |
Равенство | ГДЕ Статус = "Оплачен" |
<> или != |
Не равно | ГДЕ ТипДокумента <> "ЗаказПокупателя" |
>, >=, <, <= |
Больше/меньше | ГДЕ Сумма > 10000 |
В |
Принадлежность списку | ГДЕ Контрагент В (&СписокКонтрагентов) |
ПОДОБНО |
Поиск по шаблону (с поддержкой % и _) |
ГДЕ Наименование ПОДОБНО "Компьютер%" |
Логические операторы И (AND) и ИЛИ (OR) позволяют комбинировать условия. Приоритет операторов стандартный: И выполняется раньше ИЛИ. Для изменения порядка используйте скобки:
ГДЕ
(Дата >= &ДатаНачала И Дата <= &ДатаОкончания)
ИЛИ
Статус = "Важный"
⚠️ Внимание: При использовании оператора В с большими списками (более 1000 элементов) запрос может тормозить. В таких случаях лучше использовать временные таблицы или подзапросы.
3. Работа с параметрами и динамическими условиями
Параметры в условиях ГДЕ позволяют сделать запросы гибкими. Они обозначаются символом & и могут передаваться из кода 1С. Примеры:
ГДЕ
ДатаДокумента >= &НачалоПериода
И ДатаДокумента <= &КонецПериода
И Организация = &ТекущаяОрганизация
Особенности работы с параметрами:
- 🔹 Параметры могут быть любых типов: дата, число, строка, ссылка на справочник.
- 🔹 Если параметр не задан, запрос вернёт ошибку. Всегда проверяйте заполненность перед выполнением.
- 🔹 Для оптимизации используйте
РАЗРЕШЕННЫЕиРАЗЛИЧНЫЕпри работе со ссылками.
Пример динамического формирования условия в коде:
Условие = "";
Если ЗначениеЗаполнено(Фильтр.Контрагент) Тогда
Условие = "И Контрагент = &Контрагент";
КонецЕсли;
ТекстЗапроса = "
ВЫБРАТЬ
Номер,
Дата
ИЗ
Документ.ЗаказПокупателя
ГДЕ
Дата >= &ДатаНачала" + Условие;
Для отладки сложных условий используйте конструкцию Сообщить(ТекстЗапроса) перед выполнением — это поможет увидеть финальный SQL-запрос.
4. Фильтрация по датам и временным интервалам
Условия по датам — одни из самых распространённых в 1С. Здесь важно учитывать формат хранения дат и особенности сравнения. Примеры:
-- Интервал дат (включительно)
ГДЕ Дата >= &ДатаНачала И Дата <= &ДатаОкончания
-- Текущий день
ГДЕ Дата >= НАЧАЛОДНЯ(ТЕКУЩАЯДАТА())
И Дата < КОНЕЦДНЯ(ТЕКУЩАЯДАТА())
-- Последний месяц
ГДЕ Дата >= НАЧАЛОМЕСЯЦА(ДОБАВИТЬМЕСЯЦ(ТЕКУЩАЯДАТА(), -1))
И Дата < КОНЕЦМЕСЯЦА(ДОБАВИТЬМЕСЯЦ(ТЕКУЩАЯДАТА(), -1))
Ошибки при работе с датами:
- 🔹 Использование
=для сравнения с текущей датой без учёта времени (например,Дата = ТЕКУЩАЯДАТА()не сработает для документов, созданных сегодня днём). - 🔹 Забывают про
НАЧАЛОДНЯ()/КОНЕЦДНЯ()при фильтрации по календарным дням.
⚠️ Внимание: В больших базах условиеГДЕ Дата >=..без индекса по полюДатаможет приводить к полному сканированию таблицы. Проверьте план выполнения запроса в консоли!
Как ускорить запросы по датам?
Используйте составные индексы (например, по полям Дата + Организация) и избегайте функций над полями в условиях (например, ГДЕ ГОД(Дата) = 2023 тормозит, лучше ГДЕ Дата >= '20230101' И Дата < '20260101').
5. Работа с NULL и пустыми значениями
В 1С поле может содержать NULL (неопределённое значение) или пустую строку/ссылку. Для проверки используйте специальные функции:
-- Проверка на NULL
ГДЕ Контрагент ЕСТЬ NULL
-- Проверка на НЕ NULL
ГДЕ Контрагент НЕ ЕСТЬ NULL
-- Проверка на пустую строку
ГДЕ Наименование = ""
Типичные ошибки:
- 🔹 Использование
= NULLвместоЕСТЬ NULL(не сработает!). - 🔹 Путаница между
NULLи пустой ссылкой (например, для справочников).
Пример корректной фильтрации по заполненным полям:
ГДЕ
(Контрагент НЕ ЕСТЬ NULL И Контрагент.Наименование <> "")
И (Сумма > 0)
6. Сложные условия: вложенные запросы и EXISTS
Для сложной фильтрации используют вложенные запросы или оператор СУЩЕСТВУЕТ (EXISTS). Это позволяет проверять существование связанных записей без объединений (СОЕДИНЕНИЕ).
Пример с В (IN):
ГДЕ Контрагент В (
ВЫБРАТЬ
Контрагент
ИЗ
Документ.Договор
ГДЕ
ДатаОкончания > ТЕКУЩАЯДАТА()
)
Пример с СУЩЕСТВУЕТ:
ГДЕ СУЩЕСТВУЕТ (
ВЫБРАТЬ
1
ИЗ
Документ.Оплата
ГДЕ
Оплата.Заказ = Ссылка
И Оплата.Статус = "Оплачено"
)
Когда использовать СУЩЕСТВУЕТ:
- 🔹 Когда нужно проверить наличие хотя бы одной связанной записи.
- 🔹 Когда вложенный запрос возвращает большое количество строк (оптимизирует производительность).
Убедиться, что индексы покрывают условия вложенного запроса
Проверить план выполнения на наличие полного сканирования
Ограничить количество возвращаемых полей (например, выбрать только 1 или ключевое поле)
-->
7. Оптимизация условий для производительности
Неправильно составленные условия могут тормозить систему, особенно в больших базах. Основные правила оптимизации:
- 🔸 Используйте индексированные поля в условиях (проверьте в конфигураторе).
- 🔸 Избегайте функций над полями в условиях (например,
ГОД(Дата) = 2023). - 🔸 Для больших списков значений используйте временные таблицы.
- 🔸 Ограничивайте диапазоны дат (не используйте
Дата < '30000101').
Пример неоптимального и оптимизированного запроса:
| Неоптимально | Оптимизировано |
|---|---|
ГДЕ ПОДСТРОКА(Номер, 1, 3) = "АБВ" |
ГДЕ Номер ПОДОБНО "АБВ%" |
ГДЕ ГОД(Дата) = 2023 |
ГДЕ Дата >= '20230101' И Дата < '20260101' |
⚠️ Внимание: В последних версиях платформы 1С:Предприятие 8.3 оптимизатор запросов стал умнее, но некоторые конструкции (например, ВЫРАЗИТЬ(Дата КАК СТРОКА) в условиях) по-прежнему тормозят выполнение.
Всегда проверяйте план выполнения запроса в консоли отладки (кнопка "План" в окне результата). Если видите "Полное сканирование", пересмотрите условия.
8. Типичные ошибки и как их избежать
Даже опытные разработчики допускают ошибки в условиях ГДЕ. Рассмотрим самые распространённые:
- 🔹 Сравнение разных типов:
ГДЕ Сумма = "1000"(строка vs число) не сработает. Всегда приводите типы явно. - 🔹 Неучтённые NULL: Условие
ГДЕ Статус <> "Отменён"не вернёт строки, гдеСтатус = NULL. - 🔹 Ошибки с датами:
ГДЕ Дата = ТЕКУЩАЯДАТА()пропустит документы, созданные сегодня после полуночи. - 🔹 Лишние скобки:
ГДЕ (А И Б) И (В)— скобки вокругВизбыточны.
Пример исправления типичной ошибки:
-- Неправильно (пропускает NULL)
ГДЕ Статус <> "Отменён"
-- Правильно
ГДЕ (Статус <> "Отменён" ИЛИ Статус ЕСТЬ NULL)
Для отладки сложных условий используйте:
- 🔹
Сообщить(ТекстЗапроса)— вывод финального текста запроса. - 🔹 Консоль запросов в режиме отладки (проверка плана выполнения).
- 🔹 Логирование временных таблиц для промежуточных результатов.
FAQ: Частые вопросы по условиям ГДЕ в 1С
Как проверить, что поле не пустое и не NULL?
Используйте комбинацию:
ГДЕ (Поле <> "" И Поле НЕ ЕСТЬ NULL)
Для ссылочных полей (справочники, документы):
ГДЕ (Поле.Ссылка НЕ ЕСТЬ NULL)
Почему запрос с условием по дате работает медленно?
Вероятные причины:
- Отсутствует индекс по полю
Дата. - Используются функции над полем (например,
ГОД(Дата)). - Диапазон дат слишком широкий (например,
Дата > '20000101').
Решение: сузьте диапазон, проверьте индексы, избегайте функций.
Можно ли использовать параметры в условиях с оператором В?
Да, но с осторожностью. Пример:
ГДЕ Контрагент В (&СписокКонтрагентов)
Ограничения:
- Список параметров не должен превышать 1000 элементов (иначе ошибка).
- Для больших списков лучше использовать временные таблицы.
Как фильтровать по нескольким значениям одного поля?
Используйте оператор В:
ГДЕ Статус В ("Новый", "В работе", "Одобрен")
Или через ИЛИ:
ГДЕ Статус = "Новый" ИЛИ Статус = "В работе"
Первый вариант предпочтительнее для производительности.
Что делать, если условие с ПОДОБНО не находит нужные строки?
Проверьте:
- Регистр символов (по умолчанию поиск регистронезависимый, но зависит от СУБД).
- Наличие пробелов или спецсимволов в данных.
- Используйте
%для обозначения любых символов:ПОДОБНО "%текст%".