Почему иерархия справочника "Номенклатура" переносится не полностью, а коды не сохраняются при конвертации из 1С 7.7 в 1С 8.3?

Программист 1С v8.3 (Управляемые формы) 1С:Управление торговлей Управленческий учет Торговля и дистрибуция
← На главную

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

Рассмотрим две ключевые проблемы, с которыми обычно сталкиваются при переносе номенклатуры:

  1. Неполный перенос иерархии: часть элементов попадает в правильные группы, а часть — в корневые или "пустые" папки.
  2. Код, сформированный и присутствующий в выгружаемом XML-файле, игнорируется при загрузке в 1С 8.3, и новые элементы создаются с пустым кодом.

1. Проблемы с переносом иерархии справочника "Номенклатура"

Когда мы переносим иерархический справочник, такой как "Номенклатура", крайне важно обеспечить правильное восстановление структуры групп и подгрупп. Если часть позиций переносится в некорректные или пустые папки, это почти всегда указывает на проблемы с идентификацией родительских элементов в процессе загрузки.

Причина 1: Неуникальность кодов в 1С 7.7 и некорректный поиск

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

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

Решение 1: Обеспечение уникальности кодов для поиска родителя

Для того чтобы иерархия была перенесена корректно, нам необходимо обеспечить уникальный идентификатор для поиска родительских элементов в 1С 8.3. Рассмотрим несколько подходов:

  1. Поиск по наименованию (для групп):

    Если наименования групп в 1С 7.7 гарантированно уникальны, мы можем использовать их для поиска родителя в 1С 8.3. В ПКО для элемента справочника, в свойстве "Родитель", мы указываем поиск не по коду, а по наименованию. Однако этот метод применим только в случае строгой уникальности наименований групп.

  2. Формирование уникального составного кода в 1С 7.7 перед выгрузкой:

    Это более надежный подход. Мы можем сформировать уникальный код для каждого элемента и группы в 1С 7.7 на этапе выгрузки. Один из вариантов – это создание составного кода, который включает код родителя и код самого элемента, тем самым обеспечивая уникальность хотя бы в пределах подчинения. Например, если у нас есть родительская группа с кодом "Г001" и элемент в ней с кодом "Т001", его составной код может быть "Г001Т001".

    Пример формирования такого кода в обработчике ПКО (например, в ПередВыгрузкой):

    
    Если Источник.ЭтоГруппа Тогда
        Значение = СокрЛП(ПолучитьЗначение(Источник, "Код")); // Для групп можно использовать только их код
    Иначе
        КодРодителя = "";
        Если ЗначениеЗаполнено(Источник.Родитель) Тогда
            КодРодителя = СокрЛП(ПолучитьЗначение(Источник.Родитель, "Код"));
        КонецЕсли;
        Значение = КодРодителя + СокрЛП(ПолучитьЗначение(Источник, "Код"));
    КонецЕсли;
    // Дополнительно можно привести к нужной длине и формату
    Значение = ПривестиНомерКДлине(Значение, 11); // Пример функции для приведения к длине
    

    Функция ПривестиНомерКДлине должна быть реализована в модуле правил конвертации и обеспечивать единообразное форматирование кода, например, дополняя его нулями до нужной длины.

  3. Использование уникального идентификатора (GUID/ID) элемента 7.7:

    Каждый элемент справочника в 1С 7.7 имеет внутренний уникальный идентификатор (GUID или ID). Это наиболее надежный способ обеспечить уникальность. Мы можем выгружать этот идентификатор из 7.7 (например, через Источник.УникальныйИдентификатор() или Источник.ID) и использовать его для формирования уникального строкового кода в 8.3. Этот код будет гарантированно уникальным для каждого элемента.

    После формирования уникального кода в 8.3, мы должны указать в ПКО для свойства "Родитель" поиск по этому уникальному коду. Также важно убедиться, что для ПКО групп справочника "Номенклатура" свойство "ЭтоГруппа" установлено в "Истина", чтобы группы не переносились как обычные элементы.

