При работе с инструментом "Конвертация данных" в 1С мы часто сталкиваемся с необходимостью переноса справочников, имеющих иерархическую структуру, таких как справочник "Номенклатура". Одной из распространенных и достаточно сложной проблемой является дублирование родительских групп (папок) при повторных загрузках данных. Эта ситуация может привести к неверному представлению иерархии, появлению "пустых" дубликатов групп и общему беспорядку в данных.
Давайте вместе разберем эту проблему, проанализируем причины ее возникновения и предложим эффективные решения, основанные на лучших практиках настройки правил обмена.
Представим ситуацию: мы настроили правила переноса справочника "Номенклатура" и выполнили первую загрузку. Все элементы и группы встали на свои места, иерархия построилась корректно. Однако при повторной загрузке данных (например, для обновления информации или исправления ошибок) мы обнаруживаем, что вместо обновления существующих групп, система создает их дубликаты, которые могут появляться как вложенные, так и в корне справочника. При этом внутри этих дубликатов могут отсутствовать элементы номенклатуры, создавая пустые и ненужные папки.
Автор нашей темы столкнулся именно с такой проблемой. Он настроил Правило Конвертации Объектов (ПКО) для "Номенклатуры", установив поиск по UID (уникальному идентификатору) в первую очередь, а затем по полям: Номенклатура, ЭтоГруппа, Артикул, КодУТП (дополнительный реквизит). Несмотря на это, при повторной загрузке стали появляться дубликаты родительских папок, нарушая структуру:
Группа2-Группа3-Группа4.Группа3-Группа4 и Группа4.Это указывает на то, что система по какой-то причине не смогла однозначно идентифицировать уже существующие родительские группы и решила создать их заново.
Для корректного переноса иерархических справочников, таких как "Номенклатура", без создания дубликатов, нам необходимо тщательно подойти к настройке правил обмена. Разберем основные аспекты.
Одна из наиболее эффективных и общепринятых практик при работе с иерархическими справочниками – это создание двух отдельных правил конвертации объектов (ПКО):
Почему это так важно? Разделение ПКО позволяет нам более гибко настроить логику переноса и, что самое главное, логику поиска для каждого типа объектов. Группы и элементы имеют разную природу: группы служат для организации структуры, элементы – для хранения конкретных данных. Их уникальные признаки для поиска также могут отличаться.
Например, для элемента номенклатуры критически важен артикул, наименование, код. Для группы же важны наименование и ее родительская группа. Отдельные ПКО дают нам возможность задать специфические критерии поиска для каждого типа, минимизируя вероятность коллизий и дублирования.
Это критически важный шаг, который часто упускается из виду. Чтобы система "Конвертация данных" могла корректно находить уже существующие группы и правильно строить иерархию, нам необходимо установить флажок "Поиск" для следующих свойств в Правиле Конвертации Свойств (ПКС), особенно для ПКО, отвечающего за группы:
РодительЭтоГруппаКогда мы устанавливаем флажок "Поиск" для свойства Родитель, система при поиске группы будет учитывать не только ее собственные поля (например, наименование), но и ее родительскую группу. Это позволяет однозначно идентифицировать группы с одинаковыми наименованиями, но находящиеся в разных ветвях иерархии.
Установка флажка "Поиск" для свойства ЭтоГруппа гарантирует, что при поиске существующего объекта система будет различать группу и элемент. Если этот флажок не установлен, группа с определенным наименованием может быть ошибочно найдена как обычный элемент (или наоборот), что нарушит иерархию и приведет к созданию дубликатов.
Рекомендуем также проверить, как именно свойство ЭтоГруппа выгружается из базы-источника. Иногда может потребоваться обработчик "Перед выгрузкой" в ПКС для свойства ЭтоГруппа, чтобы явно указывать, является ли текущий объект группой или элементом, особенно если в конфигурациях-источнике и приемнике логика иерархии или определения типа объекта различается.
В "Конвертации данных" поиск по UID (Уникальному Идентификатору) является методом с наивысшим приоритетом. Если для ПКО установлен флажок "Искать по UID", то система в первую очередь попытается найти объект в базе-приемнике по его UID. Только в том случае, если объект с таким UID не найден, система переходит к поиску по полям, которые мы указали в правилах поиска.
Это означает, что если UID объектов в базах-источнике и приемнике совпадают (что идеально при перегрузке одних и тех же данных), то поиск по дополнительным полям вообще не будет использоваться для идентификации объекта. Однако, если UID не переносится, генерируется заново или базы изначально разные и UIDы не совпадают, то поля поиска становятся нашим основным механизмом идентификации.
Убедитесь, что UID выгружается из источника и загружается в приемник, если вы на него полагаетесь. В противном случае, уделите особое внимание настройке полей поиска.
Когда поиск по UID не применим или не обеспечивает достаточную уникальность, нам необходимо использовать набор полей, которые в совокупности однозначно идентифицируют объект. Условия поиска по нескольким полям объединяются логической операцией "И" (AND). То есть, объект будет найден только если все указанные поля поиска совпадают со значениями в источнике.
Автор темы предоставил пример использования вариантов поиска, который ему "вроде стало нормально грузиться". Давайте проанализируем его:
Если НомерВариантаПоиска = 1 Тогда
СтрокаИменСвойствПоиска = "Артикул, Наименование, КодУТП";
ИначеЕсли НомерВариантаПоиска = 2 Тогда
СтрокаИменСвойствПоиска = "Артикул, Наименование";
ИначеЕсли НомерВариантаПоиска = 3 Тогда
СтрокаИменСвойствПоиска = "Наименование, Родитель";
Иначе
СтрокаИменСвойствПоиска = "Наименование";
КонецЕсли;
Разберем каждый вариант:
Артикул, Наименование, КодУТП: Этот вариант является наиболее надежным, если все три поля являются уникальными для элементов номенклатуры. КодУТП, как дополнительный реквизит для кода из исходной базы, часто используется как надежный идентификатор.Артикул, Наименование: Используется как запасной вариант, если КодУТП отсутствует или не является уникальным в некоторых случаях.Наименование, Родитель: Этот вариант очень важен для групп. Он позволяет идентифицировать группу не только по ее наименованию, но и по ее родительской группе. Однако, как мы уже говорили, для корректной работы этого варианта обязательно должен быть установлен флажок "Поиск" для свойства Родитель в ПКС. Если свойство Родитель само еще не было корректно найдено или создано, это может привести к рекурсивным проблемам и созданию дубликатов родительских групп. Поэтому крайне важно, чтобы поиск родительских групп осуществлялся дочерними объектами.Наименование: Это самый "слабый" вариант поиска, используемый как последняя надежда. Он подходит только для объектов, наименование которых гарантированно уникально в рамках всего справочника, что редко бывает в случае номенклатуры. Его использование может легко привести к дубликатам или некорректному поиску.Рекомендации по вариантам поиска:
Наименование и Родитель. Если у групп есть уникальный идентификатор (например, тот же КодУТП), его также следует включить в приоритетный вариант поиска. Например: КодУТП, Наименование, Родитель.Артикул, Наименование, КодУТП. Если артикул может быть неуникальным или отсутствовать, КодУТП становится еще более важным.Как было предложено в одном из сообщений, просмотр выгруженного XML-файла является отличным диагностическим инструментом. Рекомендуем всегда анализировать XML-файл при возникновении проблем с конвертацией, особенно с иерархическими структурами.
Что мы ищем в XML:
ЭтоГруппа = Истина.СсылкаНаРодителя или подобный тег, который содержит UID родительской группы или ее уникальные поля.Анализ XML-файла поможет нам понять, на каком этапе происходит искажение информации о родителях – при выгрузке из базы-источника или при загрузке в базу-приемник.
На закладке "Конвертация свойств" в ПКО существует полезный флаг "Не замещать значение данного свойства у существующих объектов ИБ". Если мы установим этот флаг для определенного свойства (например, для Наименование или Родитель группы), то при нахождении объекта по UID или полям поиска, значение этого свойства в базе-приемнике не будет перезаписываться значением из источника.
Этот флаг может быть полезен, если вы хотите сохранить определенные значения в приемнике неизменными при повторных загрузках. Например, если наименование группы может быть изменено вручную в базе-приемнике и вы не хотите, чтобы оно перезаписывалось из источника. Однако для свойства Родитель обычно требуется, чтобы оно корректно обновлялось, чтобы поддерживать актуальную иерархию, поэтому используйте этот флаг осторожно.
Для того чтобы решить проблему с дублирующимися папками "Родители" при переносе справочника номенклатуры, мы рекомендуем следующие шаги:
Родитель и ЭтоГруппа.КодУТП, Наименование, Родитель. Убедитесь, что КодУТП выгружается для групп.Артикул, Наименование, КодУТП.ЭтоГруппа и ссылки на Родителя корректно формируются для всех объектов.UID в базах-источнике и приемнике отличаются или не переносятся, отключите "Искать по UID" и полностью полагайтесь на настроенные поля поиска, чтобы избежать непредсказуемого поведения. Или, наоборот, убедитесь, что UIDы переносятся корректно, если это ваш основной механизм поиска.Следуя этим рекомендациям, вы сможете значительно повысить надежность и корректность переноса иерархических справочников, избегая проблем с дублированием данных и поддерживая стройную структуру в вашей базе 1С.