Как исправить проблему зачеркнутых и отсутствующих дополнительных реквизитов при переходе с УТ 11.1 на УТ 11.4 через КД 2.1

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

Перенос данных из устаревших конфигураций в современные — всегда вызов для программиста 1С. Одним из классических сценариев является переход с Управления торговлей 11.1 на Управление торговлей 11.4 (или 11.5) с одновременным реинжинирингом структуры каталога. Переход от «плоского» справочника номенклатуры (когда каждая характеристика товара была отдельным элементом справочника) к полноценному использованию характеристик, управляемых свойствами и категориями, часто преподносит неприятные сюрпризы.

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

В этой статье мы подробно разберем, почему возникает эта техническая коллизия в Библиотеке стандартных подсистем (БСП), как устроена механика связей дополнительных реквизитов и предоставим готовые инструменты для автоматического исправления этой проблемы.

Почему дополнительные реквизиты отображаются зачеркнутыми?

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

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

  1. В плане видов характеристик (ПВХ) ДополнительныеРеквизитыИСведения у конкретного свойства должен быть заполнен реквизит НаборСвойств (это ссылка на элемент справочника НаборыДополнительныхРеквизитовИСведений).
  2. В справочнике НаборыДополнительныхРеквизитовИСведений в табличной части ДополнительныеРеквизиты должна присутствовать строка, указывающая на это свойство (элемент вышеуказанного ПВХ).
  3. В самом прикладном объекте (например, в элементе справочника ХарактеристикиНоменклатуры) в его табличной части ДополнительныеРеквизиты должна быть строка, где колонка Свойство ссылается на элемент ПВХ, а колонка Значение содержит актуальную ссылку или примитивный тип.

Если при переносе данных через КД 2.1 мы перенесли только свойства и значения, но забыли связать их с наборами свойств или допустили ошибку в иерархии справочника наборов, БСП считает эти свойства «чужими» для данного объекта и визуально зачеркивает их, блокируя редактирование.

Коварство справочника «Наборы дополнительных реквизитов и сведений»

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

Например, папка «Номенклатура» или «Характеристики» — это предопределенные группы. Внутри них должны лежать элементы, у которых и заполняются табличные части. Если при переносе программно или через правила КД 2.1 вы создали элементы-наборы вне предопределенных групп или перепутали родительские связи, БСП просто не сможет сопоставить метаданные объектов с наборами реквизитов. Настройки отображения сломаются.

Решение проблемы: Программное восстановление связей

Рассмотрим, как можно быстро исправить уже перенесенные данные в базе УТ 11.4 без повторного запуска конвертации. Нам нужно решить две задачи:

Для этого мы можем написать и выполнить в базе-приемнике следующую программную обработку (код можно запустить через групповую обработку или внешнюю обработку в режиме предприятия):


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

// Шаг 2. Взаимное связывание ПВХ и Наборов Свойств
Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |	ДополнительныеРеквизитыИСведения.Ссылка КАК Свойство,
    |	ДополнительныеРеквизитыИСведения.НаборСвойств КАК НаборСвойств
    |ИЗ
    |	ПланВидовХарактеристик.ДополнительныеРеквизитыИСведения КАК ДополнительныеРеквизитыИСведения
    |ГДЕ
    |	НЕ ДополнительныеРеквизитыИСведения.ЭтоГруппа";

РезультатЗапроса = Запрос.Выполнить();
Выборка = РезультатЗапроса.Выбрать();

Пока Выборка.Следующий() Цикл
    Если НЕ ЗначениеЗаполнено(Выборка.НаборСвойств) Тогда
        Продолжить; // Пропускаем свойства без указанного набора
    КонецЕсли;
    
    // Получаем объект Набора Свойств и проверяем, есть ли там наше свойство
    НаборОбъект = Выборка.НаборСвойств.ПолучитьОбъект();
    Если НаборОбъект <> Неопределено Тогда
        СтрокаНайденногоСвойства = НаборОбъект.ДополнительныеРеквизиты.Найти(Выборка.Sвойство, "Свойство");
        
        Если СтрокаНайденногоСвойства = Неопределено Тогда
            НоваяСтрока = НаборОбъект.ДополнительныеРеквизиты.Добавить();
            НоваяСтрока.Свойство = Выборка.Свойство;
            // Установим по умолчанию видимость и доступность
            НоваяСтрока.Доступен = Истина;
            НоваяСтрока.Видимый = Истина;
            
            Попытка
                НаборОбъект.Записать();
                Сообщить("Добавлено свойство " + Выборка.Свойство + " в набор " + НаборОбъект.Наименование);
            Исключение
                Сообщить("Ошибка при записи набора: " + ОписаниеОшибки());
            КонецПопытки;
        КонецЕсли;
    КонецЕсли;
КонецЦикла;

Как правильно настроить правила конвертации в КД 2.1?

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

Перенос сложного типа «ОписаниеТипов»

Стандартный реквизит ТипЗначения у ПВХ ДополнительныеРеквизитыИСведения имеет тип ОписаниеТипов. Напрямую передать его XML-пакетом КД 2.1 не всегда может корректно, особенно если набор типов изменился в новой версии конфигурации.

Для правильного переноса настроим ПКС (Правило конвертации свойства) для реквизита ТипЗначения:

  1. Создаем ПКС для свойства ТипЗначения.
  2. В поле «Получить из входящих данных» ставим флаг, а в качестве имени параметра передаем строку, например, СтрокаТипов.
  3. В обработчике Перед выгрузкой пишем код сериализации типов в строку:

ТипыСвойства = Источник.ТипЗначения.Типы();
Значение = ЗначениеВСтрокуВнутр(ТипыСвойства);
  1. В ПКО для ПВХ в обработчике При загрузке (или Перед записью) восстанавливаем описание типов из строки обратно:

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

Заполнение табличных частей при переносе объектов

Когда мы сворачиваем плоский справочник в характеристики, у нас возникает необходимость на лету заполнить табличную часть ДополнительныеРеквизиты у новой номенклатуры или характеристики. В источнике (УТ 11.1) это были обычные реквизиты, а в приемнике (УТ 11.4) это строки табличной части.

Для этого используем механизм ПКГС (Правило конвертации группы свойств):

  1. Создаем ПКГС, где Источник оставляем пустым, а Приемником указываем табличную часть ДополнительныеРеквизиты.
  2. В обработчике Перед обработкой этой группы свойств программно генерируем таблицу значений и помещаем ее в переменную КоллекцияОбъектов:

КоллекцияОбъектов = Новый ТаблицаЗначений;
КоллекцияОбъектов.Колонки.Добавить("Свойство");
КоллекцияОбъектов.Колонки.Добавить("Значение");
КоллекцияОбъектов.Колонки.Добавить("ТекстоваяСтрока");

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

Важный нюанс: Сброс кэша БСП после переноса

Вы можете перенести все связи абсолютно корректно, однако при открытии карточки номенклатуры свойства все равно могут не отобразиться сразу. Это происходит из-за кэширования механизмов БСП на стороне клиента и сервера управляемого приложения.

Чтобы принудительно заставить систему «увидеть» обновленные наборы свойств, рекомендуется запустить обработку группового изменения реквизитов после переноса и программно перезаписать ВидНоменклатуры у перенесенных позиций. При перезаписи сработают подписки на события БСП, которые автоматически обновят внутренние регистры сведений и кэш отображения реквизитов на формах.

← На главную