2. Проблемы с записью кодов в 1С 8.3 после конвертации

Ситуация, когда код присутствует в XML-файле, но в 1С 8.3 элементы создаются с пустым кодом, является одной из самых распространенных при конвертации. Это связано с фундаментальными различиями в обработке стандартных реквизитов платформами.

Причина 1: Некорректное маппирование стандартного реквизита "Код"

В 1С 8.3 "Код" и "Наименование" являются стандартными реквизитами справочников, которые имеют особое значение и обрабатываются платформой иначе, чем обычные реквизиты или свойства. Если в XML-файле код выгружается не как значение стандартного реквизита "Код", а как обычное свойство с именем "Код", 1С 8.3 проигнорирует его при загрузке.

Рассмотрим пример из обсуждения:


-<Свойство Тип="Строка" Имя="Код">
<Значение>С000000028</Значение>
</Свойство>

Такая структура XML говорит о том, что "Код" выгружен как произвольное свойство, а не как стандартный реквизит. Платформа 8.3 ожидает увидеть стандартный реквизит "Код" в другом месте и формате в XML, который формируется при корректном маппинге стандартных реквизитов в ПКО. Когда он не найден или некорректно представлен, поле "Код" в 8.3 остается пустым (или заполняется автонумерацией, если она включена).

Причина 2: Автонумерация в 1С 8.3

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

Решение 1 (рекомендуемое): Перенос старого кода 7.7 в дополнительный реквизит 8.3

Это наиболее гибкий и безопасный способ работы с кодами при конвертации. Мы сохраняем историческую информацию, не нарушая логику 1С 8.3.

  1. Создайте дополнительный реквизит в 1С 8.3:

    В конфигурации 1С 8.3 добавьте новый строковый реквизит к справочнику "Номенклатура", например, с именем КодИз77, СтарыйКод или КодИСходнойБазы. Длина этого реквизита должна быть достаточной для хранения самых длинных кодов из 1С 7.7.

  2. Настройте ПКО для переноса кода:

    В правилах конвертации данных (КД), в ПКО для справочника "Номенклатура", настройте маппинг реквизита "Код" из 1С 7.7 на ваш новый реквизит КодИз77 в 1С 8.3.

  3. Оставьте стандартный код 8.3 для автонумерации:

    Для стандартного реквизита "Код" в 1С 8.3 мы оставляем включенной автонумерацию. Это позволяет системе 8.3 самостоятельно генерировать уникальные и корректные коды в соответствии со своей внутренней логикой. Эти коды обычно короче и имеют более строгий формат (например, 9 цифр).

  4. Используйте КодИз77 для поиска (при необходимости):

    Если вам требуется искать элементы номенклатуры по старому коду из 7.7 (например, при повторных загрузках или привязке связанных объектов), вы можете установить флажок "Поиск" для реквизита КодИз77 в ПКО свойства.

Преимущества этого подхода:

Решение 2: Передача уникального кода 7.7 непосредственно в стандартный реквизит "Код" 8.3

