Замена ссылок на объекты справочников и документов

· 9 мин

Содержание

Ссылку уже записанного объекта в 1С напрямую отредактировать нельзя. Ссылка жёстко связана с внутренним идентификатором (GUID), который присваивается один раз при первой записи элемента справочника или документа и дальше не меняется.

Поэтому за фразой «изменить ссылку объекта» почти всегда стоит одна из трёх задач: заменить ссылки на один объект ссылками на другой (слияние дублей), сохранить или перенести идентификатор при обмене и миграции базы, либо создать объект с заранее заданным GUID. Ниже разберём каждый случай — от безопасного типового инструмента до кода обработки — и как всё откатить, если пошло не так.

Что именно вам нужно сделать со ссылкой?

Что такое ссылка объекта и почему её не переписать

В 1С каждый элемент справочника, документ, элемент плана видов характеристик и прочий ссылочный объект хранится в таблице базы под уникальным идентификатором. Этот идентификатор — тип УникальныйИдентификатор, то же самое, что GUID: 32 шестнадцатеричные цифры вида a1b2c3d4-....

Ссылка (СправочникСсылка.Контрагенты, ДокументСсылка.РеализацияТоваровУслуг и т. п.) — это и есть указатель на строку по её идентификатору. Когда в реквизите другого объекта, в движении документа или в регистре записана ссылка, физически там лежит именно этот GUID.

Отсюда два следствия, которые определяют всё дальнейшее:

  • 🔒 Идентификатор объекту присваивается при первой записи и после этого неизменен. Кнопки «поменять ссылку» в режиме 1С:Предприятие нет и быть не может.
  • 🔗 Ссылки хранятся в сотнях мест: реквизиты других справочников и документов, табличные части, движения по регистрам, значения в периодических сведениях. Переставить ссылку «в одном месте» обычно бессмысленно.

Когда говорят «изменить ссылку», на деле меняют не сам объект, а то, что на него ссылается. Либо все указатели на объект А переводят на объект Б, либо создают новый объект с нужным GUID, а старый убирают.

Замена ссылок типовым инструментом без кода

Самый частый сценарий — завелись два одинаковых контрагента, две одинаковые номенклатуры, и часть документов оформлена на один элемент, часть на другой. Нужно оставить один, а ссылки со второго перевести на первый.

Для этого в типовых конфигурациях на БСП (Бухгалтерия 3.0, ЗУП 3.1, УТ 11 и др.) есть обработка «Поиск и удаление дублей». Она сама находит все места использования лишнего элемента, переставляет ссылки на оставленный и помечает дубль на удаление.

Как её открыть:

  1. Включите команду Главное меню → Сервис → Параметры → Отображать команду «Все функции» (если ещё не включена).
  2. Откройте Главное меню → Все функции → Стандартные → Поиск и удаление дублей. В ряде конфигураций она же вынесена в раздел Администрирование или НСИ.
  3. Выберите область поиска (например, справочник «Контрагенты»), задайте правила сравнения и запустите поиск.
  4. В найденных группах укажите, какой элемент оставить (Оставить), какие считать дублями, и нажмите удаление.

На шаге удаления программа как раз и переставляет ссылки: во всех документах и регистрах, где фигурировал дубль, подставляется оставленный элемент.

Если нужно заменить не дубли, а любое значение на другое (например, везде поменять одну организацию на другую), подойдёт универсальная внешняя обработка «Поиск и замена значений» с диска ИТС. Она ищет конкретную ссылку по всей базе и меняет её на указанную. Открывается через Файл → Открыть (нужны права на открытие внешних обработок) либо подключается в список дополнительных обработок.

Перед заменой ссылок сделайте резервную копию базы. Операция затрагивает движения документов и не имеет кнопки «отменить». Выполняйте её в нерабочее время: при обработке больших справочников возможны длительные блокировки, из-за которых у пользователей начнут «зависать» операции.

Ссылки при обмене данными и переносе базы

При переносе базы поведение ссылок зависит от способа переноса.

Выгрузка и загрузка .dt (Конфигуратор → Администрирование → Выгрузить/Загрузить информационную базу) — это полная копия базы байт в байт. Все идентификаторы сохраняются, ссылки остаются валидными. Этот способ ссылки не меняет вообще.

Распределённая база (РИБ) — узлы обмениваются объектами вместе с их идентификаторами, поэтому один и тот же контрагент в центральной базе и в филиале имеет одинаковый GUID. Ссылки между узлами совпадают автоматически.

