Как исправить ошибку «Неправильная константа типа Число» при загрузке XML в 1С:Бухгалтерия 3.0?

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

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

Ошибка компиляции при вычислении выражения или выполнении фрагмента кода: {(1,34)}: Неправильная константа типа Число.

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

Проанализируем причину возникновения ошибки

Механизм универсального обмена (созданный с помощью «Конвертации данных 2.1») устроен таким образом, что алгоритмы правил обмена хранятся внутри XML-файла в виде обычного текста. Когда происходит загрузка объекта (в нашем случае справочника «Организации»), обработка берет текстовый код из обработчика (например, ПослеЗагрузкиОбъекта) и пытается скомпилировать его «на лету» с помощью встроенного метода платформы Выполнить().

Сообщение об ошибке компиляции означает, что в тексте алгоритма есть синтаксические проблемы. Часто ошибка «Неправильная константа типа Число» маскирует под собой следующие нюансы:

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

Разберем решение проблемы по шагам

Посмотрим на пример кода в обработчике ПослеЗагрузкиОбъекта, который стал виновником сбоя:


Если Объект.РайонныйКоэффициент < 1 ИЛИ Объект.РайонныйКоэффициент > 3 Тогда
    Объект.РайонныйКоэффициент = 1;
КонецЕсли;
    
Объект.ГоловнаяОрганизация = Объект.Ссылка;
    
Параметры.Вставить("Организация", Объект.Ссылка);

Поскольку в обычной версии БП 3.0 реквизитов РайонныйКоэффициент и ГоловнаяОрганизация нет, динамическая компиляция кода дает сбой. Выясним, как это можно исправить несколькими путями.

Способ 1: Адаптация кода под конкретную конфигурацию (простой вариант)

Если мы точно знаем, что обмен будет происходить только с ПРОФ-версией Бухгалтерии, мы можем просто убрать лишние проверки из правил конвертации. В конфигурации «Конвертация данных 2.1» нужно открыть ПКО «Организации», перейти в обработчик ПослеЗагрузкиОбъекта и оставить только безопасный код:

Параметры.Вставить("Организация", Объект.Ссылка);

После этого необходимо заново выгрузить правила обмена и повторить выгрузку/загрузку данных. Это быстрое и рабочее решение, которое применил автор вопроса.

Способ 2: Написание универсального и отказоустойчивого кода

Если правила переноса планируется использовать для разных версий Бухгалтерии 3.0 (и ПРОФ, и КОРП), удалять код нельзя. Проанализируем ситуацию: нам нужно сделать так, чтобы платформа игнорировала отсутствие реквизита. Сделаем это с помощью конструкции Попытка ... Исключение.

Перепишем алгоритм следующим образом:


Попытка
    // Блок отработает успешно только если реквизит существует (например, в КОРП)
    Если Объект.РайонныйКоэффициент < 1 ИЛИ Объект.РайонныйКоэффициент > 3 Тогда
        Объект.РайонныйКоэффициент = 1;
    КонецЕсли;
Исключение
    // Игнорируем ошибку для Базовой и ПРОФ версий
КонецПопытки;

Попытка
    Объект.ГоловнаяОрганизация = Объект.Ссылка;
Исключение
КонецПопытки;

Параметры.Вставить("Организация", Объект.Ссылка);

Также можно использовать более правильный подход программной проверки наличия реквизита через метаданные объекта:


Если Объект.Метаданные().Реквизиты.Найти("РайонныйКоэффициент") <> Неопределено Тогда
    Если Объект.РайонныйКоэффициент < 1 ИЛИ Объект.РайонныйКоэффициент > 3 Тогда
        Объект.РайонныйКоэффициент = 1;
    КонецЕсли;
КонецЕсли;

Такой подход делает правила обмена по-настоящему универсальными.

Практический совет: Как удобно отлаживать такие ошибки?

Искать опечатку или скрытый спецсимвол, глядя в номер строки {(1,34)} внутри огромного универсального модуля обмена, крайне сложно. Выполним следующие действия для удобной отладки:

  1. Откроем базу с «Конвертацией данных 2.1».
  2. В форме настройки правил обмена найдем кнопку Сохранить модуль обработчиков выгрузки / загрузки.
  3. Сохраним обработчики в виде внешнего файла .epf.
  4. В базе-приемнике (БП 3.0), перед тем как нажать кнопку загрузки, укажем путь к этой внешней обработке на вкладке дополнительно или в настройках универсального обмена.

Теперь при загрузке 1С будет использовать не текстовые алгоритмы из XML, а откомпилированный модуль внешней обработки. Если произойдет ошибка, Конфигуратор остановится точно на проблемной строке кода, и вы сразу увидите, в каком именно месте алгоритм обращается к несуществующему реквизиту или содержит синтаксическую ошибку.

← На главную