Как исправить ошибку, если при конвертации данных справочники загрузились как элементы вместо групп (ЭтоГруппа)?

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

При настройке правил обмена в конфигурации «Конвертация данных 2» (КД 2) разработчики иногда допускают критическую ошибку — забывают сопоставить стандартный реквизит ЭтоГруппа для иерархических справочников. В результате первой загрузки папки из базы-источника создаются в базе-приемнике как обычные элементы.

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

Выясняем причину: почему повторная загрузка не помогает?

Для того чтобы понять, почему обновленные правила обмена игнорируют признак группы при повторной загрузке, обратимся к объектной модели платформы 1С. Свойство ЭтоГруппа (в англоязычном варианте IsFolder) для объектов справочников имеет статус «Только чтение».

При чтении XML-файла позиционирование и создание объектов происходит по следующему алгоритму:

  1. Загрузчик пытается найти объект в базе-приемнике по уникальному идентификатору (GUID).
  2. Если объект не найден, система проверяет входящее свойство ЭтоГруппа. Если оно равно Истина, вызывается метод СоздатьГруппу(), если Ложь — метод СоздатьЭлемент().
  3. Если объект найден, система просто считывает его из базы данных для обновления реквизитов. В этот момент тип объекта (элемент или группа) уже жестко определен в базе данных. Попытка перезаписать свойство ЭтоГруппа игнорируется платформой на уровне ядра, так как у существующего объекта класса СправочникОбъект изменить этот признак напрямую невозможно. Программа не выдает ошибку, но тихо пропускает это поле, оставляя объект элементом.

Таким образом, просто «накатить» правильные правила поверх ошибочно загруженных данных не получится. Нам придется применить специальные технические приемы.

Рассмотрим подробнее три основных сценария решения этой проблемы.

---

Способ 1. Программное пересоздание объектов через GUID (Универсальный метод)

Этот способ подходит как для файловых, так и для клиент-серверных информационных баз. Суть метода заключается в том, что мы временно удаляем ошибочный элемент и тут же создаем на его месте группу с точно таким же Уникальным Идентификатором (GUID). Благодаря сохранению GUID все существующие ссылки в документах, регистрах и других справочниках не «слетят» и продолжат корректно указывать на созданную группу.

Проанализируем алгоритм работы специальной обработки, которую необходимо написать:

  1. Находим все элементы справочника, которые ошибочно созданы как элементы, но должны быть группами. Отличить их можно, например, по наличию подчиненных элементов или сверив их со списком из базы-источника.
  2. Для каждого ошибочного элемента считываем его текущие реквизиты: Код, Наименование, Родитель и сам УникальныйИдентификатор.
  3. Выполняем непосредственное удаление элемента из базы данных с помощью метода Удалить().
  4. Создаем новую группу, устанавливаем ей сохраненный GUID, заполняем реквизиты и записываем в режиме загрузки данных.

Ниже представлен пример программного кода для реализации этого сценария. Этот код можно использовать во внешней обработке:


Выборка = Справочники.Номенклатура.Выбрать();
Пока Выборка.Следующий() Цикл
    
    // Определяем условие, по которому объект должен стать группой
    // Например, мы передали список ГУИДов или сверяем по какому-то признаку
    Если НеобходимаКонвертацияВГруппу(Выборка.Ссылка) Тогда
        
        СсылкаНаОбъект = Выборка.Ссылка;
        СтарыйGUID      = СсылкаНаОбъект.УникальныйИдентификатор();
        
        // Сохраняем значения ключевых реквизитов
        СтруктураСвойств = Новый Структура;
        СтруктураСвойств.Вставить("Код", Выборка.Код);
        СтруктураСвойств.Вставить("Наименование", Выборка.Наименование);
        СтруктураСвойств.Вставить("Родитель", Выборка.Родитель);
        
        // 1. Физически удаляем ошибочный элемент из базы данных.
        // Используем ОбменДанными.Загрузка = Истина, чтобы обойти проверки ссылочной целостности
        ОбъектЭлемента = СсылкаНаОбъект.ПолучитьОбъект();
        ОбъектЭлемента.ОбменДанными.Загрузка = Истина;
        Попытка
            ОбъектЭлемента.Удалить();
        Исключение
            ЗаписьЖурналаРегистрации("Конвертация", УровеньЖурналаРегистрации.Ошибка,,, 
                "Не удалось удалить элемент: " + ОписаниеОшибки());
            Продолжить;
        КонецПопытки;
        
        // 2. Создаем группу с точно таким же уникальным идентификатором
        НоваяСсылка = Справочники.Номенклатура.ПолучитьСсылку(СтарыйGUID);
        НоваяГруппа = Справочники.Номенклатура.СоздатьГруппу();
        НоваяГруппа.УстановитьСсылкуНового(НоваяСсылка);
        
        // Заполняем свойства
        ЗаполнитьЗначенияСвойств(НоваяГруппа, СтруктураСвойств);
        
        // Записываем группу в режиме обмена данными
        НоваяГруппа.ОбменДанными.Загрузка = Истина;
        Попытка
            НоваяГруппа.Записать();
        Исключение
            ЗаписьЖурналаРегистрации("Конвертация", УровеньЖурналаРегистрации.Ошибка,,, 
                "Не удалось записать новую группу: " + ОписаниеОшибки());
        КонецПопытки;
        
    КонецЕсли;
    
