Разработка сложных отчетов и выборок данных в платформе 1С:Предприятие часто требует филигранной работы с условиями отбора. Среди множества операторов сравнения и логических конструкций особое место занимает работа с полями булевого типа. Программисты нередко сталкиваются с ситуацией, когда необходимо отфильтровать записи, где флаг не установлен, или, наоборот, найти только те документы, где признак активен. Именно здесь в игру вступает ключевое слово ЛОЖЬ.

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

Синтаксис оператора ЛОЖЬ в языке запросов

В языке запросов логический тип данных представлен двумя константами: ИСТИНА и ЛОЖЬ. Эти зарезервированные слова используются для сравнения с полями типа Булево. Синтаксически оператор помещается в секцию ГДЕ или ИМЕЮЩИЕ после знака сравнения. Например, если вам нужно найти все номенклатурные позиции, которые не являются услугами, вы будете использовать именно это значение.

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

ВЫБРАТЬ

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

Справочник.Номенклатура.ЭтоУслуга

ИЗ

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

ГДЕ

Справочник.Номенклатура.ЭтоУслуга = ЛОЖЬ

Данный код вернет список всех элементов, у которых в реквизите ЭтоУслуга установлено значение ЛОЖЬ. Однако здесь кроется важный нюанс, о котором забывают новички. Если в базе данных существуют записи, где это поле не заполнено (равно NULL), они не попадут в эту выборку. Оператор сравнения с ЛОЖЬ строго требует совпадения именно с логической ложью, а не с отсутствием значения.

⚠️ Внимание: Поля типа Булево в таблицах базы данных могут принимать три состояния: ИСТИНА, ЛОЖЬ и NULL. Условие "РАВНО ЛОЖЬ" не отберет записи со значением NULL.

💡

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

Отличия между ЛОЖЬ и значением NULL

Одной из самых распространенных ошибок при построении запросов является смешение понятий "ложь" и "пустое значение". В реляционных базах данных, на которых работает , NULL означает неизвестность или отсутствие данных. Это не ноль и не ложь, это состояние неопределенности. Когда вы пишете условие Поле = ЛОЖЬ, система ищет ячейки, в которые явно записана логическая ложь.

Представьте ситуацию с документом "Заказ клиента", где есть флаг "Оплачен". Если клиент еще не совершил платеж, но менеджер еще не внес информацию в систему, поле может быть пустым (NULL). Если же менеджер явно указал, что оплаты не было, там будет стоять ЛОЖЬ. Для бизнеса это разные ситуации: в первом случае статус неизвестен, во втором — известен отрицательный ответ.

Чтобы корректно обрабатывать такие сценарии, необходимо понимать таблицу истинности для трехзначной логики SQL. Ниже приведена таблица, демонстрирующая результаты сравнения различных значений с константой ЛОЖЬ.

Значение в поле Условие: Поле = ЛОЖЬ Условие: Поле = ИСТИНА Условие: Поле ЕСТЬ NULL
ЛОЖЬ ДА (True) НЕТ (False) НЕТ (False)
ИСТИНА НЕТ (False) ДА (True) НЕТ (False)
NULL (Пусто) НЕТ (False) НЕТ (False) ДА (True)

Из таблицы видно, что запись со значением NULL никогда не удовлетворит условию равенства ЛОЖЬ. Это фундаментальное свойство SQL, которое платформа полностью наследует. Поэтому при формировании отчетов "Неоплаченные заказы" вам придется явно указывать, учитывать ли заказы с неизвестным статусом оплаты.

☑️ Проверка логики выборки

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

Использование в составных условиях отбора

На практике редко возникает необходимость отбирать данные только по одному логическому полю. Обычно ЛОЖЬ является частью сложного фильтра, включающего даты, суммы и ссылки на другие объекты. В таких случаях критически важно правильно расставлять приоритеты операций с помощью круглых скобок.

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

ВЫБРАТЬ

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

ИЗ

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

ГДЕ

(Номенклатура.ЭтоУслуга = ЛОЖЬ ИЛИ Номенклатура.Вес = 0)

И Номенклатура.ВидНоменклатуры.ЭтоТовар = ИСТИНА

В данном запросе скобки гарантируют, что сначала будет проверена группа условий внутри них, а затем результат будет объединен с проверкой вида номенклатуры. Без скобок условие Вес = 0 И Вид... = ИСТИНА сработало бы раньше, что изменило бы логику всего запроса.

⚠️ Внимание: Всегда используйте скобки при комбинировании операторов И и ИЛИ. Это предотвратит логические ошибки в сложных фильтрах.

Также стоит упомянуть возможность использования отрицания НЕ. Конструкция НЕ (Поле = ИСТИНА) формально эквивалентна поиску значений, отличных от истины. Однако, из-за наличия NULL, результат такой операции может быть неочевидным. Запись со значением NULL при проверке НЕ ИСТИНА также попадет в выборку, так как она не равна истине.

Нюансы работы оператора НЕ

Оператор НЕ меняет истинность условия на противоположную. Однако, если исходное условие возвращает NULL (неизвестно), то НЕ NULL также остается неизвестным. В контексте отбора ГДЕ, неизвестное условие трактуется как ложь, и запись не попадает в результат. Поэтому конструкция ГДЕ НЕ (Поле = ИСТИНА) отберет только записи, где Поле = ЛОЖЬ, но пропустит NULL.

Оптимизация производительности при работе с булевыми полями

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

Например, приведение типа или использование функции ЕСТЬNULL внутри условия отбора может привести к полному сканированию таблицы. Если ваша база данных содержит миллионы документов, такой запрос может выполняться недопустимо долго. Старайтесь писать условия максимально просто, позволяя оптимизатору запросов использовать имеющиеся индексы.

