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

Неправильно сформированное условие в запросе может привести к катастрофическому падению производительности, особенно в высоконагруженных системах. Разработчик должен не только знать базовый синтаксис, но и понимать, как движок базы данных (MSSQL, PostgreSQL или встроенный) интерпретирует эти условия. В этой статье мы разберем нюансы построения фильтров, работу с логическими операторами и особенности обработки пустых значений.

Рассмотрим структуру запроса, где блок условий следует сразу после указания источников данных. Именно здесь происходит «магия» фильтрации, превращающая миллионы строк в понятную выгрузку для отчета или документа. Понимание приоритета операций и типов данных критически важно для написания качественного кода.

Базовый синтаксис блока условий WHERE

Блок условий в запросе 1С начинается с ключевого слова ГДЕ. После него перечисляются выражения, которые должны возвращать логическое значение ИСТИНА для того, чтобы строка попала в результирующую выборку. Синтаксис позволяет использовать поля из таблиц, константы, параметры и результаты вычислений.

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

ВЫБРАТЬ

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

Номенклатура.Артикул

ИЗ

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

ГДЕ

Номенклатура.ВидНоменклатуры = ЗНАЧЕНИЕ(Справочник.ВидыНоменклатуры.Товар)

В данном примере используется конструкция ЗНАЧЕНИЕ(..) для жесткой привязки к конкретному элементу справочника. Это эффективный способ фильтрации, так как значение подставляется на этапе компиляции запроса. Однако в динамических отчетах чаще используются параметры запроса, которые передаются из кода 1С.

💡

Используйте параметры запроса вместо жестко заданных значений (ЗНАЧЕНИЕ), если планируете переиспользовать этот запрос в разных контекстах или передавать данные из внешней обработки.

Синтаксический анализатор 1С строго следит за наличием пробелов вокруг операторов сравнения. Отсутствие пробела между именем поля и знаком равенства может привести к ошибке синтаксиса, которую новички часто не замечают с первого взгляда. Всегда проверяйте структуру запроса перед выполнением.

Логические операторы И, ИЛИ и НЕ

Реальные бизнес-задачи редко ограничиваются одним условием. Чаще всего требуется сложная фильтрация, например: «Найти документы, проведенные сегодня ИЛИ имеющие статус "Черновик", НО не помеченные на удаление». Для этого в языке запросов 1С предусмотрены логические операторы И (AND), ИЛИ (OR) и НЕ (NOT).

Приоритет выполнения операций в запросах 1С аналогичен математическому: сначала выполняется НЕ, затем И, и в последнюю очередь ИЛИ. Если порядок вычислений отличается от стандартного, необходимо использовать круглые скобки для явного указания приоритета. Игнорирование этого правила — частая причина логических ошибок в отчетах.

📊 Какой оператор вызывает у вас больше всего сложностей?
И (AND)
ИЛИ (OR)
НЕ (NOT)
Приоритет операций в скобках

Рассмотрим пример сложного условия, где важно правильно расставить скобки. Нам нужно выбрать контрагентов, которые являются юридическими лицами И имеют долг, ИЛИ являются индивидуальными предпринимателями с активной сделкой.

ВЫБРАТЬ

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

Контрагенты.ИНН

ИЗ

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

ГДЕ

(Контрагенты.ЭтоЮрЛицо = ИСТИНА И Контрагенты.ЕстьДолг = ИСТИНА)

ИЛИ

(Контрагенты.ЭтоИП = ИСТИНА И Контрагенты.АктивнаяСделка = ИСТИНА)

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

⚠️ Внимание: Оператор НЕ имеет наивысший приоритет. Выражение НЕ А ИЛИ Б интерпретируется как (НЕ А) ИЛИ Б, а не НЕ (А ИЛИ Б). Всегда используйте скобки для инверсии сложных выражений.

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

В прикладном коде 1С условия часто зависят от действий пользователя или состояния системы. Для передачи значений из внешней среды в текст запроса используются параметры. Они объявляются в объекте Запрос перед выполнением и обозначаются в тексте запроса символом &.

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

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

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

"ВЫБРАТЬ

| РегистрНакопления.Продажи.Период,

| РегистрНакопления.Продажи.Сумма

|ИЗ

| РегистрНакопления.Продажи КАК Продажи

|ГДЕ

| Продажи.Период МЕЖДУ &НачалоПериода И &КонецПериода";

Запрос.УстановитьПараметр("НачалоПериода", НачДата);

Запрос.УстановитьПараметр("КонецПериода", КонДата);

Особый случай представляет собой ситуация, когда параметр может быть неопределенным (NULL). В таких случаях часто требуется условие, которое срабатывает только если параметр заполнен. Это реализуется через проверку на ЕСТЬ NULL или использование конструкции ЕСТЬ.

Как проверить заполненность параметра?

Если параметр может быть пустым, используйте конструкцию: ( &Параметр ЕСТЬ NULL ИЛИ Поле = &Параметр ). Это позволит игнорировать условие фильтрации, если параметр не передан.

Динамическое формирование условий также возможно через конкатенацию строк, но этот метод считается менее безопасным и производительным. Рекомендуется всегда использовать параметризированные запросы, так как план выполнения такого запроса может кэшироваться СУБД, что ускоряет повторные запуски.

Специфика работы с датами и временными интервалами

Фильтрация по датам — одна из самых ресурсоемких операций в базах данных 1С. Неправильное использование функций над полями даты может привести к полному сканированию таблицы (Full Table Scan), что недопустимо в промышленных конфигурациях. Главное правило: не применяйте функции к полям таблицы в условии ГДЕ.