Этот подход сложнее и менее гибок, но иногда может потребоваться, если бизнес-логика жестко привязана к старым кодам 7.7 как к основным в 8.3.

  1. Обеспечение полной уникальности кода в 7.7:

    Прежде чем пытаться передать код из 7.7 в стандартный реквизит "Код" 8.3, вы должны абсолютно гарантировать его уникальность. Это может потребовать предварительной обработки данных в 7.7 или формирования очень сложного составного кода (например, на основе GUID или комбинации нескольких реквизитов), чтобы избежать конфликтов. Например:

    
    Если Источник.ЭтоГруппа Тогда
        Значение = СокрЛП(ПолучитьЗначение(Источник, "Код"));
    Иначе
        // Пример формирования уникального кода, используя GUID
        Значение = СтрЗаменить(Строка(Источник.УникальныйИдентификатор()), "-", ""); // Удаляем дефисы для чистоты
    КонецЕсли;
    // Приводим к нужной длине и формату, если необходимо.
    // В 8.3 стандартная длина кода 9-11 символов.
    Значение = Лев(Значение, 11);
    
  2. Корректное маппирование в ПКО:

    Убедитесь, что в ПКО для справочника "Номенклатура" вы маппируете исходный реквизит "Код" (или ваше сформированное уникальное значение) напрямую на стандартный реквизит "Код" приемника.

  3. Отключение автонумерации в 8.3 (или её временное игнорирование):

    В некоторых случаях может потребоваться временно отключить автонумерацию для справочника "Номенклатура" в конфигурации 8.3 перед загрузкой, а затем включить ее обратно. Однако это не всегда рекомендуется, так как может повлиять на другие механизмы платформы. Более предпочтительно, если КД позволяет явно указать, что код должен быть установлен из входящих данных, игнорируя автонумерацию.

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

Важное замечание: Несмотря на то, что в 1С 8.3 код не всегда активно используется в бизнес-логике (чаще используется ссылка или УИД), он остается видимым на форме элемента и может быть использован для поиска пользователями.

3. Общие рекомендации и подготовка к конвертации

Для успешной конвертации справочников, помимо решения специфических проблем с иерархией и кодами, мы должны выполнить ряд общих подготовительных действий:

Подготовка базы 1С 7.7

Перед началом процесса конвертации критически важно подготовить исходную базу 1С 7.7:

  1. Проверка целостности базы: Выполните стандартную проверку и исправление ошибок базы данных 7.7 (например, через утилиту chdbfl.exe для файловых баз). Это поможет избежать переноса поврежденных данных.

  2. Удаление помеченных на удаление объектов: Все объекты, помеченные на удаление, рекомендуется окончательно удалить из 7.7 до выгрузки. Это уменьшит объем переносимых данных и предотвратит перенос "мусорных" элементов в 8.3.

  3. Аудит данных: По возможности проведите аудит данных в 7.7 на предмет явных дубликатов, некорректных наименований или кодов, которые могут усложнить конвертацию.

Настройка ПКО для иерархии

Для корректного переноса иерархии в "Конвертации данных" (КД) мы должны внимательно настроить правила:

  1. Свойство "Родитель": В ПКО для элемента справочника "Номенклатура" (приемника) обязательно должно быть настроено правило для свойства "Родитель". Это правило должно указывать на соответствующее ПКО для групп справочника "Номенклатура" (источника).

  2. Свойство "ЭтоГруппа": Для ПКО групп справочника "Номенклатура" важно, чтобы свойство "ЭтоГруппа" было явно установлено в "Истина". Если оно будет "Ложь", то группы будут перенесены как обычные элементы, и иерархия не будет отображаться.

  3. Обработчики "После загрузки": В обработчике "После загрузки" ПКО справочника "Номенклатура" можно прописать дополнительную логику для установки родителя. Например, если родительский элемент не был найден (что может произойти при сложных иерархиях или некорректных данных), мы можем назначить элементу фиксированного родителя (например, корневую группу "Прочие" или "Неопределено").

Использование обработчиков в ПКО

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

Отладка правил конвертации

В процессе разработки правил конвертации мы неизбежно сталкиваемся с ошибками и неожиданным поведением. Для эффективной отладки мы можем использовать режим отладки обработчиков, доступный в универсальной обработке обмена данными. Это позволяет пошагово просматривать выполнение кода в обработчиках ПКО, анализировать значения переменных и выявлять причины проблем.

Таким образом, для успешной конвертации справочника "Номенклатура" из 1С 7.7 в 1С 8.3 мы должны системно подойти к решению проблем: обеспечить уникальность идентификаторов для построения иерархии, корректно маппировать коды с учетом особенностей 8.3 (предпочтительно в отдельный реквизит) и тщательно подготовить данные в исходной базе.

← На главную