Как перенести значение из дополнительных реквизитов в обычный реквизит при конвертации данных

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

В процессе настройки обмена между базами 1С с помощью конфигурации «Конвертация данных 2.1» часто возникает задача преобразования данных. Типичный пример — когда в базе-источнике информация хранится в виде дополнительных реквизитов (которые технически являются строками табличной части ДополнительныеРеквизиты), а в базе-приемнике для этой же информации предусмотрен отдельный физический реквизит. В данной статье мы подробно разберем, как правильно реализовать такую выгрузку.

Постановка задачи

Рассмотрим ситуацию на примере справочника Номенклатура. В источнике у объекта есть табличная часть ДополнительныеРеквизиты. Нам нужно найти в этой ТЧ строку, где свойством является «КлассТМЦ», и передать значение этого свойства в реквизит объекта-приемника КлассТМЦ. Основная сложность заключается в том, что стандартное сопоставление полей здесь не работает, так как структура хранения данных принципиально различается.

Решение 1: Обработчик «Перед выгрузкой» в ПКС (Простой перебор)

Самый надежный и понятный способ — написать алгоритм поиска значения непосредственно в правиле конвертации свойства (ПКС). Разберем этот процесс по шагам:

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

Для Каждого СтрокаТЧ Из Источник.ДополнительныеРеквизиты Цикл
    // Проверяем наименование свойства. 
    // Вместо наименования лучше использовать уникальный идентификатор или код, если это возможно.
    Если СтрокаТЧ.Свойство.Наименование = "КлассТМЦ" Тогда
        Значение = СтрокаТЧ.Значение;
        Прервать;
    КонецЕсли;
КонецЦикла;

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

Решение 2: Использование функций БСП (Библиотека стандартных подсистем)

Если ваша база-источник построена на современных версиях типовых конфигураций (например, УТ 11, ERP или БП 3.0), то в ней, скорее всего, интегрирована БСП. Мы можем воспользоваться встроенными функциями, чтобы сделать код более компактным и быстрым. Проанализируем, как это выглядит:


// Сначала находим ссылку на само свойство (ПланВидовХарактеристик)
СвойствоСсылка = ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.НайтиПоНаименованию("КлассТМЦ");

Если Не СвойствоСсылка.Пустая() Тогда
    // Используем штатную функцию БСП для получения значения
    Значение = УправлениеСвойствами.ЗначениеСвойства(Источник, СвойствоСсылка);
КонецЕсли;

Данный подход хорош тем, что функция УправлениеСвойствами.ЗначениеСвойства уже оптимизирована и учитывает особенности хранения данных в различных версиях платформы.

Решение 3: Оптимизация через «Входящие данные»

Представьте ситуацию, когда вам нужно выгрузить не один, а сразу пять или десять дополнительных реквизитов в разные поля приемника. Если для каждого ПКС писать цикл обхода ТЧ, производительность выгрузки сильно упадет, так как табличная часть будет перечитываться многократно для каждого объекта номенклатуры. Выясним, как оптимизировать этот процесс с помощью механизма ВходящиеДанные.

Шаг 1: В ПКО справочника Номенклатура в обработчике Перед выгрузкой соберите все данные в структуру:


ВходящиеДанные = Новый Структура;
Для Каждого СтрокаТЧ Из Источник.ДополнительныеРеквизиты Цикл
    Если СтрокаТЧ.Свойство.Наименование = "КлассТМЦ" Тогда
        ВходящиеДанные.Вставить("КлассТМЦ", СтрокаТЧ.Значение);
    ИначеЕсли СтрокаТЧ.Свойство.Наименование = "Производитель" Тогда
        ВходящиеДанные.Вставить("Производитель", СтрокаТЧ.Значение);
    КонецЕсли;
КонецЦикла;

Шаг 2: В настройках ПКС для соответствующих реквизитов установите флаг «Получать из входящих данных». В этом случае КД сама возьмет значение из структуры по имени ключа, и нам не придется писать код в каждом ПКС.

Важные замечания и типичные ошибки

Разберем типичную ошибку, которую часто допускают начинающие разработчики. Попытка обратиться к ТЧ по индексу, например, Источник.ДополнительныеРеквизиты[0].Значение, крайне опасна. Порядок строк в табличной части дополнительных реквизитов не гарантирован. Сегодня «КлассТМЦ» может быть первым в списке, а завтра — третьим. Проанализируем еще несколько важных моментов:

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

← На главную