Как загрузить произвольный текст в справочник Номенклатура при обмене через Конвертацию данных 2.1?

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

При настройке обмена данными между конфигурациями «Управление торговлей 10.3» (УТ 10) и «Бухгалтерия предприятия 3.0» (БП 3.0) разработчики часто сталкиваются со специфическими требованиями бизнеса. Одно из наиболее распространенных требований — трансформация данных при переносе документов. Например, при переносе документа «Счет на оплату» необходимо передать номенклатуру, наименование которой должно формироваться динамически на основе нескольких реквизитов источника: родительской группы номенклатуры, самого наименования, свойств его характеристики и размера из табличной части документа.

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

В этой статье мы подробно разберем, почему возникает эта ошибка, и рассмотрим два надежных варианта решения проблемы: классическую конвертацию «Строка в Справочник» через ПКО с пустым источником и передачу данных с помощью механизма исходящих и входящих данных.

Выясняем причину ошибки: почему падает выгрузка?

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


Ошибка получения значения свойства объекта (по имени свойства источника)
ПКО = Номенклатура (Справочник: Номенклатура)
ПКС = 2 (Наименование --> Наименование)
Объект = Куртки женские Куртка Какао 48 (Строка)
СвойствоПриемника = Наименование (Строка)
ОписаниеОшибки = Получение элемента по индексу для значения не определено

Проанализируем ситуацию. Данная ошибка возникает из-за того, что в Правилах конвертации свойств (ПКС) табличной части документа для свойства Номенклатура было указано стандартное ПКО, в котором Источник определен как справочник (ссылочный тип СправочникСсылка.Номенклатура).

Когда мы пишем произвольный код в обработчике «Перед выгрузкой» ПКС табличной части и присваиваем переменной Значение обычную строку (например, собранный текст с группой, размером и характеристикой), система КД 2.1 пытается применить к этой строке выбранное ПКО. На этапе обработки ПКС «Наименование» внутри этого ПКО движок конвертации пытается прочитать из источника его свойства. Физически это выглядит как обращение вида Источник.Наименование или Источник["Наименование"]. Но поскольку наш Источник в данный момент — это примитивный тип (обычная строка), попытка обратиться к нему по индексу или через точку вызывает критический сбой в модуле обработки обмена.

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

Вариант 1. Настройка конвертации «Строка -> Справочник» через ПКО с пустым источником

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

Шаг 1. Создание специального ПКО для Номенклатуры

  1. Перейдем в список ПКО и создадим новое правило (назовем его, например, Строка_В_Номенклатуру).
  2. Поле Источник обязательно оставляем пустым. Это ключевой момент, который сообщает системе, что на вход правила будет подаваться не объект базы данных, а произвольное значение (в нашем случае — строка).
  3. Поле Приемник заполняем как обычно: выбираем СправочникСсылка.Номенклатура.
  4. В табличной части ПКС этого ПКО добавляем только одну строку: Наименование -> Наименование. Поле «Источник» в этой строке ПКС также должно быть пустым.
  5. В ПКС «Наименование» открываем свойства и устанавливаем флаг «Поиск объекта при загрузке по свойству».
  6. В обработчике «Перед выгрузкой» этого ПКС «Наименование» пишем простой код: Значение = Источник; Примечание: Так как ПКО имеет пустой источник, переменная Источник при вызове правила будет содержать то значение, которое мы в него передали (нашу сформированную строку). Мы просто перенаправляем ее в выгружаемое значение наименования.

Шаг 2. Настройка ПКС в правиле конвертации документа

Теперь нам нужно настроить выгрузку табличной части «Товары» (или аналогичной) в документе «Счет на оплату».

  1. Открываем ПКО нашего документа («Счет на оплату») и переходим к правилам конвертации свойств табличной части.
  2. Находим ПКС Номенклатура.
  3. Очищаем поле «Источник» в этом ПКС, чтобы система не пыталась автоматически выгрузить ссылку на номенклатуру.
  4. В поле «Правило конвертации» явно указываем созданное на Шаге 1 правило Строка_В_Номенклатуру.
  5. Открываем обработчик «Перед выгрузкой» этого ПКС Номенклатура. Именно здесь мы будем динамически собирать наше уникальное наименование. Напишем следующий код:

// Получаем родительскую группу номенклатуры
РодительТекст = "";
Если ЗначениеЗаполнено(ОбъектКоллекции.Номенклатура.Родитель) Тогда
    РодительТекст = Строка(ОбъектКоллекции.Номенклатура.Родитель) + " ";
КонецЕсли;

