Значение не приводится к типу Булево: ищем источник в коде и данных

· 9 мин

Содержание

Ошибка с типом Булево означает одно: платформа ждала Истина или Ложь, а получила что-то другое. Чаще всего это пустая ссылка, Неопределено, NULL из запроса или строка вроде "Да", которую никто не преобразовал. Лечится в три хода: найти строку модуля, посмотреть, что пришло в переменную, и привести значение к логическому виду там, где оно рождается.

Ниже разбор для платформы 8.3 с интерфейсом «Такси». Текст ошибки в разных ситуациях звучит по-разному: «Преобразование значения к типу Булево невозможно», «Несоответствие типов», «Значение не является значением типа Булево». Причина у них общая, поэтому и лечение общее.

Что такое Булево и когда платформа его требует

Булево — логический тип. У него ровно два значения: Истина и Ложь. Флажок в форме, условие в Если, условие цикла Пока, поле «Использование» в справочнике — везде там, где нужен ответ «да или нет», платформа работает с этим типом.

Строгость у платформы выборочная. Часть преобразований она делает молча:

  • число 0 превращается в Ложь, любое другое число — в Истина;
  • строки "Да" и "Истина" при явном вызове Булево("Да") дают Истина, а "Нет" и "Ложь" дают Ложь.

А вот Неопределено, NULL, пустая ссылка и произвольные строки в логическое значение не превращаются. Здесь и возникает исключение.

Правило для себя: платформа прощает числа и «Да/Нет», но не прощает «ничего». Любая пустота — главный подозреваемый.

Где тип Булево прячется неявно

Не каждое обращение к нему видно в коде. Булево требуется:

  • в условии Если, ИначеЕсли, Пока;
  • в операторах И, ИЛИ, НЕ;
  • в тернарном выражении ?(Условие, Да, Нет);
  • при записи в реквизит с типом Булево;
  • в условии ГДЕ запроса, если выражение возвращает не логическое значение.

Поэтому ошибка бывает в строке, где «вроде нет ни одного логического значения». Достаточно, чтобы вместо него подставилась переменная с неподходящим содержимым.

Откуда берётся неподходящее значение

Разработчики 1С сталкиваются с ограниченным набором сценариев. Знание этого набора сокращает поиск с часа до пяти минут.

Результат обращения к реквизиту через точку

Самый частый случай. Обращение вида Документ.Контрагент.Договор.Действует внутри условия. Если на каком-то звене цепочки ссылка пустая, на выходе будет не Ложь, а значение, которое в условии использовать нельзя. Проверка: подставьте цепочку в отладчике по частям.

NULL из результата запроса

Запрос с левым соединением возвращает NULL там, где парной записи нет. Если такое поле попало в условие, ошибка неизбежна. Типичная картина: отчёт работает на тестовой базе, где все данные заполнены, и падает на рабочей, где у части контрагентов нет договора.

Значение из внешнего источника

Загрузка из Excel , CSV, обмен через XML или веб-сервис приносят текст. В ячейке написано «Да», «1», «+» или «TRUE», а в реквизит с типом Булево надо положить Истина. Прямое присваивание строки либо падает, либо даёт неверный результат.

Составной тип и забытая проверка

Реквизит может принимать несколько типов: Булево, Число, Строка. До первой записи в нём лежит Неопределено. Код, написанный в расчёте на «там всегда флажок», ломается на первой же новой строке.

Параметры процедур

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

Как найти место ошибки: журнал и отладчик

Сначала узнайте, где именно падает. Угадывать по тексту не нужно: платформа показывает стек вызова.

Шаг 1. Прочитайте стек в окне ошибки

В сообщении будет имя модуля, процедуры и номер строки, например {ОбщийМодуль.РаботаСДоговорами.Модуль(124)}. Нажмите «Подробно» и скопируйте весь текст. Номер строки — это точка входа.

Шаг 2. Загляните в журнал регистрации

Если ошибка ушла и пользователь не помнит, что делал, поможет журнал. В режиме 1С:Предприятие он открывается из раздела Администрирование (подраздел обслуживания), в Конфигураторе — через меню Администрирование → Журнал регистрации. Журнал доступен пользователям с правом администрирования.

