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

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

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

Анализируем причину ошибки и поведение платформы

Рассмотрим ситуацию: вы создаете внутренний документ программно, заполняете реквизиты и вызываете метод Записать(). Внезапно выполнение прерывается на общем модуле Делопроизводство. Код, на который указывает конфигуратор, выглядит безобидно:

Если ГрифыУтверждения.Количество() > 0

Вы открываете отладчик, проверяете ГрифыУтверждения.Количество() и видите число 0. Логическое сравнение 0 > 0 должно вернуть Ложь, и программа должна просто пойти дальше. Почему же возникает ошибка преобразования типа? Секрет кроется в том, что условие на самом деле является многострочным.

Проанализируем полную структуру условия, которая часто встречается в типовых решениях:


Если ГрифыУтверждения.Количество() > 0 
    ИЛИ ЗначениеЗаполнено(Объект.ГрифУтверждения) Тогда
    // Какая-то логика
КонецЕсли;

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

  1. При использовании оператора ИЛИ, если первая часть условия (до ИЛИ) принимает значение Истина, то вторая часть даже не вычисляется, так как результат всего выражения в любом случае будет Истина.
  2. Однако, если первая часть (в нашем случае ГрифыУтверждения.Количество() > 0) возвращает Ложь, платформа обязана вычислить вторую часть выражения, чтобы определить итоговый результат.
  3. Именно во второй части (например, при обращении к Объект.ГрифУтверждения или иной переменной) скрывается значение, которое не является логическим (Булево). Это может быть Неопределено, NULL или объект другого типа, который платформа не может неявно привести к Истина или Ложь.

Выясняем причины возникновения «не-булевых» значений

Почему при программном создании документа возникают такие странные значения? Рассмотрим подробнее основные сценарии в 1С:Документооборот:

1. Отсутствие инициализации реквизитов. Когда вы создаете документ через Справочники.ВнутренниеДокументы.СоздатьЭлемент(), объект создается «пустым». Если в коде общего модуля идет обращение к дополнительному реквизиту или специфическому параметру, который обычно инициализируется в форме, программа может получить Неопределено.

2. Работа с функциональными опциями. В 1С:Документооборот многие механизмы (например, использование грифов, категорий или проектов) зависят от функциональных опций. Если программный код пытается проверить настройку, которая не была инициализирована в текущем сеансе или для данного объекта, функция может вернуть пустой результат вместо ожидаемого Булево.

3. Кэширование и параметры сеанса. Иногда ошибка возникает из-за того, что не обновлены параметры сеанса, отвечающие за настройки делопроизводства. Код модуля Делопроизводство может опираться на закэшированные значения, которые при программном вызове оказываются недоступными.

Разберем правильный алгоритм программного создания документа

Чтобы избежать ошибок в общих модулях «1С:Документооборот», необходимо следовать строгой последовательности инициализации объекта. Посмотрим на пример правильного создания внутреннего документа:


// 1. Создаем объект
НовыйДокумент = Справочники.ВнутренниеДокументы.СоздатьЭлемент();

// 2. Обязательно вызываем Заполнить(), чтобы отработали типовые механизмы инициализации
НовыйДокумент.Заполнить(Неопределено);

// 3. Заполняем основные реквизиты
НовыйДокумент.ВидДокумента = Справочники.ВидыВнутреннихДокументов.НайтиПоНаименованию("Приказ");
НовыйДокумент.Наименование = "Тестовый документ";
НовыйДокумент.Организация = Справочники.Организации.НайтиПоНаименованию("Наша Организация");

// 4. Важный момент: инициализация табличных частей
// Если вы знаете, что код падает на проверке Грифов, инициализируйте их явно, 
// даже если они не будут содержать данных.
НовыйДокумент.ГрифыУтверждения.Очистить(); 

// 5. Вызов типовых процедур перед записью (если требуется)
// Иногда полезно вызвать процедуры из модуля менеджера или формы
// В данном случае просто записываем
Попытка
    НовыйДокумент.Записать();
Исключение
    Сообщить("Ошибка при записи: " + ОписаниеОшибки());
КонецПопытки;

Как найти «невидимую» ошибку в многострочном условии

Если вы столкнулись с подобной ситуацией, выполните следующие шаги для локализации проблемы:

  1. Проверьте весь текст условия. Не ограничивайтесь только той строкой, на которую указал конфигуратор. Посмотрите на 2-3 строки ниже. Ищите операторы И, ИЛИ.
  2. Вычислите части выражения отдельно. В табло отладчика скопируйте не всё условие Если..., а его отдельные составляющие. Например, отдельно проверьте ЗначениеЗаполнено(Объект.ГрифУтверждения) или значение переменной, стоящей после ИЛИ.
  3. Используйте стек вызовов. Посмотрите, откуда пришел вызов в общий модуль. Возможно, в вашу обработку передается объект, который не был полностью проинициализирован.
  4. Проверьте типы в метаданных. Убедитесь, что реквизит, к которому идет обращение, имеет тип, поддерживающий логическое сравнение.

Рекомендации по написанию кода для предотвращения ошибки

Проанализируем, как мы можем писать более отказоустойчивый код, чтобы другие разработчики (или мы сами) не тратили часы на отладку:

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


Если ГрифыУтверждения.Количество() > 0 
    ИЛИ Булево(НужнаяНастройка) Тогда
    // Безопасный код
КонецЕсли;

Проверка на Неопределено. Если вы работаете с реквизитами, которые могут быть не заполнены при программном создании, всегда добавляйте проверку на тип:


Если ЗначениеЗаполнено(Объект.ГрифУтверждения) И (Объект.ГрифУтверждения.Активен = Истина) Тогда
    // Логика
КонецЕсли;

Заключение

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

← На главную