При доработке или обслуживании крупных конфигураций (таких как 1С:Комплексная автоматизация или 1С:ERP) часто возникает задача масштабной замены ссылок одного справочника на другие. Стандартная обработка «Поиск и замена значений» отлично справляется с явными реквизитами. Однако, когда дело касается так называемых «скрытых» ссылок, она оказывается бессильна. Давайте разберем, где могут таиться такие неявные связи, и проанализируем алгоритмы их поиска и безопасной замены.
Скрытая ссылка — это ссылка, которая хранится не как явный типизированный реквизит в базе данных, а упакована внутри сложного объекта, сериализована в строку или спрятана глубоко в системных таблицах. Рассмотрим подробнее основные «потаенные места», на которые нужно обратить внимание.
ВариантыОтчетов или РассылкиОтчетов, есть реквизиты с типом ХранилищеЗначений. В них сохраняются настройки Системы Компоновки Данных (СКД), включая отборы по группам номенклатуры.ХранилищеСистемныхНастроек, ХранилищеОбщихНастроек, ХранилищеПользовательскихНастроекОтчетов и ХранилищеНастроекДанныхФорм. Именно здесь сохраняются пользовательские отборы динамических списков на формах.УсловияПредоставленияСкидокНаценок и ВидыЦен. Правила часто упакованы в схемы СКД внутри хранилищ значений или зашиты в текстовые запросы алгоритмов.ИсторияДанных хранят слепки объектов (в формате XML или JSON). В этих слепках остаются старые GUID-ы ссылок.ПубличныеИдентификаторыСинхронизируемыхОбъектов или СоответствияОбъектовИнформационныхБаз хранятся связи объектов. Замена ссылки без обновления этих регистров приведет к дублям при обмене.Алгоритмы) и настройки привязки дополнительных реквизитов к конкретным группам.Для начала проанализируем структуру базы на наличие реквизитов, которые могут указывать на группы справочника. Мы можем программно обойти все метаданные и проверить свойства реквизитов.
Для каждого справочника, документа или регистра мы формируем путь вида ОбъектМетаданных.Реквизит.Тип. Если тип реквизита соответствует искомому справочнику (например, СправочникСсылка.Номенклатура), мы должны проверить свойство «Выбор групп и элементов». Если там указано значение ГруппыИЭлементы или Группы — это потенциальное место использования нашей ссылки.
Самая сложная часть задачи — замена внутри типа ХранилищеЗначений. Извлечь данные методом Получить() недостаточно. Разберем по шагам, как построить надежный алгоритм:
Структура, Массив, СписокЗначений, НастройкиКомпоновкиДанных или ПользовательскиеНастройкиКомпоновкиДанных.ПараметрыДанных.Элементы и Отбор.Элементы.ХранилищеЗначений и записываем объект базы данных.Посмотрим на пример концептуального кода, который демонстрирует рекурсивный обход структуры:
Процедура ОбработатьКоллекцию(Коллекция, СтараяСсылка, НоваяСсылка, БылиИзменения)
ТипОбъекта = ТипЗнч(Коллекция);
Если ТипОбъекта = Тип("Структура") Или ТипОбъекта = Тип("Соответствие") Тогда
Для Каждого КлючИЗначение Из Коллекция Цикл
Если КлючИЗначение.Значение = СтараяСсылка Тогда
Коллекция.Вставить(КлючИЗначение.Ключ, НоваяСсылка);
БылиИзменения = Истина;
ИначеЕсли ТипЗнч(КлючИЗначение.Значение) = Тип("Массив")
Или ТипЗнч(КлючИЗначение.Значение) = Тип("Структура") Тогда
ОбработатьКоллекцию(КлючИЗначение.Значение, СтараяСсылка, НоваяСсылка, БылиИзменения);
КонецЕсли;
КонецЦикла;
ИначеЕсли ТипОбъекта = Тип("Массив") Тогда
Для Индекс = 0 По Коллекция.Количество() - 1 Цикл
Если Коллекция[Индекс] = СтараяСсылка Тогда
Коллекция[Индекс] = НоваяСсылка;
БылиИзменения = Истина;
ИначеЕсли ТипЗнч(Коллекция[Индекс]) = Тип("Массив")
Или ТипЗнч(Коллекция[Индекс]) = Тип("Структура") Тогда
ОбработатьКоллекцию(Коллекция[Индекс], СтараяСсылка, НоваяСсылка, БылиИзменения);
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецПроцедуры
Если ссылка спрятана в XML, JSON или строке с GUID, подход усложняется. Нам нужно проанализировать все реквизиты с типом Строка (длина которых позволяет вместить GUID) или ДвоичныеДанные.
При обнаружении таких данных мы пытаемся их интерпретировать: десериализовать XML/JSON в объект 1С, выполнить там рекурсивный перебор и замену (как описано выше), а затем сериализовать обратно. Либо применять строковые функции автозамены (например, СтрЗаменить для замены строкового представления старого GUID на новый в XML-документе), однако этот метод требует крайней осторожности, чтобы не повредить разметку.
Замена скрытых ссылок — это «хирургическое» вмешательство в структуру базы. Выясним, какие меры безопасности необходимо соблюдать:
ПубличныеИдентификаторыСинхронизируемыхОбъектов) и таблицы регистрации изменений планов обмена. Без их актуализации внешние системы перестанут понимать, о какой номенклатуре идет речь.