Работа с данными в платформе 1С:Предприятие немыслима без грамотной выборки информации из базы. Основным инструментом для извлечения записей является язык запросов, который, несмотря на свою похожесть на SQL, имеет ряд уникальных особенностей. Ключевым элементом фильтрации в этом языке выступает оператор ГДЕ, позволяющий сужать круг получаемых данных до необходимых пользователю или программе значений.
Ошибки в построении условия выборки часто приводят к тому, что программа либо получает лишние данные, замедляя работу системы, либо, наоборот, не находит нужные записи. Понимание логики работы условий отбора, приоритета логических операций и особенностей сравнения с неопределенными значениями является обязательным навыком для разработчика. В этой статье мы детально разберем, как правильно формировать условия, чтобы ваши отчеты работали быстро, а обработки — корректно.
Базовый синтаксис и место оператора в запросе
Оператор ГДЕ всегда следует сразу после указания источника данных в секции ИЗ. Его задача — отфильтровать строки результирующего набора перед тем, как они будут сгруппированы или упорядочены. Синтаксически условие представляет собой логическое выражение, которое должно возвращать значение Истина для тех строк, которые попадут в выборку.
Простое условие обычно состоит из имени поля, знака сравнения и значения. Например, если вам нужно выбрать только документы со статусом «Проведен», вы используете сравнение поля с константой.
Рассмотрим пример базового запроса, где мы выбираем номенклатуру определенного вида:
ВЫБРАТЬ
Справочник.Номенклатура.Наименование,
Справочник.Номенклатура.ВидНоменклатуры
ИЗ
Справочник.Номенклатура
ГДЕ
Справочник.Номенклатура.ВидНоменклатуры = &Вид
Здесь параметр &Вид передается из кода 1С, что делает запрос гибким и переиспользуемым. Использование параметров вместо жестко заданных значений — это лучшая практика программирования в 1С, обеспечивающая защиту от SQL-инъекций и упрощающая поддержку кода.
Используйте параметры запроса (начинающиеся с амперсанда) вместо подстановки значений прямо в текст запроса. Это ускоряет выполнение за счет кэширования планов запроса сервером 1С.
Логические операторы и приоритет вычислений
При построении сложных условий часто требуется комбинировать несколько критериев. Для этого используются логические операторы И, ИЛИ и НЕ. Критически важно понимать порядок их выполнения, так как он напрямую влияет на результат выборки. В языке запросов 1С приоритет операций аналогичен математическому: сначала выполняется НЕ, затем И, и в последнюю очередь — ИЛИ.
Если вы не используете скобки, выражение А ИЛИ Б И В будет интерпретировано как А ИЛИ (Б И В), а не как (А ИЛИ Б) И В. Это частая причина ошибок, когда в отчет попадают документы, которые не должны были быть выбраны. Всегда явно указывайте группировку условий с помощью круглых скобок, чтобы логика читалась однозначно.
- 🔹 Оператор
Итребует истинности обоих условий одновременно. - 🔹 Оператор
ИЛИдостаточно истинности хотя бы одного из условий. - 🔹 Оператор
НЕинвертирует результат логического выражения.
Рассмотрим ситуацию, когда нужно выбрать документы за текущий месяц, но исключить из выборки те, что проведены оперативным учетом. Без скобок запрос может сработать некорректно:
ГДЕ
(Документ.Дата МЕЖДУ &НачПериода И &КонПериода)
И НЕ Документ.Проведен
Использование скобок здесь делает код понятным для любого разработчика, который будет поддерживать эту конфигурацию в будущем. Четкая структура условия снижает риск возникновения логических ошибок при модификации запроса.
Работа с неопределенными значениями (NULL)
Одной из самых коварных тем в запросах 1С является сравнение полей, которые могут содержать значение NULL (в терминах 1С — ЕСТЬNULL). Обычные операторы сравнения, такие как = или <>, не работают с NULL так, как ожидают новички. Выражение Поле = NULL всегда вернет ЛОЖЬ, даже если поле действительно пустое.
Для проверки на заполненность или пустоту значения необходимо использовать специальные конструкции ЕСТЬNULL и ЕСТЬ НЕ NULL. Это фундаментальное отличие языка запросов 1С от привычной логики программирования, где пустая строка и NULL часто воспринимаются схоже.
⚠️ Внимание: Никогда не используйте оператор=для проверки на NULL. КонструкцияГДЕ Поле = NULLникогда не выберет строки с пустым значением, так как результат такого сравнения всегда «Неизвестно», что трактуется как ложь в условии отбора.
Если вам нужно выбрать все записи, где поле «Комментарий» не заполнено, правильный синтаксис будет выглядеть так:
ГДЕ
Справочник.Контрагенты.Комментарий ЕСТЬNULL
А если требуется найти записи, где комментарий есть, используется конструкция:
ГДЕ
Справочник.Контрагенты.Комментарий ЕСТЬ НЕ NULL
Часто возникает задача подменить NULL на какое-то значение для дальнейших вычислений или отображения. Для этого внутри выражений используется функция ЕСТЬNULL(Значение, ЗаменяющееЗначение). Она проверяет первый аргумент: если он NULL, возвращается второй аргумент, иначе — значение первого аргумента.
Запомните золотое правило: для фильтрации по NULL используйте Keywords ЕСТЬNULL/ЕСТЬ НЕ NULL, а для подмены значения в выражениях — функцию ЕСТЬNULL().
Сравнение строк и чувствительность к регистру
При работе со строковыми данными в 1С важно учитывать настройки сравнения строк в конкретной базе данных. По умолчанию в большинстве конфигураций сравнение строк в условиях запроса нечувствительно к регистру. Это означает, что условие Наименование = "стол" найдет записи со значениями «Стол», «СТОЛ» и «стол».
Однако поведение может зависеть от используемой СУБД и настроекcollation (правила сортировки) в MS SQL Server или PostgreSQL. Если в вашей базе настроено чувствительное к регистру сравнение, то вышеуказанное условие не найдет слово с заглавной буквы. Для гарантированного поиска независимо от регистра можно использовать функцию СТРЗАМЕНИТЬ или приведение к нижнему регистру, хотя это может негативно сказаться на производительности из-за невозможности использования индексов.
Также стоит упомянуть про поиск по подстроке. Для этого используются операторы ПОДОБНО или функция НАЙТИ. Оператор ПОДОБНО поддерживает символы подстановки: процент % заменяет любую последовательность символов, а подчеркивание _ — любой один символ.
| Оператор/Функция | Описание | Производительность |
|---|---|---|
= |
Точное совпадение (обычно без учета регистра) | Высокая (использует индекс) |
ПОДОБНО "%текст%" |
Поиск подстроки в любом месте | Низкая (полный перебор) |
ПОДОБНО "текст%" |
Поиск по началу строки | Средняя (может использовать индекс) |
НАЙТИ(Поле, "текст") > 0 |
Поиск подстроки через функцию | Низкая (полный перебор) |
Использование ПОДОБНО с процентом в начале строки (например, "%иванов") является одним из самых тяжелых операций для базы данных, так как она вынуждена сканировать каждую запись в таблице. Старайтесь избегать таких условий в высоконагруженных системах.
Операторы диапазона и множественного выбора
Для упрощения записи условий, проверяющих попадание значения в определенный диапазон или список, в языке запросов 1С предусмотрены специальные операторы. Вместо громоздких конструкций с множеством И или ИЛИ, можно использовать МЕЖДУ и В.
Оператор МЕЖДУ включает граничные значения. Запись Дата МЕЖДУ &Нач И &Кон эквивалентна Дата >= &Нач И Дата <= &Кон. Это удобно для отборов по периодам, суммам или количеству. Оператор В позволяет проверить вхождение значения в список констант или результат другого запроса.
ГДЕ
Справочник.Номенклатура.Ссылка В
(ВЫБРАТЬ
РегистрСведений.ЦеныНоменклатуры.Номенклатура
ИЗ
РегистрСведений.ЦеныНоменклатуры
ГДЕ
РегистрСведений.ЦеныНоменклатуры.ВидЦены = &ОсновнаяЦена)
Такой подход не только делает код компактнее, но и зачастую позволяет оптимизатору запросов 1С построить более эффективный план выполнения. При использовании оператора В с подзапросом убедитесь, что подзапрос возвращает только одно поле, иначе возникнет ошибка синтаксиса.
Нюанс оператора МЕЖДУ
Оператор МЕЖДУ всегда включает граничные значения. Если вам нужно исключить правую границу (например, дата < КонПериода), используйте явное сравнение < вместо МЕЖДУ.
Оптимизация условий и использование индексов
Написание работающего запроса — это только половина дела. Вторая половина — обеспечение его быстродействия на больших объемах данных. Ключевым фактором производительности является способность базы данных использовать индексы для поиска записей. Если условие в секции ГДЕ написано так, что индекс не может быть применен, серверу придется выполнять полный обход таблицы, что критически замедляет работу.
Главное правило оптимизации: не применяйте функции к полям таблицы в левой части условия сравнения. Например, конструкция ГОД(Дата) = 2026 заставит базу данных вычислить год для каждой строки таблицы, что отключит использование индекса по полю Дата. Правильный вариант — использовать диапазон дат:
ГДЕ
Дата >= '20260101' И Дата < '20260101'
Аналогичная ситуация возникает при использовании приведения типов или функций обработки строк непосредственно над полем. Старайтесь, чтобы поле участвовало в сравнении в «чистом» виде. Также стоит избегать условий ИЛИ, если они охватывают разные индексы, так как это часто приводит к деградации производительности; в таких случаях иногда эффективнее объединить результаты двух отдельных запросов через ОБЪЕДИНИТЬ.
⚠️ Внимание: Избегайте использования функций над полями в условии ГДЕ. ВыражениеСТРОКА(Код) = "001"гораздо медленнее, чемКод = 1, так как первое требует пересчета каждой строки таблицы.
Всегда проверяйте план выполнения запроса через консоль отладки или инструменты администрирования СУБД, чтобы убедиться, что ваши условия действительно используют индексацию. Небольшие изменения в формулировке условия могут ускорить отчет в десятки раз.
☑️ Чек-лист оптимизации условия ГДЕ
Часто задаваемые вопросы (FAQ)
Можно ли использовать в условии ГДЕ поля из связанных таблиц?
Да, вы можете использовать поля из таблиц, подключенных через ЛЕВОЕ СОЕДИНЕНИЕ или ВНУТРЕННЕЕ СОЕДИНЕНИЕ. Однако помните, что при левом соединении условия, фильтрующие правую таблицу, лучше размещать в секции ГДЕ только если вы хотите отсечь строки, где связь не найдена. Если условие на правую таблицу поместить в ГДЕ, оно может превратить левое соединение во внутреннее.
В чем разница между ПУСТОЙ СТРОКОЙ и NULL в 1С?
В базе данных это разные значения. NULL означает отсутствие значения как такового (неизвестно), а пустая строка "" — это значение, которое известно и равно нулевой длине. В запросах 1С для строковых полей, не разрешающих NULL, пустое значение часто хранится как пустая строка, но проверка ЕСТЬNULL на нее не сработает. Нужно использовать = "".
Как передать список значений в параметр условия В?
Для передачи списка в параметр запроса используется специальный тип данных СписокЗначений в коде 1С. В тексте запроса вы ссылаетесь на него как на обычный параметр: ГДЕ Поле В &СписокПараметр. Платформа автоматически раскроет этот список при выполнении.
Почему запрос с условием по дате работает медленно?
Чаще всего проблема в том, что условие написано через функцию (например, МЕсяц(Дата)) или используется неправильный тип данных для параметра. Убедитесь, что параметр имеет тип Дата, а не Строка, и что вы используете диапазон значений, а не вычисления над полем даты.