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