Особое внимание следует уделить временным таблицам. Если вы отбираете данные во временную таблицу с условием Поле = ЛОЖЬ, убедитесь, что структура временной таблицы позволяет эффективную работу с этими данными на следующих этапах алгоритма. Иногда имеет смысл явно указать тип поля в определении временной таблицы.

💡

Использование простых условий сравнения с константами (ЛОЖЬ/ИСТИНА) позволяет СУБД эффективно использовать индексы, ускоряя выборку в разы.

Частые ошибки разработчиков при написании запросов

Даже опытные специалисты иногда допускают досадные оплошности при работе с логикой. Одна из самых частых ошибок — попытка сравнить логическое поле со строкой или числом. В языке запросов строгая типизация не позволит выполнить запрос вида Поле = "Ложь" или Поле = 0. Это вызовет ошибку выполнения.

Другая распространенная проблема возникает при работе с объединениями запросов (ОБЪЕДИНИТЬ). Если в первом запросе поле имеет тип Булево, а во втором — NULL (потому что поле отсутствует или не выбрано), тип результирующего поля может измениться или привести к непредсказуемому поведению при последующей фильтрации.

  • 🚫 Попытка использовать число 0 вместо ключевого слова ЛОЖЬ приведет к ошибке типов.
  • 🚫 Игнорирование значений NULL при подсчете количества "отрицательных" записей искажает статистику.
  • 🚫 Отсутствие скобок в сложных условиях И/ИЛИ меняет приоритет вычислений.

Также стоит помнить о различиях в поведении разных СУБД (MSSQL, PostgreSQL, Oracle), которые могут использоваться под капотом . Хотя платформа абстрагирует эти различия, в редких случаях специфичная оптимизация или особенности хранения битовых масок могут влиять на скорость выполнения запросов с большим количеством логических условий.

📊 С какой проблемой вы сталкивались чаще?
Ошибка типов данных
Неверный результат из-за NULL
Медленная работа запроса
Сложная логика условий

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

Рассмотрим реальный кейс из области складского учета. Представьте, что вам необходимо сформировать отчет по товарам, у которых истек срок гарантии, но которые при этом не были списаны. В регистре сведений могут храниться даты окончания гарантии и флаг списания.

Запрос должен отбирать записи, где текущая дата больше даты гарантии, И флаг списания равен ЛОЖЬ. При этом нужно учесть, что для некоторых товаров гарантия может быть не установлена (NULL). Такие товары, согласно бизнес-логике, не должны попадать в отчет о истекшей гарантии.

ВЫБРАТЬ

РегистрСведений.ГарантияТоваров.Товар,

РегистрСведений.ГарантияТоваров.ДатаОкончания

ИЗ

РегистрСведений.ГарантияТоваров

ГДЕ

РегистрСведений.ГарантияТоваров.Списан = ЛОЖЬ

И РегистрСведений.ГарантияТоваров.ДатаОкончания < &ТекущаяДата

В этом примере использование ЛОЖЬ гарантирует, что мы игнорируем уже списанные товары. Если бы мы использовали конструкцию НЕ Списан = ИСТИНА, мы бы рискули захватить товары, по которым статус списания еще не определен, что могло бы привести к юридическим или учетным ошибкам.

Еще один пример — формирование списка пользователей, не имеющих права на проведение документов. Здесь удобно использовать отрицание отбора по группе доступа, но если право хранится в отдельном булевом реквизите, то прямое сравнение с ЛОЖЬ будет наиболее читаемым и надежным вариантом.

Как обработать ситуацию, если поле Булево пришло из внешней системы как число?

При загрузке данных из внешних источников (например, через HTTP-сервисы или текстовые файлы) логические значения могут приходить в виде 0 и 1. В этом случае перед записью в базу данных 1С необходимо выполнить преобразование типов. В самом запросе 1С нельзя сравнивать булево поле с числом. Вам потребуется использовать функцию ЕСТЬNULL или явное приведение типов на уровне кода 1С перед формированием запроса, либо использовать временную таблицу с правильной типизацией.

Можно ли использовать ЛОЖЬ в псевдонимах полей?

Нет, ключевые слова ИСТИНА и ЛОЖЬ зарезервированы для обозначения значений. Вы не можете назвать поле запроса словом "ЛОЖЬ". Однако вы можете использовать их в выражениях. Например: ВЫБРАТЬ (Поле = ЛОЖЬ) КАК ПризнакЛожности. В данном случае псевдонимом будет "ПризнакЛожности", а значением в колонке — результат сравнения.

Влияет ли язык интерфейса 1С на написание ЛОЖЬ в запросе?

Нет, язык запросов 1С не зависит от языка интерфейса пользователя или языка самой платформы (русский/английский). Ключевые слова SELECT, WHERE, TRUE, FALSE в тексте запроса всегда пишутся на русском языке (ВЫБРАТЬ, ГДЕ, ИСТИНА, ЛОЖЬ), даже если конфигурация работает на английском интерфейсе. Это внутреннее требование синтаксического анализатора платформы.

Что быстрее: Поле = ЛОЖЬ или НЕ Поле?

С точки зрения оптимизатора СУБД, эти конструкции часто эквивалентны, если поле строго типизировано и не содержит NULL. Однако конструкция Поле = ЛОЖЬ является более явной и понятной для чтения кода. Использование НЕ может усложнить анализ запроса человеком. Рекомендуется придерживаться явного сравнения для повышения поддерживаемости кода.