Как избежать дублирования данных при загрузке XML в 1С, если в файле не указано имя правила?

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

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

Выясним причину проблемы: механизм работы «Конверсии данных 2.0»

Проанализируем ситуацию: когда мы используем типовую обработку Универсальный обмен данными в формате XML (V8Exch81.epf), система ожидает увидеть в теге Объект атрибут ИмяПравила. Этот атрибут указывает загрузчику, какое именно Правило Конвертации Объектов (ПКО) следует применить для обработки данных. В ПКО обычно прописаны ключевые поля поиска (например, Код, Артикул или Наименование) и логика синхронизации по внутренним идентификаторам (GUID).

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

Решение 1: Настройка правил обмена для поиска «по умолчанию»

Посмотрим на ситуацию с точки зрения настройки правил в конфигурации «Конверсия данных». Если мы не можем изменить выгрузку из внешней программы, мы должны подготовить 1С к приему «анонимных» объектов. Разберем по шагам, что необходимо сделать:

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

Проанализируем этот метод: даже если имя правила не указано в XML, при загрузке этих правил в обработку обмена, система будет пытаться применить их к соответствующим типам данных. Однако этот метод не всегда стабилен, если для одного типа метаданных создано несколько разных ПКО. Разобраться в тонкостях поведения таких алгоритмов помогут заметки по особенностям конвертации данных без поиска по внутреннему идентификатору.

Решение 2: Текстовая модификация XML-файла перед загрузкой

Если нам нужно быстрое решение без изменения программного кода 1С, мы можем воспользоваться методом «инъекции» недостающих данных прямо в файл выгрузки. Выясним, как автоматизировать этот процесс. Мы можем использовать любой текстовый редактор с поддержкой регулярных выражений, например, Notepad++.

Рассмотрим алгоритм замены:

  1. Откроем полученный из «АвтоДилера» файл XML.
  2. Вызовем окно поиска и замены (Ctrl+H) и включим режим регулярных выражений.
  3. В поле поиска введем шаблон, который находит пустые правила для конкретного типа:

Тип="СправочникСсылка.КлассификаторЕдиницИзмерения" ИмяПравила=""

  1. В поле замены пропишем то же самое, но с указанием имени правила, которое есть в наших правилах конвертации:

Тип="СправочникСсылка.КлассификаторЕдиницИзмерения" ИмяПравила="КлассификаторЕдиницИзмерения"

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

Решение 3: Программная обработка события «ПередЗагрузкойОбъекта»

Рассмотрим более продвинутый вариант, который подойдет для программистов. Мы можем вмешаться в процесс загрузки на лету. В самой обработке Универсальный обмен данными в формате XML или в модуле правил обмена (если мы используем КД 2.0) есть обработчик события ПередЗагрузкойОбъекта. Проанализируем пример кода, который поможет нам подменить правило:


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

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

Решение 4: Разбор файла через чтение XML (без использования КД)

Если файл от «АвтоДилера» слишком сильно отклоняется от стандартов 1С:Конверсия данных, наиболее надежным способом будет написание собственного загрузчика. Разберем, как это реализовать с помощью объекта ЧтениеXML. Посмотрим на пример упрощенного кода:


Чтение = Новый ЧтениеXML;
Чтение.ОткрытьФайл(ПутьКФайлу);

Пока Чтение.Прочитать() Цикл
    Если Чтение.ТипУзла = ТипУзлаXML.НачалоЭлемента И Чтение.Имя = "Объект" Тогда
        ТипОбъекта = Чтение.ПолучитьАтрибут("Тип");
        
        // Самостоятельная логика поиска объекта в базе
        Если ТипОбъекта = "СправочникСсылка.КлассификаторЕдиницИзмерения" Тогда
            Наименование = Чтение.ПолучитьАтрибут("Наименование");
            СсылкаНаОбъект = Справочники.КлассификаторЕдиницИзмерения.НайтиПоНаименованию(Наименование);
            
            Если СсылкаНаОбъект.Пустая() Тогда
                НовыйОбъект = Справочники.КлассификаторЕдиницИзмерения.СоздатьЭлемент();
                // Заполнение реквизитов...
                НовыйОбъект.Записать();
            КонецЕсли;
        КонецЕсли;
    КонецЕсли;
КонецЦикла;

Проанализируем ситуацию: этот метод полностью избавляет нас от зависимости от атрибута ИмяПравила. Мы сами контролируем, как искать объект (по коду, наименованию или другим реквизитам) и как его записывать. Это исключает проблему дублей из-за несовпадения GUID, так как мы полагаемся на бизнес-логику сопоставления, а не на внутренние идентификаторы систем.

Рекомендации по синхронизации

Выясним, какие дополнительные меры помогут избежать проблем при обмене данными:

Таким образом, мы рассмотрели все возможные пути решения проблемы. Выбор конкретного метода зависит от ваших навыков программирования и того, насколько часто вам приходится выполнять подобную загрузку. Совместное использование правильной настройки поиска в КД 2.0 и, при необходимости, текстовой правки файла — самый быстрый путь к корректному обмену данными без дублей.

← На главную