Логический тип Булево во встроенном языке 1С
Содержание
Булево значение в 1С задаётся всего двумя литералами — Истина и Ложь. Отдельной функции-конвертера вроде Число() или Строка() для него нет, и «создавать» переменную заранее не обязательно: тип определяется в момент присваивания. Частая путаница у тех, кто пришёл из других языков, — попытка написать == для сравнения или true/false латиницей. Во встроенном языке 1С это не сработает: сравнение и присваивание — один знак =, а значения пишутся по-русски.
Булев тип — самый простой из базовых: у него всего два значения. Но именно на нём чаще всего спотыкаются из-за NULL в запросах, бесполезной проверки ЗначениеЗаполнено и путаницы Неопределено с Ложь. Разберём работу с ним в коде, в запросах и на форме — с рабочими примерами.
Истина и Ложь: как задать логическую переменную
Переменные во встроенном языке не типизированы. Можно объявить через Перем в начале модуля, а можно сразу присвоить значение — тип подтянется автоматически:
Перем ДокументПроведён;
ДокументПроведён = Истина;
// или без объявления
ФлагОбмена = Ложь;
Чаще булево значение не пишут руками, а получают из выражения. Любое сравнение (=, <>, >, <, >=, <=) возвращает Истина или Ложь:
ЕстьОстаток = (Количество > 0);
СуммыРавны = (СуммаДокумента = СуммаОплаты);
Скобки здесь для читаемости — приоритет сравнения и так выше присваивания. Результат — обычное булево, которым дальше можно пользоваться как переменной.
Переключить флаг на противоположное значение можно одной строкой через НЕ — пригодится в обработчиках «вкл/выкл»:
РежимРедактирования = НЕ РежимРедактирования;
Где булев тип встречается в метаданных:
- 📄 реквизиты справочников, документов, регистров (флаг «Проведён», «Услуга», «Не действует»);
- 📊 ресурсы и измерения регистров сведений, когда нужно хранить признак;
- ⚙️ параметры и возвращаемые значения процедур и функций в модулях.
У реквизита объекта или справочника типа «Булево» всегда есть значение: по умолчанию оно равно Ложь. «Пустого» или неинициализированного булева у реквизита не бывает — это важно отличать от NULL, который приходит только из запросов (об этом ниже).
Логические операторы и проверка условий
Для составных условий есть три оператора: И, ИЛИ, НЕ. Приоритет такой же, как в математике: сначала НЕ, затем И, затем ИЛИ. Когда сомневаетесь — ставьте скобки, они читаются однозначно.
Если Склад = Склады.Основной И Количество > 0 Тогда
Сообщить("Товар есть на основном складе");
КонецЕсли;
Проверять булево через = Истина не нужно — переменная и так подставляется в условие:
// избыточно
Если ДокументПроведён = Истина Тогда
// правильно и короче
Если ДокументПроведён Тогда
// отрицание — через НЕ
Если НЕ ДокументПроведён Тогда
Операторы И и ИЛИ вычисляются «лениво»: если левая часть уже определяет результат, правая не считается. Это даёт безопасную проверку ссылки перед обращением к её полям:
Если Ссылка <> Неопределено И НЕ Ссылка.ПометкаУдаления Тогда
// сюда не зайдём, если Ссылка = Неопределено,
// и обращения к .ПометкаУдаления не будет — ошибки нет
КонецЕсли;
Если нужно выбрать одно из двух значений по условию, пригодится тернарный оператор ?(). Его первый аргумент — булево выражение:
ТекстСтатуса = ?(Активен, "Включён", "Отключён");
Сложную проверку удобно вынести в функцию-предикат — она возвращает Истина или Ложь и читается как обычное условие. Такой код проще сопровождать, чем длинное выражение прямо в Если:
Функция ДоступенКОтгрузке(Товар)
Возврат НЕ Товар.Услуга
И НЕ Товар.ПометкаУдаления
И Товар.ВНаличии;
КонецФункции
// применение
Если ДоступенКОтгрузке(ТекущийТовар) Тогда
ДобавитьВОтгрузку(ТекущийТовар);
КонецЕсли;
Имя функции-предиката стоит формулировать утвердительно (ДоступенКОтгрузке, ЕстьПрава), чтобы отрицание в вызове читалось естественно: Если НЕ ДоступенКОтгрузке(...).
Булево значение в циклах
Цикл Пока работает ровно до тех пор, пока его условие остаётся Истина. Классический пример — обход выборки из запроса, где метод Следующий() сам возвращает булево:
Выборка = Результат.Выбрать();
Пока Выборка.Следующий() Цикл
Сообщить(Выборка.Наименование);
КонецЦикла;
Как только строки закончатся, Следующий() вернёт Ложь, и цикл остановится.
Часто логическую переменную заводят как «флаг» — чтобы запомнить факт события внутри цикла и использовать его после. Флаг инициализируют Ложь, а при совпадении переключают на Истина:
НайденоСовпадение = Ложь;
Для Каждого Строка Из ТаблицаТоваров Цикл
Если Строка.Код = ИскомыйКод Тогда
НайденоСовпадение = Истина;
Прервать;
КонецЦикла;
КонецЦикла;
Опечатка в примере выше намеренно наглядна: закрывать Для Каждого нужно КонецЦикла, а Если — КонецЕсли. Путаница закрывающих ключевых слов — одна из частых причин, почему модуль не компилируется. Внутренний Если закрывается КонецЕсли, затем идёт КонецЦикла.
Правильный вариант завершения:
Если Строка.Код = ИскомыйКод Тогда
НайденоСовпадение = Истина;
Прервать;
КонецЕсли;
КонецЦикла;
Оператор Прервать выходит из цикла сразу, как только флаг установлен, — не нужно гонять коллекцию до конца.
Логический тип в запросах к базе данных
В языке запросов булевы литералы пишутся так же: ИСТИНА и ЛОЖЬ (регистр не важен). Логическое поле можно поставить прямо в условие ГДЕ без сравнения:
ВЫБРАТЬ
Номенклатура.Ссылка,
Номенклатура.Наименование
ИЗ
Справочник.Номенклатура КАК Номенклатура
ГДЕ
Номенклатура.Услуга
Запись ГДЕ Номенклатура.Услуга эквивалентна ГДЕ Номенклатура.Услуга = ИСТИНА. Отобрать товары, а не услуги, можно через НЕ Номенклатура.Услуга или = ЛОЖЬ.
Вычислить булево прямо в выборке помогает конструкция ВЫБОР … КОГДА:
ВЫБОР
КОГДА Номенклатура.Услуга
ТОГДА "Услуга"
ИНАЧЕ "Товар"
КОНЕЦ КАК ВидНоменклатуры
Логическое выражение можно собрать и из сравнений — например, пометить позиции с нулевым остатком:
ВЫБОР
КОГДА ОстаткиТоваров.КоличествоОстаток > 0
ТОГДА ЛОЖЬ
ИНАЧЕ ИСТИНА
КОНЕЦ КАК НетВНаличии
Булево значение удобно передавать в запрос параметром — тогда одна и та же выборка обслуживает оба случая. В тексте запроса пишем параметр, а в коде устанавливаем его значение:
// в тексте запроса
// ГДЕ Номенклатура.Услуга = &ТолькоУслуги
Запрос.УстановитьПараметр("ТолькоУслуги", Истина);
Тот же приём работает в параметрах системы компоновки данных и в отборах динамических списков: признак задаётся как булево значение, и список фильтруется без правки текста запроса.
Таблица ниже показывает, как одно и то же логическое условие выглядит в коде и в запросе.
| Задача | Встроенный язык | Язык запросов |
|---|---|---|
| Истина / Ложь | Истина / Ложь | ИСТИНА / ЛОЖЬ |
| Проверка флага | Если Услуга Тогда | ГДЕ Услуга |
| Отрицание | НЕ Услуга | НЕ Услуга |
| И / ИЛИ | И / ИЛИ | И / ИЛИ |
| Пустое значение | Неопределено | NULL |
Флажок на форме: реквизит булевого типа
Реквизит с типом «Булево» на управляемой форме по умолчанию выводится как флажок (галочка). Чтобы добавить его:
- Откройте форму в конфигураторе.
- На вкладке реквизитов добавьте реквизит и задайте тип
Булево. - Перетащите его на форму — элемент примет вид флажка автоматически.
В палитре свойств элемента есть свойство вида флажка — его можно переключить с обычной галочки на тумблер. Если нужного значения в списке не видно, ориентируйтесь по названию свойства, отвечающего за внешний вид флажка.
Булево удобно связывать с поведением формы. Два типовых приёма:
- 🔒 Доступность и видимость. Свойства «Доступность» и «Видимость» других элементов можно переключать из обработчика в зависимости от значения флажка — показывать блок полей, только когда галочка стоит.
- 🎨 Условное оформление. В настройках условного оформления списка булево поле задаёт условие — например, подсветить строки, где флаг «Проведён» снят.
- ✅ Значение по умолчанию. Чтобы новый объект создавался с уже проставленной галочкой, задайте начальное значение реквизита в обработчике заполнения — например, в
ОбработкаЗаполненияили при создании формы, присвоив реквизитуИстина.
Для флажка, который управляет видимостью соседних полей, пропишите реакцию в обработчике события «ПриИзменении» этого элемента, иначе форма перерисуется только после записи объекта.
У поля флажка есть свойство «ТриСостояния». Если его включить, галочка умеет показывать не только Истина и Ложь, но и третье, «серое» состояние — Неопределено. Это удобно для фильтров и отборов, где нужен вариант «не важно»: флаг в среднем положении означает «условие не применяем». Но помните — такой элемент возвращает уже не чистое булево, а значение, которое может быть Неопределено, и обрабатывать его надо явно.
NULL, Неопределено и приведение типов
С булевым типом связаны два «пустых» значения, и их нельзя путать.
Неопределено — значение переменной, которой ещё ничего не присвоили, или реквизита, которого нет. Это не Ложь: сравнение Неопределено = Ложь даёт Ложь.
NULL приходит из запросов, когда соединение не нашло данных. Если левым соединением подтянуть регистр остатков, а остатка нет, булево поле вернёт не ЛОЖЬ, а NULL. Строка при этом в условие ГДЕ Поле не попадёт, потому что NULL — не Истина. Лечится функцией ЕСТЬNULL:
ГДЕ ЕСТЬNULL(Остатки.ВНаличии, ЛОЖЬ)
Теперь отсутствующий остаток трактуется как Ложь, и логика становится предсказуемой.
В языке запросов логика трёхзначная: выражение с NULL даёт не Истина и не Ложь, а снова NULL. Поэтому NULL И ИСТИНА — это NULL, а строка с таким результатом в условие ГДЕ не проходит. Если в соединении есть поля, способные быть пустыми, оборачивайте их в ЕСТЬNULL до того, как подставляете в И/ИЛИ, — иначе часть строк молча выпадет из выборки.
Отдельной функции приведения к булеву типу (аналога Число(), Строка(), Дата()) во встроенном языке нет. Приводят через сравнение:
// из числа: любое ненулевое считаем Истина
Флаг = (ЗначениеЧисла <> 0);
// из строки: сверяем с эталоном
Флаг = (ВРег(СокрЛП(ТекстСтроки)) = "ДА");
Для сериализации работают стандартные функции XML: XMLСтрока(Истина) вернёт строку "true", а обратное преобразование делает XMLЗначение(Тип("Булево"), "true"). Это удобно при обмене данными и записи настроек в строку.
Функция ЗначениеЗаполнено() для булева бесполезна: ЗначениеЗаполнено(Ложь) возвращает Ложь, потому что Ложь для платформы — «пустое» значение типа. Проверять, что пользователь осознанно поставил галочку, через ЗначениеЗаполнено нельзя — у реквизита всегда есть значение по умолчанию.
Частые ошибки при работе с булевым типом
Короткий разбор граблей, на которые наступают регулярно:
- ❌
==вместо=. Во встроенном языке и в запросах сравнение — одиночный=. Двойного знака нет, он даёт синтаксическую ошибку. - ❌
true/falseлатиницей. Литералы только русские:Истина,Ложь(в запросеИСТИНА,ЛОЖЬ). Строка"Истина"— это текст, а не логическое значение. - ❌
Если Флаг = Истина. Не ошибка, но лишнее. ПишитеЕсли ФлагиЕсли НЕ Флаг. - ❌ Проверка булева через
ЗначениеЗаполнено. ДляЛожьона вернётЛожь— условие сработает не так, как ожидалось. - ❌
NULLиз запроса приняли заЛожь. После левого соединения оборачивайте логическое поле вЕСТЬNULL(Поле, ЛОЖЬ). - ❌ Путаница
НеопределеноиЛожь. Неинициализированная переменная равнаНеопределено, а неЛожь; сравнивать их напрямую нельзя.
Частые вопросы
Можно ли сравнить булево значение с числом или строкой?
Ложь, потому что это разные типы. Сначала приведите число или строку к логическому выражению через сравнение (Число <> 0), а потом сопоставляйте булево с булевым.Почему условие `ГДЕ Поле` в запросе пропускает часть строк?
NULL, оно не равно ИСТИНА, и строка в выборку не попадает. Оберните поле в ЕСТЬNULL(Поле, ЛОЖЬ), чтобы задать поведение для пустого значения.Какое значение у булева реквизита по умолчанию?
Ложь. У реквизита объекта всегда есть конкретное значение — «пустого» булева, как NULL в запросе, у него не бывает.Как в коде получить флажок с формы?
Истина или Ложь. Чтобы реагировать на переключение сразу, обработайте событие «ПриИзменении» элемента, а не ждите записи объекта.Есть ли функция `Булево()` для приведения типа?
Число(), Строка() и Дата(), конвертера к булеву типу не предусмотрено. Используйте сравнение (Значение <> 0) или функции XML для сериализации.