Обмен через правила конвертации (КД 2.0/3.0, формат EnterpriseData) — другое дело. Здесь объекты в базе-приёмнике ищутся не по GUID, а по полям поиска из правил (ИНН, код, наименование). Если поля сопоставления заданы неточно, получаются либо дубли, либо «склейка» разных объектов в один. «Побитые ссылки» после обмена — это почти всегда ошибка в правилах сопоставления, а не в самих ссылках.

Что с этим делать:

  • Проверьте в правилах конвертации, по каким полям сопоставляются объекты, и совпадают ли они в источнике и приёмнике.
  • Уже появившиеся дубли уберите через «Поиск и удаление дублей» (раздел выше).
  • Если нужно, чтобы объект в приёмнике получил конкретный идентификатор из источника, это задаётся программно до записи — смотрите следующий раздел.

Как найти все места, где используется ссылка

Прежде чем что-то менять, полезно увидеть полную картину: где именно фигурирует ссылка. Для этого есть глобальная функция НайтиПоСсылкам.

СтарыйКонтрагент = Справочники.Контрагенты.НайтиПоНаименованию("ООО Старое");

МассивСсылок = Новый Массив;
МассивСсылок.Добавить(СтарыйКонтрагент);

ТаблицаИспользования = НайтиПоСсылкам(МассивСсылок);

Для Каждого Строка Из ТаблицаИспользования Цикл
    // в колонке Ссылка — объект, который использует искомую ссылку
    Сообщить(Строка(Строка.Ссылка));
КонецЦикла;

Функция возвращает таблицу значений с перечнем объектов, которые ссылаются на переданные ссылки. В колонке Ссылка — объект-источник (документ, элемент справочника), который содержит ссылку на искомый объект.

Это удобно и как диагностика перед удалением: если таблица пустая, объект нигде не используется и его безопасно помечать на удаление.

Для анализа «вширь» — сколько документов за период, какие суммы — используют запрос. Конструктор запросов (кнопка в контекстном меню модуля или в консоли запросов) помогает собрать выборку: например, все документы реализации, где указан данный контрагент. Запросом ссылку не изменить — язык запросов только читает данные, — но он незаменим, чтобы оценить масштаб и отобрать объекты для обработки.

НайтиПоСсылкам показывает прямые ссылки на объект. Косвенные связи (например, через подчинённый справочник) она не раскручивает — для сложной иерархии проходите по уровням.

Замена ссылок в коде обработки

Когда типовой инструмент не подходит (нетиповая конфигурация, своя логика отбора), замену делают обработкой. Общий алгоритм:

  1. Собрать массив старых ссылок, которые нужно заменить.
  2. Найти объекты-потребители через НайтиПоСсылкам.
  3. Для каждого объекта получить его ПолучитьОбъект(), заменить значение реквизита или строки табличной части и записать.
  4. Перепровести документы, у которых поменялись реквизиты, влияющие на движения.

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

При записи объектов в цикле замены ставьте флаг обмена, чтобы не плодить лишние проведения и не запускать бизнес-логику повторно без необходимости:

Объект = Строка.Ссылка.ПолучитьОбъект();
Объект.Контрагент = НовыйКонтрагент;
Объект.ОбменДанными.Загрузка = Истина; // отключить лишние проверки при записи
Объект.Записать();

Флаг ОбменДанными.Загрузка = Истина отключает проверки заполнения и часть бизнес-логики. Ставьте его осознанно и только там, где уверены, что проверки не нужны: иначе в базу попадут некорректно заполненные документы.

Отдельный случай — создать объект с заранее нужным идентификатором. Изменить GUID существующего объекта нельзя, но у нового, ещё не записанного, ссылку можно задать явно:

Ид = Новый УникальныйИдентификатор("a1b2c3d4-e5f6-4789-0abc-def012345678");
НужнаяСсылка = Справочники.Контрагенты.ПолучитьСсылку(Ид);

Объект = Справочники.Контрагенты.СоздатьЭлемент();
Объект.УстановитьСсылкуНового(НужнаяСсылка);
Объект.Наименование = "ООО Новое";
Объект.Записать();

Метод ПолучитьСсылку(Идентификатор) возвращает ссылку с заданным GUID, даже если объекта с ним ещё нет. УстановитьСсылкуНового работает только до первой записи. Именно так переносят идентификаторы при миграции, чтобы ссылки из внешней системы указывали на правильные объекты.

