Как заставить Конвертацию данных 2.1 корректно работать с объектами из расширений?

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

При использовании классического механизма Конвертации данных 2.1 (КД 2) программисты часто сталкиваются с неприятной особенностью: объекты, созданные в расширениях конфигурации, ведут себя «неправильно» при обмене — для этого подойдёт подсистема для настройки обмена по правилам Конвертации данных. Основная проблема проявляется в том, что при выгрузке данных через обработку УниверсальныйОбменДаннымиXML для новых справочников или документов из расширения не выгружается Уникальный Идентификатор (GUID). В результате при загрузке в базу-приемник возникают ошибки или создаются дубли, так как поиск по идентификатору становится невозможным.

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

Анализируем симптомы проблемы

Рассмотрим типичную ситуацию. Мы создали расширение и добавили в него новый справочник, например, GUD_АдресаМагазинов. Мы выгрузили структуру конфигурации с помощью MD83Exp.epf, настроили правила обмена в КД 2.1 и пытаемся выполнить выгрузку. Проанализируем содержимое сформированного XML-файла. Для обычного справочника из основной конфигурации узел объекта выглядит полноценно:


<Объект Тип="СправочникСсылка.Валюты" Имя="Валюты">
    <Ссылка>
        <Свойство Имя="{УникальныйИдентификатор}" Тип="Строка">
            <Значение>c0be710e-6e9e-11ef-835b-d23c2dac05d8</Значение>
        </Свойство>
    </Ссылка>
    ...
</Объект>

Однако для объекта из расширения картина меняется. В блоке <Ссылка> отсутствует свойство {УникальныйИдентификатор}, а вместо него выгружаются только поля поиска (Код или Наименование). При попытке загрузить такой файл обработка УниверсальныйОбменДаннымиXML выдает ошибку: «Ошибка при вызове конструктора (УникальныйИдентификатор) ... Недопустимое значение параметра». Это происходит потому, что загрузчик ожидает строку формата GUID, а получает пустое значение или некорректные данные.

Выясняем техническую причину: коварство метода ТипВсеСсылки

Проанализируем работу модуля объекта обработки УниверсальныйОбменДаннымиXML. В процессе выгрузки каждого объекта система должна определить: является ли текущее значение ссылочным типом? Если да — нужно извлечь его GUID. Для этого во многих версиях обработки используется вспомогательная функция ЗначениеСсылочногоТипа().

Посмотрим на типичную реализацию этой функции в старых версиях обработки:


Функция ЗначениеСсылочногоТипа(Значение)
    Тип = ТипЗнч(Значение);
    Возврат Тип <> Тип("Неопределено") 
        И (Справочники.ТипВсеСсылки().СодержитТип(Тип) 
        ИЛИ Документы.ТипВсеСсылки().СодержитТип(Тип) 
        ИЛИ Перечисления.ТипВсеСсылки().СодержитТип(Тип)
        ... );
КонецФункции

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

Таким образом, когда код обработки проверяет ссылку на справочник из расширения, функция ЗначениеСсылочногоТипа() возвращает Ложь. Система «думает», что перед ней не ссылка, а некий примитивный тип или структура, и пропускает шаг выгрузки Уникального Идентификатора.

Решение №1: Универсальное исправление кода обработки

Чтобы обработка корректно определяла типы из расширений независимо от режима совместимости, нам нужно изменить подход к проверке типа. Мы не будем полагаться на коллекции ТипВсеСсылки(), а воспользуемся глобальным методом поиска метаданных по типу.

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


Функция ЗначениеСсылочногоТипа(Значение)
    Перем Тип;
    Тип = ТипЗнч(Значение);
    
    // Используем поиск в метаданных, который видит и расширения
    ОбъектМетаданных = Метаданные.НайтиПоТипу(Тип);
    
    Если ОбъектМетаданных = Неопределено Тогда
        Возврат Ложь;
    КонецЕсли;
    
    // Проверяем, относится ли найденный объект к ссылочным типам
    ИмяИерархии = ОбъектМетаданных.ПолноеИмя();
    Если СтрНайти(ИмяИерархии, "Справочник.") > 0 
        Или СтрНайти(ИмяИерархии, "Документ.") > 0 
        Или СтрНайти(ИмяИерархии, "ПланВидовХарактеристик.") > 0 
        Или СтрНайти(ИмяИерархии, "ПланСчетов.") > 0 
        Или СтрНайти(ИмяИерархии, "ПланВидовРасчета.") > 0 
        Или СтрНайти(ИмяИерархии, "Перечисление.") > 0 Тогда
        Возврат Истина;
    КонецЕсли;
    
    Возврат Ложь;
КонецФункции

Важный момент: использование Метаданные.НайтиПоТипу() гарантирует, что система найдет описание объекта, даже если он находится в расширении. После такой правки выгрузка начнет корректно определять GUID для расширенных объектов, и файл обмена станет валидным.

Решение №2: Использование актуальной платформы

Как мы уже выяснили, поведение коллекций ТипВсеСсылки было изменено в платформе версии 8.3.20. Если вы переведете конфигурацию (и основной проект, и расширение) на режим совместимости 8.3.20 или выше, то стандартная обработка может заработать без внесения правок в код. Однако это не всегда возможно в продуктивных системах, так как смена режима совместимости требует полного регрессионного тестирования всей базы.

Если же вы используете современную платформу (например, 8.3.25), но режим совместимости базы установлен как 8.3.16, вы все равно столкнетесь со «старым» поведением. В этом случае правка кода обработки остается единственным быстрым решением.

Рекомендации по выгрузке структуры (MD83Exp.epf)

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

  1. Запускайте обработку MD83Exp.epf непосредственно в той информационной базе, где подключены и активны ваши расширения.
  2. Убедитесь, что в именах объектов расширений используются префиксы (например, расш1_). Это поможет избежать конфликтов имен при сопоставлении в КД.
  3. В правилах обмена (ПКО) обязательно проверьте, что в качестве Имени типа источника и Имени типа приемника указаны полные имена с учетом расширения (например, СправочникСсылка.GUD_АдресаМагазинов).

Альтернативные способы переноса данных

Если задача переноса данных разовая и вы не хотите погружаться в отладку КД 2.1, проанализируем альтернативы:

Заключение

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

← На главную