Отберите события так:

  1. Задайте период — час-два вокруг времени жалобы.
  2. В отборе по уровню оставьте Ошибка.
  3. Добавьте отбор по пользователю, если жалоба от одного человека.
  4. Откройте событие «Ошибка выполнения…» и прочитайте комментарий — там будет тот же стек, что и в окне.

Журнал полезен ещё и тем, что показывает серию ошибок. Если одна и та же строка падает у десяти пользователей, значит причина в данных, а не в действиях одного оператора.

Шаг 3. Остановитесь на ошибке в отладчике

Откройте базу в Конфигураторе и запустите отладку (F5). В меню Отладка включите остановку по ошибке — платформа прервёт выполнение на строке, которая падает, и покажет локальные переменные. Дальше два действия:

  • наведите курсор на переменную из условия — увидите её значение и тип;
  • нажмите Shift+F9 и вычислите выражение целиком, по частям.

Если в окне «Вычислить» видно Неопределено или NULL, источник найден. Остаётся выяснить, почему туда не попало логическое значение.

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

Диагностика: выберите симптом

Проверка условий в коде и запросах

Когда место найдено, переходим к исправлению. Принцип один: превращайте «что-то» в Истина или Ложь как можно раньше, там, где значение появилось, а не в конечном условии.

Условия в модуле

Проверяйте заполненность перед использованием:

Если ЗначениеЗаполнено(Договор) Тогда
    Действует = Договор.Действует;
Иначе
    Действует = Ложь;
КонецЕсли;

Если Действует Тогда
    // дальнейшая обработка
КонецЕсли;

Если значение приходит снаружи как строка, используйте явное преобразование:

Функция ТекстВБулево(Текст)
    Нормализованный = НРег(СокрЛП(Текст));
    Возврат Нормализованный = "да"
        Или Нормализованный = "истина"
        Или Нормализованный = "1"
        Или Нормализованный = "+";
КонецФункции

Функция возвращает Ложь на любой «непонятный» вход, и это сознательный выбор: обработка не падает, а неверные строки легко найти по отчёту после загрузки. Если для вас пустой текст должен быть ошибкой, а не Ложью, добавьте отдельную проверку и выдайте сообщение пользователю.

Условия в запросе

NULL в запросе обрабатывается на стороне запроса. Два рабочих приёма.

Первый — подстановка значения по умолчанию:

ВЫБРАТЬ
    Контрагенты.Ссылка КАК Контрагент,
    ЕСТЬNULL(Договоры.Действует, ЛОЖЬ) КАК Действует
ИЗ
    Справочник.Контрагенты КАК Контрагенты
        ЛЕВОЕ СОЕДИНЕНИЕ Справочник.ДоговорыКонтрагентов КАК Договоры
        ПО Договоры.Владелец = Контрагенты.Ссылка

Второй — явное выражение выбора, когда нужна своя логика:

ВЫБОР
    КОГДА Договоры.Ссылка ЕСТЬ NULL ТОГДА ЛОЖЬ
    ИНАЧЕ Договоры.Действует
КОНЕЦ

Оба варианта делают то же самое: к моменту, когда результат попадёт в код, поле всегда содержит логическое значение.

Если запрос используется в схеме компоновки данных, поле с ЕСТЬNULL удобно сразу задать в наборе данных. Тогда условия отбора в отчёте не будут падать на пустых строках.

Три приёма, которые не стоит забывать

Опытный разработчик держит в голове три вещи, без которых разбор неполон:

  1. Явно сравнивать с Истина не нужно — Если Флаг = Истина Тогда избыточно. Но проверить тип стоит: ТипЗнч(Флаг) = Тип("Булево").
  2. Не смешивать Неопределено и Ложь. Это разные состояния: «не знаем» и «нет». Если логике нужны три состояния, заводите перечисление, а не флажок.
  3. Не писать функцию, у которой есть ветка без Возврат. Вызывающий код получит Неопределено и упадёт в чужом месте.

Исправление уже испорченных данных

