Как исправить ошибку «Преобразование значения к типу Булево не может быть выполнено» при синхронизации УТ 11 и БП 3.0?

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

При обновлении конфигураций «1С:Управление торговлей» (начиная с релизов 11.4.12.71, 11.4.12.77 и выше) и выполнении регулярной синхронизации с «1С:Бухгалтерия предприятия 3.0» пользователи часто сталкиваются с неприятным сбоем. Процесс выгрузки данных аварийно прерывается, а в журнале регистрации фиксируется критическая ошибка выполнения обработчика ПриОбработкеПОД для документа ВнутреннееПотреблениеТоваров (или других товарных документов). Сообщение об ошибке выглядит следующим образом:

Преобразование значения к типу Булево не может быть выполнено {ОбщийМодуль.МенеджерОбменаЧерезУниверсальныйФормат.Модуль(47324)}: Если Строка.ВыгружатьУпаковки И ЗначениеЗаполнено(Строка.УпаковкаСсылка) Тогда

Давайте подробно разберем, почему возникает это поведение системы, проанализируем исходный код конфигурации и рассмотрим несколько практических способов решения данной проблемы, включая правильное исправление запроса и создание безопасного расширения.

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

Для того чтобы понять природу ошибки, обратимся к общему модулю МенеджерОбменаЧерезУниверсальныйФормат. Ошибка происходит в момент выполнения проверки строки табличной части документа. Платформа пытается вычислить логическое выражение:

Если Строка.ВыгружатьУпаковки И ЗначениеЗаполнено(Строка.УпаковкаСсылка) Тогда

Для того чтобы такое условие успешно отработало, свойство Строка.ВыгружатьУпаковки обязательно должно содержать значение булевого типа (Истина или Ложь). Однако в проблемных релизах конфигурации при определенных условиях туда записывается значение NULL (в системе 1С представленное как DbNull). При попытке применить логическое «И» к значению NULL платформа выдает ошибку приведения типов, так как не может неявно преобразовать NULL в Булево.

Посмотрим на источник формирования этого значения. Свойство заполняется результатом запроса, текст которого генерируется в функции ПолучитьТекстЗапросаУпаковки. В проблемных релизах этот код выглядит следующим образом:


Функция ПолучитьТекстЗапросаУпаковки(КомпонентыОбмена, НаименованиеИсточника, КоличественныеПоказатели = Истина)
    // ... Сокращено для удобства
    Иначе
        ТекстЗапроса = 
        " НЕ &Источник.Упаковка = ЗНАЧЕНИЕ(Справочник.УпаковкиЕдиницыИзмерения.ПустаяСсылка) КАК ВыгружатьУпаковки, 
        | &Источник.Упаковка.Владелец КАК УпаковкаВладелец,
        | &Источник.Упаковка.ТипИзмеряемойВеличины КАК УпаковкаТипИзмеряемойВеличины,
        | &Источник.Упаковка КАК УпаковкаСсылка,
        // ... Продолжение текста запроса

Проанализируем выражение НЕ &Источник.Упаковка = ЗНАЧЕНИЕ(Справочник.УпаковкиЕдиницыИзмерения.ПустаяСсылка) КАК ВыгружатьУпаковки. Если в документе выгружается строка, в которой не указана упаковка (например, товар отгружается в базовых единицах или выгружается услуга, у которой в принципе нет и не может быть упаковок), реквизит Упаковка в базе данных равен NULL.

По правилам работы СУБД и трехзначной логики SQL:

  1. Любое сравнение с NULL возвращает NULL. Выражение NULL = ПустаяСсылка дает результат NULL.
  2. Логическое отрицание НЕ (NULL) также возвращает NULL.

В результате СУБД возвращает значение NULL в поле ВыгружатьУпаковки, что и приводит к падению всей синхронизации. Фирма «1С» зарегистрировала эту проблему как официальную ошибку с кодом 00-00307618.

Вариант 1. Временный обходной путь (без изменения кода)

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

  1. Перейдите в монитор синхронизации данных и откройте состав отправляемых данных.
  2. Найдите зарегистрированные к отправке документы Внутреннее потребление товаров (списание на расходы).
  3. Определите конкретный документ, на который ругается система (его уникальный идентификатор или номер обычно указан в начале сообщения об ошибке, например, 00УР-000109).
  4. Вручную снимите данный документ (или все документы этого типа, где не используются упаковки) с регистрации для обмена.
  5. Проведите синхронизацию повторно. Она должна завершиться успешно. Для автоматизации регулярной выгрузки данных по расписанию можно настроить программу автоматического обмена между базами 1С.
  6. Исключенные документы перенесите в базу-приемник («1С:Бухгалтерия») вручную.

Важно: Этот способ является временной полумерой и не решает проблему системно, так как при появлении новых аналогичных документов ошибка повторится. При необходимости быстро исключать отдельные объекты из выгрузки можно использовать расширение для выборочного переноса документов из УТ.

Вариант 2. Программное исправление запроса (с изменением конфигурации)

Если ваша конфигурация снята с поддержки (разрешено изменение) или вы готовы внести исправления непосредственно в основную конфигурацию, нам необходимо скорректировать функцию ПолучитьТекстЗапросаУпаковки общего модуля МенеджерОбменаЧерезУниверсальныйФормат.

