Перенос данных из устаревших конфигураций в современные — всегда вызов для программиста 1С. Одним из классических сценариев является переход с Управления торговлей 11.1 на Управление торговлей 11.4 (или 11.5) с одновременным реинжинирингом структуры каталога. Переход от «плоского» справочника номенклатуры (когда каждая характеристика товара была отдельным элементом справочника) к полноценному использованию характеристик, управляемых свойствами и категориями, часто преподносит неприятные сюрпризы.
Один из таких сюрпризов — ситуация, когда после переноса данных с помощью Конвертации данных 2.1 дополнительные реквизиты перенеслись в базу-приемник, но ведут себя некорректно: они либо вообще не отображаются на управляемых формах карточки номенклатуры или характеристики, либо отображаются в списке как зачеркнутые и недоступны для редактирования.
В этой статье мы подробно разберем, почему возникает эта техническая коллизия в Библиотеке стандартных подсистем (БСП), как устроена механика связей дополнительных реквизитов и предоставим готовые инструменты для автоматического исправления этой проблемы.
Давайте проанализируем поведение управляемых форм БСП. В современных конфигурациях 1С (включая УТ 11.4) зачеркнутый шрифт у дополнительного реквизита на форме объекта означает строго определенное состояние базы данных: значение этого реквизита записано для данного объекта, но сам реквизит исключен из набора свойств, назначенного этому объекту (в нашем случае — виду номенклатуры или характеристике).
Для того чтобы управляемая форма корректно отрисовала поле ввода дополнительного реквизита, в системе должна строго соблюдаться трехсторонняя связь:
ДополнительныеРеквизитыИСведения у конкретного свойства должен быть заполнен реквизит НаборСвойств (это ссылка на элемент справочника НаборыДополнительныхРеквизитовИСведений).НаборыДополнительныхРеквизитовИСведений в табличной части ДополнительныеРеквизиты должна присутствовать строка, указывающая на это свойство (элемент вышеуказанного ПВХ).ХарактеристикиНоменклатуры) в его табличной части ДополнительныеРеквизиты должна быть строка, где колонка Свойство ссылается на элемент ПВХ, а колонка Значение содержит актуальную ссылку или примитивный тип.Если при переносе данных через КД 2.1 мы перенесли только свойства и значения, но забыли связать их с наборами свойств или допустили ошибку в иерархии справочника наборов, БСП считает эти свойства «чужими» для данного объекта и визуально зачеркивает их, блокируя редактирование.
Давайте выясним еще одну причину, из-за которой часто совершают ошибки при переносе. В справочнике НаборыДополнительныхРеквизитовИСведений существует жесткая иерархия. При этом в интерфейсе платформы 1С визуально как группы, так и элементы этого справочника могут отображаться абсолютно одинаковыми иконками (в виде папок). Это сбивает разработчиков с толку.
Например, папка «Номенклатура» или «Характеристики» — это предопределенные группы. Внутри них должны лежать элементы, у которых и заполняются табличные части. Если при переносе программно или через правила КД 2.1 вы создали элементы-наборы вне предопределенных групп или перепутали родительские связи, БСП просто не сможет сопоставить метаданные объектов с наборами реквизитов. Настройки отображения сломаются.
Рассмотрим, как можно быстро исправить уже перенесенные данные в базе УТ 11.4 без повторного запуска конвертации. Нам нужно решить две задачи:
ДополнительныеРеквизитыИСведения и справочником НаборыДополнительныхРеквизитовИСведений.Для этого мы можем написать и выполнить в базе-приемнике следующую программную обработку (код можно запустить через групповую обработку или внешнюю обработку в режиме предприятия):
// Шаг 1. Исправление иерархии наборов свойств
РодительХарактеристики = Справочники.НаборыДополнительныхРеквизитовИСведений.НайтиПоНаименованию("Характеристики", Истина);
Если ЗначениеЗаполнено(РодительХарактеристики) Тогда
// Найдем наш созданный набор, который ошибочно лег не туда
НаборОбъект = Справочники.НаборыДополнительныхРеквизитовИСведений.НайтиПоНаименованию("Характеристики номенклатуры (Общие)", Ложь).ПолучитьОбъект();
Если НаборОбъект <> Неопределено И НаборОбъект.Родитель <> РодительХарактеристики Тогда
НаборОбъект.Родитель = РодительХарактеристики;
НаборОбъект.Записать();
Сообщить("Родитель для набора характеристик успешно обновлен.");
КонецЕсли;
КонецЕсли;
// Шаг 2. Взаимное связывание ПВХ и Наборов Свойств
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ДополнительныеРеквизитыИСведения.Ссылка КАК Свойство,
| ДополнительныеРеквизитыИСведения.НаборСвойств КАК НаборСвойств
|ИЗ
| ПланВидовХарактеристик.ДополнительныеРеквизитыИСведения КАК ДополнительныеРеквизитыИСведения
|ГДЕ
| НЕ ДополнительныеРеквизитыИСведения.ЭтоГруппа";
РезультатЗапроса = Запрос.Выполнить();
Выборка = РезультатЗапроса.Выбрать();
Пока Выборка.Следующий() Цикл
Если НЕ ЗначениеЗаполнено(Выборка.НаборСвойств) Тогда
Продолжить; // Пропускаем свойства без указанного набора
КонецЕсли;
// Получаем объект Набора Свойств и проверяем, есть ли там наше свойство
НаборОбъект = Выборка.НаборСвойств.ПолучитьОбъект();
Если НаборОбъект <> Неопределено Тогда
СтрокаНайденногоСвойства = НаборОбъект.ДополнительныеРеквизиты.Найти(Выборка.Sвойство, "Свойство");
Если СтрокаНайденногоСвойства = Неопределено Тогда
НоваяСтрока = НаборОбъект.ДополнительныеРеквизиты.Добавить();
НоваяСтрока.Свойство = Выборка.Свойство;
// Установим по умолчанию видимость и доступность
НоваяСтрока.Доступен = Истина;
НоваяСтрока.Видимый = Истина;
Попытка
НаборОбъект.Записать();
Сообщить("Добавлено свойство " + Выборка.Свойство + " в набор " + НаборОбъект.Наименование);
Исключение
Сообщить("Ошибка при записи набора: " + ОписаниеОшибки());
КонецПопытки;
КонецЕсли;
КонецЕсли;
КонецЦикла;
Чтобы избежать подобных ручных правок при последующих итерациях выгрузки, давайте разберем, как правильно настроить ПКО (Правила конвертации объектов) в Конвертации данных 2.1.
Стандартный реквизит ТипЗначения у ПВХ ДополнительныеРеквизитыИСведения имеет тип ОписаниеТипов. Напрямую передать его XML-пакетом КД 2.1 не всегда может корректно, особенно если набор типов изменился в новой версии конфигурации.
Для правильного переноса настроим ПКС (Правило конвертации свойства) для реквизита ТипЗначения:
ТипЗначения.СтрокаТипов.
ТипыСвойства = Источник.ТипЗначения.Типы();
Значение = ЗначениеВСтрокуВнутр(ТипыСвойства);
Если ПараметрыОбъекта <> Неопределено И ПараметрыОбъекта.Свойство("СтрокаТипов") Тогда
Попытка
Объект.ТипЗначения = ЗначениеИзСтрокиВнутр(ПараметрыОбъекта["СтрокаТипов"]);
Исключение
// Резервный вариант, если типы конфигураций сильно различаются
Объект.ТипЗначения = Новый ОписаниеТипов("СправочникСсылка.ЗначенияСвойствОбъектов");
КонецПопытки;
КонецЕсли;
Когда мы сворачиваем плоский справочник в характеристики, у нас возникает необходимость на лету заполнить табличную часть ДополнительныеРеквизиты у новой номенклатуры или характеристики. В источнике (УТ 11.1) это были обычные реквизиты, а в приемнике (УТ 11.4) это строки табличной части.
Для этого используем механизм ПКГС (Правило конвертации группы свойств):
ДополнительныеРеквизиты.КоллекцияОбъектов:
КоллекцияОбъектов = Новый ТаблицаЗначений;
КоллекцияОбъектов.Колонки.Добавить("Свойство");
КоллекцияОбъектов.Колонки.Добавить("Значение");
КоллекцияОбъектов.Колонки.Добавить("ТекстоваяСтрока");
// Пример разбора старых реквизитов и записи их в свойства новой характеристики
Если ЗначениеЗаполнено(Источник.СтарыйРеквизитЦвет) Тогда
НоваяСтрока = КоллекцияОбъектов.Добавить();
// Находим или сопоставляем ПВХ Свойство
НоваяСтрока.Свойство = НайтиСвойствоПоИмени("Цвет");
НоваяСтрока.Значение = ПолучитьЗначениеСвойства(Источник.СтарыйРеквизитЦвет, НоваяСтрока.Свойство);
КонецЕсли;
Вы можете перенести все связи абсолютно корректно, однако при открытии карточки номенклатуры свойства все равно могут не отобразиться сразу. Это происходит из-за кэширования механизмов БСП на стороне клиента и сервера управляемого приложения.
Чтобы принудительно заставить систему «увидеть» обновленные наборы свойств, рекомендуется запустить обработку группового изменения реквизитов после переноса и программно перезаписать ВидНоменклатуры у перенесенных позиций. При перезаписи сработают подписки на события БСП, которые автоматически обновят внутренние регистры сведений и кэш отображения реквизитов на формах.