Вместо того чтобы писать ГОД(ПолеДата) = 2026, что заставит базу вычислять год для каждой строки, следует использовать диапазон дат. Оператор МЕЖДУ (BETWEEN) является наиболее оптимальным решением для фильтрации временных интервалов.

Способ фильтрации Производительность Использование индекса Рекомендация
ГОД(Дата) = 2026 Низкая Нет Избегать
Дата >= '20260101' И Дата < '20260101' Высокая Да Рекомендуется
Дата МЕЖДУ &Нач И &Кон Высокая Да Оптимально
СУММА(Поле) > 100 Ошибка Н/Д Только в ИМЕЮЩИЕ

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

⚠️ Внимание: Никогда не используйте функцию НАЧАЛОДНЯ() или КОНЕЦДНЯ() непосредственно в условии ГДЕ над полем таблицы. Вычисляйте границы интервала в коде 1С и передавайте их параметрами.

Обработка пустых значений (NULL) в условиях

В реляционных базах данных отсутствие значения обозначается специальным маркером NULL. Важно понимать, что NULL не равен нулю, пустой строке или ложному значению. Любое сравнение обычного значения с NULL (например, Поле = NULL) возвращает неизвестность (UNKNOWN), а не ИСТИНУ.

Для проверки на пустое значение в 1С используется специальный синтаксис: ЕСТЬ NULL или НЕ ЕСТЬ NULL. Это стандартизированный способ, который корректно транслируется в SQL-диалекты различных СУБД. Попытка использовать обычное равенство приведет к тому, что строки с пустыми значениями просто не попадут в выборку.

ВЫБРАТЬ

Сотрудники.ФИО,

Сотрудники.ДатаУвольнения

ИЗ

Справочник.Сотрудники КАК Сотрудники

ГДЕ

Сотрудники.ДатаУвольнения ЕСТЬ NULL

Этот запрос выберет всех действующих сотрудников, у которых еще не указана дата увольнения. Часто возникает необходимость обработать NULL как конкретное значение (например, заменить на 0 или пустую строку) прямо в условии. Для этого существует функция ЕСТЬNULL(Выражение, Замена).

💡

Оператор сравнения с NULL всегда возвращает ЛОЖЬ. Используйте конструкцию "ЕСТЬ NULL" для проверки отсутствия данных.

При соединении таблиц (JOIN) поведение NULL также имеет свои особенности. Если ключевое поле для соединения содержит NULL, такие строки не попадут во внутреннее соединение (INNER JOIN), но могут сохраниться при левом соединении (LEFT JOIN). Это нужно учитывать при построении сложных аналитических отчетов.

Оптимизация и частые ошибки разработчиков

Оптимизация запросов начинается с правильного написания условий. Самая распространенная ошибка — применение функций к полям, что отключает использование индексов. База данных вынуждена перебирать каждую запись, вычислять функцию и только потом сравнивать результат, что убивает производительность на больших объемах.

Еще одна проблема — неявное преобразование типов. Если поле имеет тип Число(15, 2), а в условии вы сравниваете его со строкой "100", движок может попытаться привести типы, что также замедлит выполнение. Всегда следите за соответствием типов данных в параметрах и полях выборки.

☑️ Чек-лист оптимизации условий

Выполнено: 0 / 5

Для анализа того, как выполняется ваш запрос, используйте встроенный инструмент Консоль запросов или режим отладки с включенной технологией производительности. Она покажет план выполнения запроса и подсветит узкие места, где условие WHERE сработало неэффективно.

⚠️ Внимание: Интерфейс и возможности инструмента "Технология производительности" могут отличаться в разных версиях платформы 1С. Актуальную информацию по работе с профайлером сверяйте в официальной документации ITS.1C.ru.

Часто задаваемые вопросы (FAQ)

Можно ли использовать в условии ГДЕ агрегатные функции типа СУММА или КОЛИЧЕСТВО?

Нет, агрегатные функции нельзя использовать в блоке ГДЕ, так как фильтрация происходит до группировки данных. Для фильтрации результатов агрегации необходимо использовать блок ИМЕЮЩИЕ (HAVING), который выполняется после группировки строк.

В чем разница между оператором ПОДОБНО и обычным равенством?

Оператор ПОДОБНО (LIKE) позволяет использовать шаблоны поиска с символами подстановки % (любая последовательность) и _ (один символ). Обычное равенство = требует точного совпадения значения. Использование ПОДОБНО с процентом в начале строки (например, %Иванов) часто приводит к полному сканированию таблицы.

Как правильно передать список значений в параметр запроса?

Для передачи списка значений (например, несколько выбранных элементов справочника) в параметр запроса следует использовать тип Таблица значений. В тексте запроса это поле сравнивается с помощью оператора В (IN), где справа указывается имя параметра-таблицы.

Почему запрос с условием по реквизиту справочника работает медленно?

Если условие накладывается на реквизит, который не входит в состав основных индексов таблицы, база данных будет выполнять полное сканирование. Рекомендуется проверять настройки индексов в конфигураторе или использовать предварительную выборку в временную таблицу для оптимизации.

Что означает ошибка "Неопознанный идентификатор" в блоке условий?

Эта ошибка возникает, если в условии ГДЕ используется имя поля, которое не было выбрано в блоке ВЫБРАТЬ или не имеет псевдонима таблицы. Убедитесь, что все используемые в условиях поля явно указаны в секции выбора запроса или доступны через соединение таблиц.