Рассмотрим, как правильно переписать проблемный участок запроса, чтобы СУБД гарантированно возвращала логическое значение Ложь вместо NULL. Мы можем использовать один из двух подходов.

Подход А (Рекомендуемый, с использованием конструкции ВЫБОР):

Этот вариант наиболее нагляден и полностью соответствует стандартам разработки «1С».


// Заменяем проблемную строку на конструкцию ВЫБОР
ТекстЗапроса = 
" ВЫБОР 
|   КОГДА &Источник.Упаковка ЕСТЬ NULL 
|     ИЛИ &Источник.Упаковка = ЗНАЧЕНИЕ(Справочник.УпаковкиЕдиницыИзмерения.ПустаяСсылка) 
|   ТОГДА Ложь 
|   ИНАЧЕ Истина 
| КОНЕЦ КАК ВыгружатьУпаковки,
| &Источник.Упаковка.Владелец КАК УпаковкаВладелец,
// Далее код функции без изменений

Подход Б (Свертка через функцию ЕСТЬNULL):

Этот вариант лаконичнее и подменяет значение NULL на пустую ссылку перед непосредственным сравнением.


ТекстЗапроса = 
" НЕ ЕСТЬNULL(&Источник.Упаковка, ЗНАЧЕНИЕ(Справочник.УпаковкиЕдиницыИзмерения.ПустаяСсылка)) = ЗНАЧЕНИЕ(Справочник.УпаковкиЕдиницыИзмерения.ПустаяСсылка) КАК ВыгружатьУпаковки,
| &Источник.Упаковка.Владелец КАК УпаковкаВладелец,
// Далее код функции без изменений

При использовании любого из этих подходов поле ВыгружатьУпаковки всегда будет содержать либо Истина, либо Ложь, что позволит платформе корректно выполнить проверку условий в коде обмена.

Вариант 3. Безопасное исправление через расширение конфигурации

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

  1. Перейдите в меню Конфигурация — Расширения конфигурации.
  2. Добавьте новое расширение (например, с именем ИсправлениеОшибкиСинхронизации) и назначьте ему назначение Адаптация.
  3. В дереве объектов основной конфигурации найдите общий модуль МенеджерОбменаЧерезУниверсальныйФормат, нажмите на него правой кнопкой мыши и выберите пункт Добавить в расширение.
  4. В модуле расширения создайте процедуру-перехватчик с аннотацией &Вместо, полностью заменяющую логику исходной функции.

Посмотрим на готовый код модуля расширения:


&Вместо("ПолучитьТекстЗапросаУпаковки")
Функция ИСПР_ПолучитьТекстЗапросаУпаковки(КомпонентыОбмена, НаименованиеИсточника, КоличественныеПоказатели = Истина)
    
    Если ВерсияФорматаЧислом(КомпонентыОбмена.ВерсияФорматаОбмена) < ВерсияФорматаЧислом("1.6") Тогда
        ТекстЗапроса = " Ложь КАК ВыгружатьУпаковки, | &Источник.Упаковка КАК УпаковкаСсылка";
        ТекстЗапросаКоличественныеПоказатели = " | ,&Источник.Количество КАК КоличествоУпаковок";
    Иначе
        // Применяем исправленный вариант с конструкцией ВЫБОР для исключения NULL
        ТекстЗапроса = 
        " ВЫБОР 
        |   КОГДА &Источник.Упаковка ЕСТЬ NULL 
        |     ИЛИ &Источник.Упаковка = ЗНАЧЕНИЕ(Справочник.УпаковкиЕдиницыИзмерения.ПустаяСсылка) 
        |   ТОГДА Ложь 
        |   ИНАЧЕ Истина 
        | КОНЕЦ КАК ВыгружатьУпаковки,
        | &Источник.Упаковка.Владелец КАК УпаковкаВладелец,
        | &Источник.Упаковка.ТипИзмеряемойВеличины КАК УпаковкаТипИзмеряемойВеличины,
        | &Источник.Упаковка КАК УпаковкаСсылка,
        | ЕСТЬNULL(&Источник.Упаковка.Владелец, ЗНАЧЕНИЕ(Справочник.НаборыУпаковок.ПустаяСсылка)) ССЫЛКА Справочник.Номенклатура КАК УпаковкаНоменклатуры,
        | &Источник.Упаковка.Наименование КАК УпаковкаНаименование,
        | &Источник.Упаковка.ЕдиницаИзмерения КАК УпаковкаЕдиницаИзмерения,
        | &Источник.Упаковка.Высота КАК УпаковкаВысота,
        | &Источник.Упаковка.Глубина КАК УпаковкаГлубина,
        | &Источник.Упаковка.Объем КАК УпаковкаОбъем,
        | &Источник.Упаковка.Ширина КАК УпаковкаШирина,
        | &Источник.Упаковка.Знаменатель КАК УпаковкаЗнаменатель,
        | &Источник.Упаковка.Числитель КАК УпаковкаЧислитель";
        
        ТекстЗапросаКоличественныеПоказатели = " | ,&Источник.КоличествоУпаковок КАК КоличествоУпаковок";
    КонецЕсли;
    
    Если КоличественныеПоказатели Тогда
        ТекстЗапроса = ТекстЗапроса + ТекстЗапросаКоличественныеПоказатели;
    КонецЕсли;
    
    ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "&Источник", НаименованиеИсточника);
    
    Возврат ТекстЗапроса;
    
КонецФункции

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

← На главную