КонецЦикла;

Важное примечание: Использование свойства ОбменДанными.Загрузка = Истина является критически важным. Без этого флага платформа заблокирует удаление элемента, если на него уже ссылаются другие объекты (например, проведенные документы), и выбросит исключение.

---

Способ 2. Прямое исправление в СУБД через SQL (Для клиент-серверных баз)

Если ваша база данных работает под управлением MS SQL Server, PostgreSQL или другой СУБД, у вас есть возможность исправить признак ЭтоГруппа мгновенно для любого количества объектов, избежав долгого процесса удаления и создания. Это самый быстрый и безопасный способ с точки зрения сохранения целостности транзакций.

На уровне таблиц СУБД признак группы хранится в бинарном виде в специальной колонке. Разберем логику хранения:

Для исправления ситуации нам достаточно изменить значение в колонке _Folder с 0 на 1 для списка нужных идентификаторов объектов. Схематично SQL-запрос обновления выглядит следующим образом:


-- ПРИМЕР ДЛЯ MS SQL SERVER
-- Предварительно необходимо перевести ГУИДы 1С в бинарный формат SQL (с учетом перестановки байт)
UPDATE _Reference123 
SET _Folder = 0x01 
WHERE _IDRRef IN (0x80E800155D050B0111E29BCF2E3A0B66, 0x80E800155D050B0111E29BCF2E3A0B67);

ВНИМАНИЕ! КРАТЧАЙШИЙ ПУТЬ К ПОВРЕЖДЕНИЮ БАЗЫ ДАННЫХ: Прямая запись в СУБД обходит бизнес-логику платформы «1С:Предприятие». После выполнения подобного запроса обязательно выполните следующие действия:

  1. Очистите кэш сервера 1С и кэш клиентов. Платформа кэширует типы объектов, и если не сбросить кэш, система продолжит воспринимать измененные записи как элементы, что приведет к непредсказуемым ошибкам динамического обновления.
  2. Запустите «Тестирование и исправление» (ТиИ) в Конфигураторе 1С. Выберите пункты «Проверка логической целостности» и «Реиндексация таблиц информационной базы». Это позволит платформе корректно перестроить индексы и иерархические связи в измененной таблице.

---

Способ 3. Полное удаление и повторная загрузка (Рекомендуется для пустых баз)

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

Выполните следующие шаги:

  1. С помощью стандартной обработки «Групповое изменение реквизитов» или написав простую обработку, пометьте на удаление все ошибочные элементы справочника.
  2. Запустите операцию «Удаление помеченных объектов» и полностью сотрите их из базы-приемника.
  3. Откройте правила конвертации объектов в конфигурации «Конвертация данных 2».
  4. Для правила конвертации свойств (ПКС) реквизита ЭтоГруппа обязательно установите флаг «Поиск».
  5. Сохраните новые правила обмена, обновите их в узлах обмена или обработке загрузки.
  6. Зарегистрируйте объекты справочника к перегрузке в базе-источнике и выполните обмен заново. Поскольку объектов в приемнике больше нет, платформа создаст их с нуля, вызвав метод СоздатьГруппу() для всех папок.

---

Как избежать подобных ошибок в КД 2 в будущем?

Чтобы больше не сталкиваться с проблемой «перепутавшихся» элементов и групп, придерживайтесь золотых стандартов настройки правил обмена в «Конвертации данных 2»:

Мы проанализировали причины блокировки изменения признака папки в 1С и разобрали три практических способа восстановления иерархии справочников. Выбирайте программный способ пересоздания по GUID для рабочих баз без прямого доступа к СУБД, используйте SQL-запросы для быстрой реанимации крупных серверных баз или прибегайте к полному перезапуску обмена, если данные еще не обросли транзакционной историей.

← На главную