Пакетная обработка и временные таблицы

Если заменить нужно не один объект, а тысячи (например, после массового задвоения при обмене), обработка «в лоб» упрётся в память и в длинную транзакцию. Помогают временные таблицы и обработка порциями.

Список заменяемых ссылок удобно поместить во временную таблицу запроса и соединять с ней документы — так поиск использований идёт по индексу, а не перебором:

Запрос = Новый Запрос;
Запрос.МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц;
Запрос.Текст =
"ВЫБРАТЬ Ссылка ПОМЕСТИТЬ ВТ_Замена
 ИЗ &ТаблицаЗамен КАК Т
 ИНДЕКСИРОВАТЬ ПО Ссылка";
Запрос.УстановитьПараметр("ТаблицаЗамен", ТаблицаЗамен);
Запрос.Выполнить();

Дальше во втором запросе соединяете нужные документы с временной таблицей ВТ_Замена и получаете только затронутые объекты.

Саму запись ведите пачками по несколько сотен объектов, фиксируя каждую пачку отдельной транзакцией. Это снижает нагрузку на буфер транзакции и уменьшает риск блокировок. Не заворачивайте десятки тысяч записей в одну транзакцию — её откат при сбое занимает столько же, сколько сама операция, и всё это время база заблокирована.

Тяжёлую замену запускайте в фоновом задании и в нерабочее время. Промежуточный результат логируйте, чтобы при обрыве продолжить с места остановки, а не начинать заново.

Проверка результата, перепроведение и откат

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

Что проверить после замены:

  • 📄 Перепроведение. Документы, затронутые заменой, перепроведите (групповое перепроведение за период или типовое «Проведение документов»). Типовой инструмент «Поиск и удаление дублей» предлагает это сделать сам.
  • 🔎 Остаточные ссылки. Прогоните НайтиПоСсылкам по старому объекту ещё раз. Пустая таблица означает, что ссылок на него не осталось.
  • 🗑 Удаление старого объекта. Пометьте его на удаление и запустите Операции → Удаление помеченных объектов (или одноимённую обработку в разделе «Администрирование»). Платформа не даст удалить объект, пока на него что-то ссылается, — это защита от битых ссылок.

Отдельно держите в голове закрытые периоды. Если замена ссылок затрагивает документы за уже закрытый месяц и требует их перепроведения, сначала проверьте дату запрета изменения данных: при включённом запрете перепроведение в закрытом периоде не пройдёт. Либо временно сдвиньте дату запрета, либо согласуйте правку с тем, кто отвечает за закрытие периода , чтобы не разошлись отчётность и учётные данные.

Отдельной кнопки «отменить замену ссылок» в 1С нет. Единственный надёжный откат — восстановление из резервной копии, сделанной до операции. Поэтому копия перед заменой не формальность, а реальный план отступления. Если база большая и восстановление целиком затянется, заранее прикиньте время простоя и выбирайте для операции окно, когда этот простой допустим.

Перед заменой ссылок
Выполнено: 0 / 5

Частые вопросы

Можно ли изменить GUID уже записанного объекта?
Нет. Идентификатор присваивается при первой записи и неизменен. Нужный GUID можно задать только новому, ещё не записанному объекту через УстановитьСсылкуНового, а затем перевести на него ссылки и удалить старый.
Что происходит со старым объектом после замены ссылок?
Он остаётся в базе. Когда ссылок на него не осталось, пометьте его на удаление и запустите «Удаление помеченных объектов». Пока хоть одна ссылка есть, платформа удалить не даст.
Нужно ли перепроводить документы после замены?
Да, если заменённая ссылка влияет на движения (проводки, записи регистров). Иначе в отчётах останутся старые данные. Типовой инструмент предлагает перепроведение автоматически.
Чем `ПолучитьСсылку` отличается от `НайтиПоКоду` или `НайтиПоНаименованию`?
НайтиПоКоду ищет существующий элемент по реквизиту и возвращает пустую ссылку, если не нашёл. ПолучитьСсылку(Идентификатор) формирует ссылку по заданному GUID, даже если объекта с таким идентификатором ещё нет в базе.
Сохранятся ли ссылки при переносе базы через выгрузку `.dt`?
Да. Выгрузка и загрузка .dt — это полная копия базы, все идентификаторы и ссылки сохраняются без изменений. Ссылки «переезжают» только при обмене через правила конвертации, где объекты ищутся по полям сопоставления.