Как исправить ошибку «Преобразование значения к типу Булево не может быть выполнено» при поиске элементов в 1С

Программист 1С v8.3 (Управляемые формы)
← На главную

При написании программного кода в среде 1С:Предприятие начинающие разработчики часто сталкиваются с ошибкой «Преобразование значения к типу Булево не может быть выполнено». Эта ситуация типична при использовании стандартных методов поиска, таких как НайтиПоНаименованию() или НайтиПоКоду(). В данной статье мы подробно разберем, почему возникает эта ошибка, как правильно проверять результаты поиска и какие архитектурные подходы следует использовать, чтобы ваш код был надежным и эффективным.

Выясним причину возникновения ошибки

Проанализируем ситуацию, представленную в вопросе. Автор пытается выполнить проверку в процедуре ПриЗаписи следующим образом:


Процедура ПриЗаписи(Отказ)
    Если Справочники.Номенклатура.НайтиПоНаименованию("НаименованиеТовара") Тогда 
        Сообщить("Товар найден!");
    КонецЕсли;
КонецПроцедуры

Ошибка возникает из-за фундаментального непонимания того, что возвращают встроенные функции поиска. Оператор Если ожидает, что выражение после него примет логическое значение (Истина или Ложь). Однако методы НайтиПоНаименованию() и НайтиПоКоду() возвращают объект типа СправочникСсылка (ссылку на найденный элемент) или специальное значение Неопределено.

Система 1С не может автоматически превратить ссылку на справочник или Неопределено в логическое «да» или «нет». Именно поэтому выполнение прерывается с сообщением о невозможности преобразования к типу Булево.

Разберем возвращаемые значения методов поиска

Для того чтобы правильно написать условие, нужно четко понимать, что именно возвращает платформа. Согласно синтакс-помощнику (СП), методы поиска работают по следующим правилам:

  1. Если элемент с указанными данными найден, возвращается ссылка на этот элемент (СправочникСсылка).
  2. Если элемент не найден, возвращается пустая ссылка этого же типа.
  3. В исключительных случаях (например, если длина кода или наименования в метаданных установлена в 0), может вернуться значение Неопределено.

Таким образом, проверка должна строиться не на самом факте вызова функции, а на сравнении результата с «пустотой».

Решение 1: Сравнение с пустой ссылкой

Самый простой способ исправить ошибку — это явно сравнить результат поиска с пустой ссылкой соответствующего справочника. Рассмотрим исправленный пример кода:


Процедура ПриЗаписи(Отказ)
    НайденнаяСсылка = Справочники.Номенклатура.НайтиПоКоду("УТ000006624");
    
    Если Не НайденнаяСсылка.Пустая() Тогда 
        Сообщить("В базе данных существует номенклатура с таким кодом.");
    КонецЕсли;
КонецПроцедуры

Здесь мы сначала получаем результат в переменную НайденнаяСсылка, а затем используем встроенный метод ссылки Пустая(). Если метод возвращает Ложь, значит, ссылка заполнена и поиск прошел успешно.

Решение 2: Использование универсальной функции ЗначениеЗаполнено

В современной практике разработки на платформе 1С 8.3 рекомендуется использовать более универсальный и «чистый» способ — функцию ЗначениеЗаполнено(). Она корректно обрабатывает и пустые ссылки, и значение Неопределено, и пустые строки.

Проанализируем, как будет выглядеть код в этом случае:


Процедура ПриЗаписи(Отказ)
    СсылкаНаТовар = Справочники.Номенклатура.НайтиПоНаименованию("Коагучек ИксЭс PT тест");
    
    Если ЗначениеЗаполнено(СсылкаНаТовар) Тогда 
        Сообщить("Акционный товар найден в справочнике.");
    КонецЕсли;
КонецПроцедуры

Этот подход считается эталонным, так как он более читаем и устойчив к различным типам возвращаемых данных.

Архитектурная ошибка: Поиск в справочнике vs Поиск в документе

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

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

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


Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
    // Определим список кодов номенклатуры, которые участвуют в акции
    МассивАкционныхКодов = Новый Массив;
    МассивАкционныхКодов.Добавить("УТ000006624");
    МассивАкционныхКодов.Добавить("УТ000006621");
    
    АкцияНайдена = Ложь;
    
    // Обходим строки табличной части текущего документа
    Для Каждого СтрокаТовара Из Товары Цикл
        Если МассивАкционныхКодов.Найти(СтрокаТовара.Номенклатура.Код) <> Неопределено Тогда
            АкцияНайдена = Истина;
            Прервать; // Выходим из цикла, если нашли хотя бы одну позицию
        КонецЕсли;
    ДляКода;
    
    Если АкцияНайдена Тогда
        Сообщить("Внимание! В заказе присутствуют позиции, участвующие в акции.");
    КонецЕсли;
КонецПроцедуры

Почему «Хардкод» — это плохо?

В коде автора используются прямые строковые значения кодов и наименований: "УТ000006624" или "CoaguChek XS...". В профессиональной среде это называется «хардкод», и это считается плохой практикой по нескольким причинам:

  1. Хрупкость: Если пользователь изменит наименование товара в справочнике или администратор выполнит перенумерацию кодов, ваш код перестанет работать, и найти причину будет сложно.
  2. Сложность поддержки: Если список акционных товаров изменится, вам придется лезть в конфигуратор и переписывать программный код.

Как сделать лучше?

Выбор между ПриЗаписи и ПередЗаписью

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

Это позволит избежать лишней нагрузки на сервер базы данных, так как проверка будет выполнена до начала физической записи данных на диск.

Резюме

Для исправления ошибки «Преобразование значения к типу Булево» и повышения качества кода выполните следующие шаги:

  1. Всегда сравнивайте результат поиска с пустой ссылкой: Если Не Ссылка.Пустая() Тогда.
  2. Используйте ЗначениеЗаполнено() для универсальности.
  3. Проверяйте наличие товара в табличной части документа, а не в справочнике в целом, если логика касается текущего документа.
  4. Старайтесь избегать поиска по наименованию, так как оно часто содержит кавычки, пробелы и другие спецсимволы, которые легко перепутать при написании кода.
← На главную