Как найти и заменить скрытые ссылки на группы справочника в 1С?

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

При доработке или обслуживании крупных конфигураций (таких как 1С:Комплексная автоматизация или 1С:ERP) часто возникает задача масштабной замены ссылок одного справочника на другие. Стандартная обработка «Поиск и замена значений» отлично справляется с явными реквизитами. Однако, когда дело касается так называемых «скрытых» ссылок, она оказывается бессильна. Давайте разберем, где могут таиться такие неявные связи, и проанализируем алгоритмы их поиска и безопасной замены.

Где могут прятаться скрытые ссылки?

Скрытая ссылка — это ссылка, которая хранится не как явный типизированный реквизит в базе данных, а упакована внутри сложного объекта, сериализована в строку или спрятана глубоко в системных таблицах. Рассмотрим подробнее основные «потаенные места», на которые нужно обратить внимание.

  1. Справочники настроек отчетов. В таких справочниках, как ВариантыОтчетов или РассылкиОтчетов, есть реквизиты с типом ХранилищеЗначений. В них сохраняются настройки Системы Компоновки Данных (СКД), включая отборы по группам номенклатуры.
  2. Платформенные хранилища системных настроек. Помимо обычных справочников, существуют скрытые платформенные таблицы: ХранилищеСистемныхНастроек, ХранилищеОбщихНастроек, ХранилищеПользовательскихНастроекОтчетов и ХранилищеНастроекДанныхФорм. Именно здесь сохраняются пользовательские отборы динамических списков на формах.
  3. Подсистема ценообразования и скидок. Ссылки на группы товаров могут массово фигурировать в справочниках УсловияПредоставленияСкидокНаценок и ВидыЦен. Правила часто упакованы в схемы СКД внутри хранилищ значений или зашиты в текстовые запросы алгоритмов.
  4. Параметры регламентных и фоновых заданий. Если настроен автоматический обмен или переоценка по конкретной группе товаров, ссылка на нее будет сериализована в массивах или структурах, выступающих параметрами фонового задания.
  5. Механизмы версионирования и история данных. Механизм БСП «Версионирование объектов» и встроенная платформенная ИсторияДанных хранят слепки объектов (в формате XML или JSON). В этих слепках остаются старые GUID-ы ссылок.
  6. Планы обмена и служебные регистры. В таблицах регистрации изменений и регистрах ПубличныеИдентификаторыСинхронизируемыхОбъектов или СоответствияОбъектовИнформационныхБаз хранятся связи объектов. Замена ссылки без обновления этих регистров приведет к дублям при обмене.
  7. Внешние обработки и присоединенные файлы. Внешние XML/JSON файлы, сохраненные как присоединенные файлы или настройки внешних обработок.
  8. Ограничения доступа (RLS). Настройки ограничения прав на уровне записей могут содержать прямые ссылки на группы доступа или объекты, к которым этот доступ предоставляется.
  9. Пользовательские алгоритмы и доп. реквизиты. Произвольные алгоритмы (справочник Алгоритмы) и настройки привязки дополнительных реквизитов к конкретным группам.

Механика поиска по метаданным

Для начала проанализируем структуру базы на наличие реквизитов, которые могут указывать на группы справочника. Мы можем программно обойти все метаданные и проверить свойства реквизитов.

Для каждого справочника, документа или регистра мы формируем путь вида ОбъектМетаданных.Реквизит.Тип. Если тип реквизита соответствует искомому справочнику (например, СправочникСсылка.Номенклатура), мы должны проверить свойство «Выбор групп и элементов». Если там указано значение ГруппыИЭлементы или Группы — это потенциальное место использования нашей ссылки.

Рекурсивный обход Хранилища Значений

Самая сложная часть задачи — замена внутри типа ХранилищеЗначений. Извлечь данные методом Получить() недостаточно. Разберем по шагам, как построить надежный алгоритм:

  1. Извлекаем содержимое хранилища.
  2. Определяем тип полученного объекта. Это может быть Структура, Массив, СписокЗначений, НастройкиКомпоновкиДанных или ПользовательскиеНастройкиКомпоновкиДанных.
  3. Если это коллекция (массив, структура), мы запускаем рекурсивный перебор всех ее элементов.
  4. Если это настройки СКД, мы обращаемся к коллекциям ПараметрыДанных.Элементы и Отбор.Элементы.
  5. Как только мы находим значение, равное старой ссылке, мы заменяем его на новую.
  6. После обработки упаковываем измененный объект обратно в ХранилищеЗначений и записываем объект базы данных.

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


Процедура ОбработатьКоллекцию(Коллекция, СтараяСсылка, НоваяСсылка, БылиИзменения)
    
    ТипОбъекта = ТипЗнч(Коллекция);
    
    Если ТипОбъекта = Тип("Структура") Или ТипОбъекта = Тип("Соответствие") Тогда
        Для Каждого КлючИЗначение Из Коллекция Цикл
            Если КлючИЗначение.Значение = СтараяСсылка Тогда
                Коллекция.Вставить(КлючИЗначение.Ключ, НоваяСсылка);
                БылиИзменения = Истина;
            ИначеЕсли ТипЗнч(КлючИЗначение.Значение) = Тип("Массив") 
                Или ТипЗнч(КлючИЗначение.Значение) = Тип("Структура") Тогда
                ОбработатьКоллекцию(КлючИЗначение.Значение, СтараяСсылка, НоваяСсылка, БылиИзменения);
            КонецЕсли;
        КонецЦикла;
        
    ИначеЕсли ТипОбъекта = Тип("Массив") Тогда
        Для Индекс = 0 По Коллекция.Количество() - 1 Цикл
            Если Коллекция[Индекс] = СтараяСсылка Тогда
                Коллекция[Индекс] = НоваяСсылка;
                БылиИзменения = Истина;
            ИначеЕсли ТипЗнч(Коллекция[Индекс]) = Тип("Массив") 
                Или ТипЗнч(Коллекция[Индекс]) = Тип("Структура") Тогда
                ОбработатьКоллекцию(Коллекция[Индекс], СтараяСсылка, НоваяСсылка, БылиИзменения);
            КонецЕсли;
        КонецЦикла;
    КонецЕсли;

КонецПроцедуры

Сериализованные данные и бинарные файлы

Если ссылка спрятана в XML, JSON или строке с GUID, подход усложняется. Нам нужно проанализировать все реквизиты с типом Строка (длина которых позволяет вместить GUID) или ДвоичныеДанные.

При обнаружении таких данных мы пытаемся их интерпретировать: десериализовать XML/JSON в объект 1С, выполнить там рекурсивный перебор и замену (как описано выше), а затем сериализовать обратно. Либо применять строковые функции автозамены (например, СтрЗаменить для замены строкового представления старого GUID на новый в XML-документе), однако этот метод требует крайней осторожности, чтобы не повредить разметку.

Рекомендации по безопасному выполнению

Замена скрытых ссылок — это «хирургическое» вмешательство в структуру базы. Выясним, какие меры безопасности необходимо соблюдать:

← На главную