Перенос конфигурации в новую базу данных — стандартная задача при реструктуризации учета, свертке информационной базы или переходе на новые серверные мощности. Однако при ручном или частичном переносе справочников пользователи часто сталкиваются с непредвиденными ошибками при проведении документов. Одна из самых распространенных и критических ошибок в решениях на обычных формах, таких как «1С:Управление производственным предприятием 1.3» (УПП), связана с некорректной работой доработанных алгоритмов при обращении к пустым аналитическим разрезам.
В этой статье мы подробно разберем, почему при попытке заполнить или провести документ ОтчетПроизводстваЗаСмену (ОПзС) на основании документа ЗаданиеНаПроизводство (или при обычном выборе номенклатуры в ОПзС) возникает системный сбой: «Преобразование значения к типу Булево не может быть выполнено» в общем модуле ОбработкаТабличныхЧастей. Мы проанализируем архитектурную причину этой ошибки и рассмотрим два детальных сценария решения: методический (для пользователей и системных администраторов) и программный (для разработчиков 1С).
Для начала проанализируем текст ошибки, с которой сталкивается пользователь:
{ОбщийМодуль.ОбработкаТабличныхЧастей.Модуль(451)}: Преобразование значения к типу Булево не может быть выполнено
При этом проблемная строка кода выглядит следующим образом:
Если КатегорияПооперационныйУчет Тогда
В типовой конфигурации «1С:Управление производственным предприятием 1.3» данной строки в общем модуле ОбработкаТабличныхЧастей нет. Это означает, что конфигурация подверглась кастомной доработке со стороны программистов под нужды конкретного предприятия. Целью доработки было разделение логики проведения документов в зависимости от того, ведется ли по конкретной номенклатуре, подразделению или документу-основанию пооперационный учет.
Для реализации этого функционала разработчик использовал стандартный механизм платформы — «Свойства и категории объектов». Давайте вспомним, как устроен этот механизм:
КатегорииОбъектов содержит список названий категорий (например, «Пооперационный учет»). Категории работают как логические флаги (теги): они либо присвоены объекту, либо нет.РегистрСведений.КатегорииОбъектов. Если запись в регистре существует, значит, категория присвоена (Истина). Если записи нет — категория не присвоена (Ложь).В новой базе данных конфигурация была успешно развернута, однако справочники и регистры заполнялись заново или частично вручную. Перенесли только базовые данные: справочники контрагентов, номенклатуры, складов, организаций и подразделений. Специфический справочник КатегорииОбъектов и записи одноименного регистра сведений перенесены не были.
В результате при выполнении обработчика заполнения документа программа пытается инициализировать переменную КатегорияПооперационныйУчет. Поскольку в базе данных нет нужной категории, поисковый запрос или метод НайтиПоНаименованию() возвращает пустую ссылку типа СправочникСсылка.КатегорииОбъектов или значение Неопределено (либо NULL при левом соединении в запросе). Когда выполнение доходит до условной конструкции Если, платформа 1С пытается неявно привести пустую ссылку или значение NULL к логическому типу Булево. Так как платформа не умеет этого делать, сессия аварийно завершается с системной ошибкой.
Если у вас нет доступа к конфигуратору или вы не хотите менять программный код, проблему можно решить путем восстановления структуры данных, которая существовала в старой информационной базе. Разберем этот процесс по шагам:
Пооперационный учет.Номенклатуры;Подразделения или ПодразделенияОрганизации;ЗаданиеНаПроизводство.После этого попробуйте снова создать или заполнить документ ОтчетПроизводстваЗаСмену. Ошибка должна исчезнуть, так как код сможет успешно найти категорию и определить ее логическое значение.
Описанный выше пользовательский метод решает симптомы проблемы, но оставляет систему уязвимой к будущим ошибкам. Если завтра пользователь создаст новую номенклатуру и забудет присвоить ей категорию, система снова аварийно завершит работу. Чтобы сделать конфигурацию отказоустойчивой, необходимо скорректировать программный код доработки в конфигураторе.
Рассмотрим, как исправить уязвимый код в общем модуле ОбработкаТабличныхЧастей на строке 451.
Вариант 1. Исправление логического условия (если переменная содержит ссылку)
Предположим, исходный код выглядит следующим образом:
КатегорияПооперационныйУчет = Справочники.КатегорииОбъектов.НайтиПоНаименованию("Пооперационный учет");
// Небезопасное условие: если категория не найдена, переменная содержит пустую ссылку
Если КатегорияПооперационныйУчет Тогда
// Алгоритм заполнения пооперационного учета
КонецЕсли;
Чтобы избежать ошибки при отсутствии категории в справочнике, перепишем условие, добавив проверку на заполненность ссылки:
КатегорияПооперационныйУчет = Справочники.КатегорииОбъектов.НайтиПоНаименованию("Пооперационный учет");
// Безопасное условие: сначала проверяем, заполнена ли ссылка
Если ЗначениеЗаполнено(КатегорияПооперационныйУчет) Тогда
// Дополнительно проверяем, назначена ли эта категория текущему объекту
Если ОбъектИмеетКатегорию(СсылкаНаОбъект, КатегорияПооперационныйУчет) Тогда
// Алгоритм заполнения пооперационного учета
КонецЕсли;
КонецЕсли;
Вариант 2. Исправление запроса к регистру сведений (если переменная получается из запроса)
Очень часто разработчики получают статус категории с помощью запроса к регистру сведений РегистрСведений.КатегорииОбъектов. Если в запросе используется левое соединение, а запись в регистре отсутствует, поле вернет значение NULL. Попытка использовать его в условии Если гарантированно вызовет ошибку.
Рассмотрим пример небезопасного запроса:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| КатегорииОбъектов.Категория КАК КатегорияПооперационныйУчет
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.КатегорииОбъектов КАК КатегорииОбъектов
| ПО КатегорииОбъектов.Объект = Номенклатура.Ссылка
| И КатегорииОбъектов.Категория.Наименование = ""Пооперационный учет""
|ГДЕ
| Номенклатура.Ссылка = &Ссылка";
В данном случае, если связь не найдена, поле КатегорияПооперационныйУчет примет значение NULL. Чтобы этого избежать, используем функцию ЕСТЬNULL непосредственно в тексте запроса, преобразуя отсутствующую связь в явное булево значение ЛОЖЬ:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ВЫБОР
| КОГДА КатегорииОбъектов.Категория ЕСТЬ NULL ТОГДА ЛОЖЬ
| ИНАЧЕ ИСТИНА
| КОНЕЦ КАК КатегорияПооперационныйУчет
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.КатегорииОбъектов КАК КатегорииОбъектов
| ПО КатегорииОбъектов.Объект = Номенклатура.Ссылка
| И КатегорииОбъектов.Категория.Наименование = ""Пооперационный учет""
|ГДЕ
| Номенклатура.Ссылка = &Ссылка";
Такой подход полностью исключает появление значений типа NULL или пустых ссылок на этапе проверки логических условий. Даже если справочник категорий пуст, программа вернет значение Ложь и продолжит работу в штатном режиме без аварийных остановок.
Чтобы минимизировать риски возникновения подобных ошибок при миграции баз данных, рекомендуем придерживаться следующих правил:
Применяя описанные методики, вы сможете быстро локализовать и устранить сбой, восстановить стабильную работу производственного учета и обеспечить надежность программного кода вашей системы.