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

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

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

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

Представим сценарий: в базе-источнике у справочника есть реквизиты НомерГТД и СрокГодности. В базе-приемнике нам нужно найти соответствующий элемент по номеру ГТД и обновить только дату срока годности. Проблема заключается в том, что стандартная настройка ПКС (Правила конвертации свойств) по умолчанию перезаписывает все переданные поля. Если тип данных в источнике и приемнике различается (например, Ссылка против Строки), это неизбежно приводит к ошибкам при загрузке.

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

Шаг 1. Настройка ПКС для поиска по реквизиту

Для начала разберем, как указать системе, что идентификация объекта должна происходить по полю НомерГТД. В правиле конвертации объекта (ПКО) на вкладке «Конвертация свойств» находим соответствующее ПКС.

  1. Установите флаг «Поиск» для реквизита НомерГТД. Это заставит систему включить данное поле в WHERE-запрос при поиске существующего объекта в приемнике.
  2. Чтобы само значение номера ГТД не перезаписывалось в приемнике при загрузке, перейдите в настройки этого ПКС и установите флаг «Не замещать значение свойства у существующих объектов в приемнике». Это гарантирует, что если объект найден, его номер останется нетронутым.

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

Шаг 2. Устранение ошибки «Значение не является значением объектного типа (ИмяТипа)»

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

Выясним причину: когда у ПКС указано правило конвертации, система ожидает увидеть в файле обмена структуру объекта (с УИД, типом и т.д.). Если приемник — строка, возникает конфликт типов. Чтобы этого избежать, выполните следующие действия:

  1. В ПКС для реквизита НомерГТД полностью очистите поле «Правило конвертации». Если ПКО не указано, КД передает данные как простой тип.
  2. В обработчике «Перед выгрузкой» для этого ПКС явно укажите, какое строковое значение должно быть передано. Проанализируем пример кода:

// Если НомерГТД в источнике — это ссылка на справочник НомераГТД
// Нам нужно передать именно строковое представление (Код или Наименование)
Значение = Строка(Источник.НомерГТД); 
// Или, если номер хранится в коде справочника:
Значение = Источник.НомерГТД.Код;

Таким образом, мы передаем в XML обычную строку, которую база-приемник легко сопоставит со своим строковым реквизитом.

Шаг 3. Использование обработчика «ПоляПоиска» для сложной логики

Иногда стандартного флажка «Поиск» недостаточно. Например, если поиск должен быть регистронезависимым или включать дополнительные условия. В таких случаях мы используем обработчик «ПоляПоиска» на уровне ПКО.

Рассмотрим, как это работает. В этом обработчике доступна коллекция СвойстваПоиска. Мы можем программно вмешаться в процесс:


// Пример модификации поиска
Если НомерВариантаПоиска = 1 Тогда
    // Проверяем, передано ли наше поле для поиска
    ГТД_Значение = СвойстваПоиска["НомерГТД"];
    
    Если ЗначениеЗаполнено(ГТД_Значение) Тогда
        // Здесь можно выполнить произвольный запрос к базе-приемнику
        Запрос = Новый Запрос;
        Запрос.Текст = "ВЫБРАТЬ Ссылка ИЗ Справочник.Номенклатура ГДЕ НомерГТД = &НомерГТД";
        Запрос.УстановитьПараметр("НомерГТД", ГТД_Значение);
        
        Результат = Запрос.Выполнить();
        Если Не Результат.Пустой() Тогда
            Выборка = Результат.Выбрать();
            Выборка.Следующий();
            СсылкаНаОбъект = Выборка.Ссылка; // Объект найден!
        КонецЕсли;
    КонецЕсли;
КонецЕсли;

Использование этого метода позволяет реализовать практически любую логику сопоставления объектов, включая поиск по части строки или сложным алгоритмам.

Шаг 4. Предотвращение дублирования данных

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

Чтобы этого не произошло, в настройках ПКО на закладке «Настройки» обязательно установите флаг «Не создавать новых объектов при поиске». В этом случае, если поиск по НомерГТД не даст результатов, загрузка этого конкретного объекта будет пропущена, и лишние элементы в справочнике не появятся.

Итоги и рекомендации

Подводя итог, для успешного решения задачи «поиск по одному полю, обновление другого» нам необходимо:

Соблюдение этих правил позволит вам создавать надежные и эффективные правила обмена, минимизируя риск возникновения ошибок типа Значение не является значением объектного типа и предотвращая порчу данных в базе-приемнике.

← На главную