// Получаем свойства характеристики (адаптируйте под ваши метаданные УТ 10)
ХарактеристикаТекст = "";
Если ЗначениеЗаполнено(ОбъектКоллекции.Характеристика) Тогда
    // Если свойства хранятся в дополнительных реквизитах характеристики
    // Для примера предположим получение текстовых представлений свойств
    Свойство1 = Строка(ОбъектКоллекции.Характеристика.Свойство1); 
    Свойство2 = Строка(ОбъектКоллекции.Характеристика.Свойство2);
    Если ЗначениеЗаполнено(Свойство1) Или ЗначениеЗаполнено(Свойство2) Тогда
        ХарактеристикаТекст = Свойство1 + " " + Свойство2 + " ";
    КонецЕсли;
КонецЕсли;

// Получаем значение размера из табличной части документа
РазмерТекст = "";
Если ЗначениеЗаполнено(ОбъектКоллекции.Размер) Тогда
    РазмерТекст = Строка(ОбъектКоллекции.Размер);
КонецЕсли;

// Собираем итоговую строку для поиска и создания номенклатуры в БП 3.0
Значение = СокрЛП(РодительТекст + Строка(ОбъектКоллекции.Номенклатура) + " " + ХарактеристикаТекст + РазмерТекст);

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

Вариант 2. Передача данных через ИсходящиеДанные (если нужны дополнительные реквизиты)

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

Для создания нового полноценного элемента номенклатуры в приемнике одной строки наименования недостаточно. Как минимум, потребуются такие реквизиты, как ЕдиницаИзмерения, СтавкаНДС, Услуга и другие обязательные поля. Передать этот комплекс данных из строки табличной части документа в ПКО номенклатуры нам поможет механизм ИсходящиеДанные.

Шаг 1. Передача структуры данных из ПКС документа

В ПКС Номенклатура табличной части документа в обработчике «Перед выгрузкой» мы инициализируем специальную структуру ИсходящиеДанные:


ИсходящиеДанные = Новый Структура;

// Собираем наше динамическое наименование
РодительТекст = ?(ЗначениеЗаполнено(ОбъектКоллекции.Номенклатура.Родитель), Строка(ОбъектКоллекции.Номенклатура.Родитель) + " ", "");
ХарактеристикаТекст = ?(ЗначениеЗаполнено(ОбъектКоллекции.Характеристика), Строка(ОбъектКоллекции.Характеристика) + " ", "");
РазмерТекст = ?(ЗначениеЗаполнено(ОбъектКоллекции.Размер), Строка(ОбъектКоллекции.Размер), "");

ИмяДляПоиска = СокрЛП(РодительТекст + Строка(ОбъектКоллекции.Номенклатура) + " " + ХарактеристикаТекст + РазмерТекст);

// Заполняем структуру передаваемых свойств
ИсходящиеДанные.Вставить("Наименование", ИмяДляПоиска);
ИсходящиеДанные.Вставить("НаименованиеПолное", ИмяДляПоиска);
ИсходящиеДанные.Вставить("БазоваяЕдиницаИзмерения", ОбъектКоллекции.Номенклатура.БазоваяЕдиницаИзмерения);
ИсходящиеДанные.Вставить("СтавкаНДС", ОбъектКоллекции.Номенклатура.СтавкаНДС);
// Поле Значение оставляем пустым или Неопределено, так как вся информация передается в структуре
Значение = Неопределено;

Шаг 2. Настройка ПКО для приема структуры данных

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

При такой настройке XML-выгрузка сформирует узел с набором свойств из структуры ИсходящиеДанные. При загрузке в БП 3.0 система сначала выполнит поиск номенклатуры по переданному значению наименования. Если элемент не будет найден, она автоматически создаст новый элемент и заполнит его всеми реквизитами, которые мы передали во входящих данных.

Настройка точного поиска в базе-приемнике (БП 3.0)

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

Для этого в ПКО номенклатуры откроем обработчик «Поля поиска» и напишем следующий алгоритм:


Если НомерВариантаПоиска = 1 Тогда
    // Исключаем лишние пробелы по краям строки поиска
    СтрокаПоиска = СокрЛП(СвойстваПоиска["Наименование"]);
    
    // Выполняем явный поиск по наименованию в базе БП
    НайденнаяСсылка = Справочники.Номенклатура.НайтиПоНаименованию(СтрокаПоиска, Истина);
    
    Если ЗначениеЗаполнено(НайденнаяСсылка) Тогда
        СсылкаНаОбъект = НайденнаяСсылка;
        ПрекратитьПоиск = Истина; // Прерываем дальнейшие стандартные попытки поиска
    КонецЕсли;
КонецЕсли;

Параметр Истина в методе НайтиПоНаименованию указывает системе на необходимость точного совпадения строки. Это исключит ситуации, когда, к примеру, «Куртка Какао» будет ошибочно сопоставлена с элементом «Куртка Какао демисезонная».

Также обратите внимание на настройку ПКО: флаг «Не создавать новые объекты в приемнике, если они не найдены» должен быть снят, если вы хотите, чтобы новые уникальные комбинации номенклатуры и характеристик автоматически создавались в БП 3.0 в процессе загрузки документов.

← На главную