Как программно добавить префикс к коду или номеру в «1С:Конвертация данных 2.0»?

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

При настройке правил обмена в конфигурации «Конвертация данных 2.0» (КД 2) разработчики часто сталкиваются с необходимостью модифицировать реквизиты объектов при выгрузке — например, добавить префикс узла или организации к коду справочника или номеру документа. Однако попытка изменить значение напрямую через свойства выгружаемого объекта приводит к ошибке выполнения. Разберем по шагам, почему возникает эта ошибка, как правильно передавать новое значение и как корректно управлять длиной номера с учетом лидирующих нулей.

Анализ ошибки: почему «Поле объекта недоступно для записи»?

Рассмотрим типичную ошибку начинающих разработчиков. В обработчиках событий уровня объекта (например, ПередВыгрузкойОбъекта или ПередВыгрузкойОбъектаВыборки в ПВД/ПКО) часто пытаются написать код следующего вида:


// Ошибочный вариант
Объект.Код = "ПР" + Объект.Код;

При выполнении обмена обработка «Универсальный обмен данными в формате XML» аварийно прерывает выгрузку со следующим сообщением:


Ошибка в обработчике события ПередВыгрузкойОбъекта
    ПВД            =  Контрагенты
    ОписаниеОшибки =  Поле объекта недоступно для записи (Код)

Выясним причину такого поведения платформы. В обработчиках выгрузки переменные Объект или Источник содержат ссылку на элемент (типы СправочникСсылка, ДокументСсылка) либо выборку из базы данных. Ссылочные типы в платформе 1С доступны исключительно для чтения. Прямое присвоение значения полям ссылки невозможно.

Важное предостережение: никогда не пытайтесь обойти эту ошибку через вызов метода Объект.ПолучитьОбъект() с последующей записью. Это грубейшая ошибка проектирования обмена, так как вы физически измените данные непосредственно в рабочей базе-источнике.

Корректный способ: использование обработчика ПККС

Проанализируем архитектуру правил конвертации. Чтобы изменить выгружаемое значение без модификации источника данных, платформе нужно передать результат вычисления в специальную переменную. Для этого правила конвертации свойств (ПККС) предоставляют предопределенный обработчик «Перед выгрузкой».

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

  1. Откроем нужное Правило конвертации объекта (ПКО), например, справочника «Контрагенты».
  2. Перейдем в табличную часть «Правила конвертации свойств» (ПККС).
  3. Найдем строку реквизита Код (или Номер для документов).
  4. Откроем обработчик события «Перед выгрузкой» для этого свойства.
  5. Зададим значение через специальную системную переменную Значение.

Значение = "ПР" + Источник.Код;

В этом контексте платформа возьмет значение поля из исходной ссылки Источник.Код, добавит строку префикса и поместит итоговый результат в переменную Значение, которая и уйдет в исходящий XML-файл.

Проблема переполнения длины кода и обрезки нулей

После добавления строкового префикса часто возникает сопутствующая проблема: длина реквизита Код ограничена метаданными приемника (например, ровно 9 символов). Если исходный код имел вид 000000154, то при простом сложении строк "ПР" + "000000154" мы получим 11 символов: ПР000000154.

При записи в приемнике платформа 1С автоматически обрежет строку справа под максимальную длину поля (9 символов). В итоге значащие цифры потеряются, и номер превратится в некорректный ПР0000001. Требуется сохранить значащие цифры, убрав лишние нули, чтобы получить, например, ПР0000154.

Рассмотрим простейший вариант решения, предложенный в обсуждении:

Значение = "ПР" + Сред(Источник.Код, 3);

Функция Сред(Источник.Код, 3) отсекает ровно 2 первых символа исходного кода, освобождая место под двухсимвольный префикс "ПР".

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

Универсальное выравнивание кода с учетом длины реквизита

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

Разберем пример реализации для обработчика ПККС «Перед выгрузкой»:


Префикс = "ПР";
ДлинаПоляПриемника = 9; // Длина кода в конфигурации-приемнике

// Получаем исходный код без пробелов
ИсходныйКод = СокрЛП(Источник.Код);

// Вычисляем доступную длину под цифровую часть
ДлинаНомера = ДлинаПоляПриемника - СтрДлина(Префикс);

Если ДлинаНомера > 0 Тогда
    // Удаляем лидирующие нули из исходного кода
    Позиция = 1;
    Пока Позиция <= СтрДлина(ИсходныйКод) И Сред(ИсходныйКод, Позиция, 1) = "0" Цикл
        Позиция = Позиция + 1;
    КонецЦикла;
    ЗначащаяЧасть = Сред(ИсходныйКод, Позиция);
    
    // Дополняем значащую часть нулями слева до нужной длины
    ФорматированныйНомер = Прав("000000000000" + ЗначащаяЧасть, ДлинаНомера);
    Значение = Префикс + ФорматированныйНомер;
Иначе
    Значение = Префикс + ИсходныйКод;
КонецЕсли;

Важные последствия модификации кода при обмене

Проанализируем архитектурные риски, о которых важно помнить перед внедрением модификации кодов:

  1. Нарушение полей поиска: если в ПКО для элемента справочника включен поиск по реквизиту Код, изменение кода при выгрузке приведет к тому, что существующий в базе-приемнике объект не будет найден. В результате при каждом обмене создадутся дубли. Если вы модифицируете код, настройте поиск по уникальному идентификатору (GUID) или другим полям (например, по реквизитам ИНН и КПП).
  2. Риск коллизий: искусственное уменьшение разрядности числовой части номера снижает диапазон доступных номеров и при плотном заполнении базы может привести к пересечению кодов.
  3. Альтернатива — префиксация в приемнике: нередко более правильным решением является отказ от изменения кода при выгрузке. Вместо этого в ПКО приемника в обработчике «ПослеЗагрузки» или «ПриЗагрузке» проверяют системный флаг Не СсылкаНайденная. Если объект действительно новый, префикс присваивается только ему, что гарантирует сохранение кодов у ранее синхронизированных элементов.
← На главную