Иногда причина не в коде, а в записях, которые давно лежат в базе. Реквизит принимает составной тип, в нём лежат строки или числа, и каждый отчёт, который эти данные читает, падает.

Как найти плохие записи

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

Если реквизит одного типа — Булево, — испорченных записей быть не может: платформа не даст положить в него другой тип. Тогда проблема в расчёте, который строится поверх этого реквизита.

Как исправить

Исправляйте обработкой, а не вручную в форме, если записей больше десятка:

  1. Сделайте копию базы или выгрузку .dt.
  2. Отберите записи с неверным значением.
  3. Для каждой запишите правильное логическое значение, определив его по содержимому: «Да» → Истина, пусто → Ложь.
  4. Запись выполняйте с отключёнными проверками и обработчиками только если вы точно знаете, что они не нужны; иначе изменения запустят пересчёты и обмены.

Перед массовой правкой данных сделайте резервную копию. Обработка, которая меняет тысячу записей, откатывается только из копии.

После правки прогоните тот сценарий, на котором падало. Если ошибка осталась, значит, источник не в данных — вернитесь к коду.

Проверка после исправления
Выполнено: 0 / 4

Как не получить ошибку снова

Профилактика сводится к привычкам при написании кода и настройке данных.

Привычки разработчика

  • Задавайте начальное значение логической переменной: Результат = Ложь;. Тогда у функции всегда есть что вернуть.
  • Все ветки функции заканчивайте Возврат. Включите в отладчике просмотр результата перед выходом.
  • Не используйте реквизиты составного типа там, где достаточно флажка. Чем уже тип, тем меньше сюрпризов.
  • Поля запроса, которые уйдут в условия, оборачивайте в ЕСТЬNULL.
  • Внешние данные приводите к типу на границе: сразу после чтения файла или ответа сервиса.

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

  • Не загружайте данные из Excel в реквизиты, не проверив, что в колонке нет текста вместо «Да/Нет».
  • После обновления конфигурации проверяйте типовые отчёты и документы на тестовой копии.
  • Смотрите журнал регистрации раз в неделю: серия одинаковых ошибок видна сразу, пока ей не пользуются все сотрудники.

Когда не надо лезть в код

Если ошибка появилась после обновления типовой конфигурации и код модуля вы не писали, не правьте типовой модуль «на месте». Такая правка слетит при следующем обновлении, а конфигурация перейдёт на поддержку с изменениями. Безопаснее оформить расширение или обратиться к тому, кто сопровождает базу. Если правка не ваша, а источник в данных — исправляйте данные.

Сводная таблица

Источник значенияЧто приходитЧто делать
Пустая ссылка в цепочкеНеопределеноПроверить ЗначениеЗаполнено до обращения
Запрос, левое соединениеNULLЕСТЬNULL(Поле, ЛОЖЬ) в запросе
Файл, обменСтрока «Да/Нет», «1»Своя функция разбора
Составной реквизитНеопределено до записиОграничить тип или проверять тип
Функция без ВозвратНеопределеноЗадать значение по умолчанию

Частые вопросы

Чем Булево отличается от флажка в форме?
Флажок — это элемент формы, а Булево — тип данных, который в нём хранится. Флажок связан с реквизитом типа Булево и показывает Истина как поставленную галочку.
Можно ли хранить в реквизите три состояния: да, нет, не знаю?
С типом Булево нельзя: у него только два значения. Для трёх состояний заведите перечисление с значениями «Да», «Нет», «Не определено».
Почему ошибка есть у одного пользователя, а у других нет?
Обычно у него другие данные: пустой договор, незаполненный реквизит или иные настройки. Проверьте именно его документ и его параметры сеанса.
Что делать, если ошибка в типовом отчёте?
Скопируйте стек из окна ошибки и проверьте, какие данные попадают в отчёт. Чаще всего помогает заполнить пустые справочники. Модуль отчёта не правьте напрямую, а используйте расширение.
Как быстро проверить значение в отладчике?
Остановитесь на строке и вычислите выражение через Shift+F9. Там видно и значение, и его тип.