Возможность гибкой фильтрации данных — основа эффективной работы с запросами в 1С:Предприятие. Без грамотно составленных условий даже простые отчеты превращаются в бесконечные списки ненужной информации, а аналитика теряет смысл. Но как правильно сформулировать условие, чтобы система вернула именно те записи, которые вам нужны?
Эта статья поможет разобраться с синтаксисом условий в языке запросов 1С — от базовых операторов сравнения до сложных логических конструкций с параметрами. Мы рассмотрим не только стандартные приемы, но и типичные ошибки, которые приводят к некорректным результатам или падению производительности. Особое внимание уделим нюансам работы с датами, ссылками и пустыми значениями, которые часто становятся источником проблем.
Базовый синтаксис условий: WHERE и операторы сравнения
Любое условие в запросе 1С начинается с ключевого слова ГДЕ (или его английского аналога WHERE). После него указывается поле, оператор сравнения и значение. Например, чтобы отфильтровать документы за определенную дату, используется конструкция:
ВЫБРАТЬ
Документ.Ссылка КАК Ссылка,
Документ.Дата КАК Дата
ИЗ
Документ.ЗаказПокупателя КАК Документ
ГДЕ
Документ.Дата = &ДатаОтчета
Основные операторы сравнения в 1С:
- 🔹
=— равно (точное совпадение) - 🔹
<>или!=— не равно - 🔹
<,<=— меньше/меньше или равно - 🔹
>,>=— больше/больше или равно - 🔹
В— проверка вхождения в список (В (&СписокЗначений)) - 🔹
МЕЖДУ— диапазон значений (МЕЖДУ ДатаНачала И ДатаОкончания)
Например, ГДЕ Наименование = "Товар" не найдет запись с названием "товар".
Логические операторы: И, ИЛИ, НЕ
Для создания сложных условий используются логические операторы, которые позволяют комбинировать несколько простых фильтров. В 1С доступны три основных оператора:
- 🔸
И(AND) — оба условия должны выполняться - 🔸
ИЛИ(OR) — достаточно выполнения хотя бы одного условия - 🔸
НЕ(NOT) — отрицание условия
Пример комбинированного условия:
ГДЕ
Документ.Дата >= &ДатаНачала
И Документ.Дата <= &ДатаОкончания
И (Документ.Контрагент = &Контрагент1 ИЛИ Документ.Контрагент = &Контрагент2)
И НЕ Документ.ПометкаУдаления
Приоритет выполнения операторов (если нет скобок): НЕ → И → ИЛИ. Всегда используйте скобки для явного указания порядка вычислений, чтобы избежать неоднозначностей.
Если условие становится слишком громоздким (более 5-7 строк), рассмотрите возможность вынесения части логики в временные таблицы или подзапросы. Это улучшит читаемость и может ускорить выполнение.
Работа с параметрами в условиях
Параметры позволяют сделать запросы динамическими, передавая значения извне. В 1С параметры обозначаются символом & перед именем. Например, &ДатаНачала или &СписокКонтрагентов. При выполнении запроса эти параметры должны быть заполнены реальными значениями.
Пример использования параметра:
ВЫБРАТЬ
Номенклатура.Наименование КАК Наименование,
Номенклатура.Артикул КАК Артикул
ИЗ
Справочник.Номенклатура КАК Номенклатура
ГДЕ
Номенклатура.Группа = &ВыбраннаяГруппа
И НЕ Номенклатура.ПометкаУдаления
Особенности работы с параметрами:
- 📌 Параметры могут быть любого типа: дата, число, строка, ссылка на справочник и т.д.
- 📌 Если параметр не задан, запрос завершится с ошибкой.
- 📌 Для необязательных параметров используйте конструкцию
ЕСТЬ NULL:
ГДЕ
(&Параметр ЕСТЬ NULL ИЛИ Номенклатура.Артикул = &Параметр)
Что будет если не передать значение параметра?
При выполнении запроса без обязательного параметра система выдаст ошибку "Не задан параметр запроса &ИмяПараметра". Для необязательных параметров (где используется проверка на NULL) запрос выполнится, но может вернуть неожиданные результаты.
Фильтрация по датам и временным интервалам
Условия по датам — одни из самых распространенных в 1С. Здесь важно учитывать несколько нюансов:
- 🗓️ Для интервалов всегда используйте
>=и<=, а не>и<, чтобы включить граничные даты. - 🗓️ При работе с временем (например, в документах) учитывайте, что дата без времени в 1С интерпретируется как
00:00:00. - 🗓️ Для текущей даты используйте функцию
ТЕКУЩАЯДАТА().
Примеры условий с датами:
| Задача | Условие в запросе |
|---|---|
| Документы за сегодня | Документ.Дата = ТЕКУЩАЯДАТА() |
| Документы за текущий месяц | Документ.Дата >= НАЧАЛОМЕСЯЦА(ТЕКУЩАЯДАТА()) |
| Документы за прошлый год | Документ.Дата >= НАЧАЛОГОДА(ДОБАВИТЬМЕСЯЦ(ТЕКУЩАЯДАТА(), -12)) |
| Документы за последние 30 дней | Документ.Дата >= ТЕКУЩАЯДАТА() - 30 |
Критическая ошибка: при фильтрации по датам без учета времени (например, Дата = &Параметр) вы можете пропустить документы, созданные в этот день после 00:00:00. Всегда используйте диапазоны с >= и <= для точности.
Условия для ссылочных полей и пустых значений
Работа со ссылочными полями (ссылками на справочники, документы) имеет свои особенности. Например, нельзя напрямую сравнивать ссылку с пустым значением — для этого существует оператор ЕСТЬ NULL.
Примеры условий для ссылок:
-- Товары без указанного производителя
ГДЕ
Номенклатура.Производитель ЕСТЬ NULL
-- Товары конкретного производителя
ГДЕ
Номенклатура.Производитель = &ВыбранныйПроизводитель
-- Товары из списка производителей
ГДЕ
Номенклатура.Производитель В (&СписокПроизводителей)
Для проверки заполненности реквизитов используйте:
- 🔗
ЕСТЬ NULL— поле не заполнено - 🔗
НЕ ЕСТЬ NULL— поле заполнено - 🔗
= ЗНАЧЕНИЕ(Справочник.Производители.ПустаяСсылка)— явное сравнение с пустой ссылкой
Убедиться, что справочник не пустой|Проверить права доступа к объекту|Учесть возможность NULL-значений|Оптимизировать запрос для больших справочников
-->
Сложные условия: подзапросы и временные таблицы
Когда стандартных операторов недостаточно, на помощь приходят подзапросы и временные таблицы. Они позволяют:
- 🛠️ Фильтровать данные на основе результатов другого запроса
- 🛠️ Создавать промежуточные наборы данных для сложной логики
- 🛠️ Оптимизировать производительность за счет предварительной выборки
Пример с подзапросом:
ВЫБРАТЬ
Заказ.Ссылка КАК Ссылка
ИЗ
Документ.ЗаказПокупателя КАК Заказ
ГДЕ
Заказ.Контрагент В (
ВЫБРАТЬ
Контрагент.Ссылка
ИЗ
Справочник.Контрагенты КАК Контрагент
ГДЕ
Контрагент.Группа = &ГруппаКонтрагентов
)
Пример с временной таблицей:
ВЫБРАТЬ
Товары.Наименование,
Товары.Количество
ИЗ
Документ.ПоступлениеТоваров.Товары КАК Товары
ПОМЕСТИТЬ ВТ_Товары
ГДЕ
Товары.ДокументСсылка = &СсылкаНаДокумент
;
ВЫБРАТЬ
ВТ_Товары.Наименование,
ВТ_Товары.Количество * ВТ_Товары.Цена КАК Сумма
ИЗ
ВТ_Товары КАК ВТ_Товары
ГДЕ
ВТ_Товары.Количество > 10
Временные таблицы особенно полезны, когда нужно:
- Разбить сложный запрос на логические части
- Использовать результаты одного запроса в другом
- Оптимизировать производительность за счет уменьшения вложенности
Подзапросы в условии WHERE могут значительно замедлить выполнение на больших базах данных. Если подзапрос возвращает много строк, рассмотрите возможность использования временных таблиц или joins.
Типичные ошибки и как их избежать
Даже опытные разработчики иногда допускают ошибки при составлении условий в запросах. Вот наиболее распространенные из них:
⚠️ Внимание: Использование функцииЗНАЧЕНИЕ()внутри условия для каждого ряда данных может привести к критическому падению производительности на больших выборках. Например, конструкцияГДЕ ЗНАЧЕНИЕ(Справочник.Номенклатура.Наименование) = "Товар"работает в разы медленнее, чемГДЕ Наименование = "Товар".
Другие распространенные ошибки:
- 🚫 Сравнение чисел со строками без явного приведения типов (
ГДЕ ЧисловоеПоле = "100") - 🚫 Использование
ПОДОБНОбез ограничений по длине строки на больших таблицах - 🚫 Забытые скобки в сложных логических выражениях
- 🚫 Неучтенные NULL-значения в условиях с оператором
=
Для отладки сложных условий используйте:
- Поэтапное тестирование частей условия
- Вывод промежуточных результатов с помощью
ВЫБРАТЬ РАЗРЕШЕННЫЕ.. - Конструктор запросов в конфигураторе для визуальной проверки
Помните, что 1С не всегда выдает понятные сообщения об ошибках в запросах. Например, опечатка в имени поля может привести к сообщению "Ошибка при выполнении запроса", без указания конкретной проблемы.
⚠️ Внимание: При использовании параметров типа "Массив" или "СписокЗначений" в условиях В (&Параметр) убедитесь, что элементы списка имеют совместимые типы. Например, нельзя сравнивать ссылки на документы со строками — это вызовет ошибку выполнения.
FAQ: Ответы на частые вопросы
Как сделать условие "похоже на" для строк?
Используйте оператор ПОДОБНО (или LIKE) с шаблоном. Символ % заменяет любую последовательность символов, а _ — один символ. Пример:
ГДЕ Наименование ПОДОБНО "Товар%" -- начинается на "Товар"
ГДЕ Артикул ПОДОБНО "%-100" -- заканчивается на "-100"
Для регистронезависимого поиска используйте ВРЕГ():
ГДЕ ВРЕГ(Наименование) ПОДОБНО "%ТОВАР%"
Можно ли в условии использовать функции 1С, например СОКРЛП()?
Да, но это не рекомендуется для больших таблиц, так как функции вычисляются для каждой строки, что замедляет выполнение. Пример:
ГДЕ СОКРЛП(Наименование) = "Товар"
Лучше заранее привести данные к нужному виду или использовать временные таблицы.
Как сделать условие по нескольким полям одновременно?
Используйте логические операторы И/ИЛИ для комбинирования условий:
ГДЕ
(Поле1 = Значение1 И Поле2 = Значение2)
ИЛИ
(Поле3 = Значение3 И Поле4 > Значение4)
Для сложной логики рассмотрите возможность использования ВЫРАЗИТЬ или подзапросов.
Почему условие с датой не возвращает ожидаемые результаты?
Наиболее вероятные причины:
- Не учтено время в дате (используйте
>=и<=вместо=) - Параметр даты передан без времени (например,
Дата = &Параметр, где&Параметр— это20230101000000) - Разница часовых поясов (актуально для распределенных баз)
Для отладки выведите в результат запроса поле с датой и сравните его с вашим условием.
Как оптимизировать запрос со сложными условиями?
Рекомендации по оптимизации:
- 🔧 Перенесите часть логики в
ПОМЕСТИТЬ(временные таблицы) - 🔧 Используйте индексированные поля в условиях
- 🔧 Избегайте функций над полями в условиях (
ГДЕ ЛЕВ(Наименование, 3) = "Тов") - 🔧 Разбивайте сложные запросы на несколько простых
Для анализа производительности используйте план выполнения запроса в конфигураторе.