Смена уникального идентификатора ссылки в 1С 8.3: новый объект, перенос ссылок, откат

· 10 мин

Содержание

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

Типичная ситуация: после переноса данных из другой базы контрагент «Альфа» оказался с другим GUID, чем в учётной системе холдинга. Обмен по идентификаторам перестал его узнавать и плодит дубли. Сменить идентификатор объекта можно безопасно — кодом, обработкой БСП, через Конфигуратор или XML, а SQL оставить на крайний случай.

Когда смена GUID нужна, а когда хватит другого решения

GUID (тип УникальныйИдентификатор) — это 16 байт, которые платформа хранит в поле ссылки. По нему связаны все документы, регистры, реквизиты и табличные части. Поэтому «поменять GUID» на деле значит «поменять ссылку во всех местах, где она встречается».

Реальные причины, по которым за это берутся:

  • 🔗 Синхронизация по идентификаторам. Две базы обмениваются данными по GUID, а один и тот же объект в них заведён с разными ссылками.
  • 🧩 Восстановление удалённого объекта. Элемент удалили, а в документах остались ссылки вида <Объект не найден> (75:a1b2...). Нужно вернуть объект именно с тем GUID, на который они указывают.
  • 📦 Слияние баз. При переносе справочников из одной базы в другую совпали или, наоборот, разошлись идентификаторы.
  • 🔁 Внешняя система. Сайт, CRM или складская программа хранит GUID из 1С, и объект пришлось пересоздать.

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

Сравнение способов

СпособКогда подходитРиски
Копия с УстановитьСсылкуНового() + замена ссылокЛюбая конфигурация, объект существуетДолго на больших базах, нужны права администратора
Тестирование и исправление с созданием объектовОбъект удалён, остались битые ссылкиСоздаются пустые заглушки, их надо заполнить
Выгрузка в XML, правка, загрузкаПеренос объектов между базами с нужным GUIDЗагрузка без проверок, легко сломать связи
Прямой UPDATE в SQLПоследний вариант, клиент-серверная базаПропущенная таблица = битые данные, без поддержки

Как узнать текущий GUID объекта и битой ссылки

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

Получить GUID существующей ссылки можно одной строкой кода. Например, в консоли кода или во внешней обработке:

УИД = Ссылка.УникальныйИдентификатор();
Сообщить(Строка(УИД)); // 1cbec0e1-8e7d-11df-aa1b-001a6463a6ca

Метод работает и для битой ссылки, на которую уже нет объекта. Это удобно: GUID удалённого элемента достаётся прямо из реквизита документа.

Из текстового представления <Объект не найден> идентификатор тоже извлекается. Строка вида <Объект не найден> (79:aa1b001a6463a6ca11df8e7d1cbec0e1) содержит номер таблицы и 32 hex-символа в порядке хранения. Чтобы собрать GUID, группы переставляют:

Часть в строкеСимволыМесто в GUID
1–4 символаaa1b4-я группа
5–16001a6463a6ca5-я группа
17–2011df3-я группа
21–248e7d2-я группа
25–321cbec0e11-я группа

Итог: 1cbec0e1-8e7d-11df-aa1b-001a6463a6ca. В таком же порядке байты лежат в поле _IDRRef на SQL Server. Число перед двоеточием — внутренний номер таблицы, для сборки GUID оно не нужно.

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

Замена GUID объекта в 1С кодом: копия, перенос ссылок, удаление

Это основной и самый безопасный путь. Он работает в файловой и клиент-серверной базе и не выходит за рамки платформы.

Перед началом сделайте резервную копию базы (выгрузку .dt или бэкап СУБД). Замена ссылок затрагивает сотни таблиц, и откатить её вручную почти невозможно.

Шаг 1. Создайте новый объект с нужным GUID

Код выполняется на сервере: во внешней обработке или в консоли кода с правами администратора.

&НаСервереБезКонтекста
Функция СоздатьКопиюСНовымGUID(СтараяСсылка, СтрокаGUID)

    НовыйУИД = Новый УникальныйИдентификатор(СтрокаGUID);
    МенеджерОбъекта = ОбщегоНазначения.МенеджерОбъектаПоСсылке(СтараяСсылка);
    НоваяСсылка = МенеджерОбъекта.ПолучитьСсылку(НовыйУИД);

    Если НоваяСсылка.ПолучитьОбъект() <> Неопределено Тогда
        ВызватьИсключение "Объект с таким GUID уже существует";
    КонецЕсли;

    НовыйОбъект = СтараяСсылка.ПолучитьОбъект().Скопировать();
    НовыйОбъект.УстановитьСсылкуНового(НоваяСсылка);
    НовыйОбъект.Записать();

    Возврат НоваяСсылка;

КонецФункции

ОбщегоНазначения.МенеджерОбъектаПоСсылке() есть в конфигурациях на БСП (БП 3.0, ЗУП 3.1, УТ 11). В самописной базе менеджер берите напрямую: Справочники.Контрагенты.

Несколько тонкостей:

  • ⚠️ Контроль уникальности кода. Если в справочнике он включён, копия с прежним кодом не запишется. Очистите код у копии, а после удаления старого элемента верните прежний.
  • 📄 Документы. Копию записывайте в режиме РежимЗаписиДокумента.Запись, без проведения. Иначе на время работы в регистрах окажутся двойные движения.
  • 🗂️ Подчинённые данные. Скопируются реквизиты и табличные части. Присоединённые файлы, контактная информация в отдельных регистрах и история версий останутся на старой ссылке, пока вы не замените ссылки.

Шаг 2. Переведите все ссылки со старого объекта на новый

В типовых конфигурациях для этого есть готовая функция БСП ОбщегоНазначения.ЗаменитьСсылки(). Она обходит все таблицы, где встречается ссылка, включая регистры и составные типы.

ПарыЗамен = Новый Соответствие;
ПарыЗамен.Вставить(СтараяСсылка, НоваяСсылка);

ПараметрыЗамены = Новый Структура;
ПараметрыЗамены.Вставить("СпособУдаления", "Пометка");

Ошибки = ОбщегоНазначения.ЗаменитьСсылки(ПарыЗамен, ПараметрыЗамены);
Для Каждого Ошибка Из Ошибки Цикл
    Сообщить(Ошибка.ТекстОшибки);
КонецЦикла;

Набор параметров зависит от версии БСП, поэтому сверьтесь с комментарием к функции в общем модуле ОбщегоНазначения вашей конфигурации.

Без программирования то же самое делает обработка «Поиск и удаление дублей». В БП 3.0 она открывается из Администрирование → Обслуживание → Корректировка данных. Найдите пару «старый — новый» и выберите новый элемент как оригинал: обработка заменит ссылки и пометит старый на удаление.

В конфигурации без БСП ссылки собирают методом НайтиПоСсылкам(). Он вернёт таблицу со всеми объектами и записями регистров, где встречается старая ссылка. Каждую найденную запись придётся перезаписать отдельно — это долгая ручная работа, проще встроить в базу общий модуль с аналогичной логикой.

Шаг 3. Проверьте и удалите старый объект

  1. Повторно вызовите НайтиПоСсылкам() для старой ссылки. Таблица должна быть пустой.
  2. Проведите новый документ, если это документ.
  3. Удалите старый объект через «Удаление помеченных объектов».
  4. Сформируйте контрольные отчёты: оборотно-сальдовую ведомость по счёту объекта, остатки по регистрам.
Перед удалением старого объекта
Выполнено: 0 / 5

Как вернуть удалённый объект по прежнему GUID

Здесь замена ссылок не нужна: битые ссылки уже указывают на нужный GUID. Достаточно создать объект именно с этим идентификатором, и все документы «оживут».

Через Конфигуратор: тестирование и исправление

В Конфигураторе выберите Администрирование → Тестирование и исправление. Отметьте проверку ссылочной целостности и в настройке для ссылок на несуществующие объекты выберите вариант «Создавать объекты».

Платформа создаст объекты-заглушки с теми GUID, на которые есть ссылки. Наименование у них служебное, реквизиты пустые. Найдите заглушки в справочнике и заполните вручную или кодом.

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

В режиме Предприятия кодом

Если битых ссылок мало и вы точно знаете GUID, создайте один объект без остановки работы:

УИД = Новый УникальныйИдентификатор("1cbec0e1-8e7d-11df-aa1b-001a6463a6ca");
Ссылка = Справочники.Номенклатура.ПолучитьСсылку(УИД);

Если Ссылка.ПолучитьОбъект() = Неопределено Тогда
    Объект = Справочники.Номенклатура.СоздатьЭлемент();
    Объект.УстановитьСсылкуНового(Ссылка);
    Объект.Наименование = "Восстановленный элемент";
    Объект.Записать();
КонецЕсли;

После записи все реквизиты, где стояло <Объект не найден>, покажут новое наименование.

Перенос объекта с заданным GUID через XML

Когда объект нужно перенести в другую базу с конкретным идентификатором, удобна универсальная обработка выгрузки и загрузки данных XML. Её распространяют для 8.3 как внешнюю обработку .

Порядок такой:

  1. Выгрузите объект из исходной базы в XML-файл.
  2. Откройте файл в текстовом редакторе и найдите тег <Ref> нужного объекта.
  3. Подставьте целевой GUID в обычном формате с дефисами. Замените его и во всех местах файла, где этот объект упоминается.
  4. Загрузите файл в приёмник той же обработкой.

Загрузка идёт в режиме обмена данными: проверки заполнения и обработчики записи не срабатывают. Документы после загрузки проведите отдельно и проверьте остатки.

Не используйте этот путь внутри одной базы для «переименования» GUID: старый объект останется, а ссылки на него не изменятся.

Прямая замена идентификатора через SQL

На SQL Server или PostgreSQL ссылка лежит в поле _IDRRef типа binary(16) (в PostgreSQL — bytea). Ссылки на объект хранятся в полях _Fld…RRef всех таблиц, где он встречается. Для составных типов — ещё и в паре полей с номером типа.

Соответствие имён таблиц объектам конфигурации покажет функция ПолучитьСтруктуруХраненияБазыДанных().

Фрагмент для одной таблицы выглядит так (SQL Server):

-- Только для иллюстрации: меняет ссылку в одной таблице
UPDATE _Reference75
SET _IDRRef = 0xAA1B001A6463A6CA11DF8E7D1CBEC0E1
WHERE _IDRRef = 0x<старый идентификатор>;

Почему этот способ — последний:

  • ❌ Нужно обновить все поля во всех таблицах: документы, табличные части, регистры, итоги, историю версий, таблицы регистрации изменений. Пропустили одну — получили битые данные.
  • ❌ Платформа не узнает об изменениях: не обновятся итоги и полнотекстовый индекс, не зарегистрируются изменения для обмена.
  • ❌ Фирма 1С не поддерживает прямое изменение данных в таблицах базы. Если после правки база начнёт сбоить, разбираться придётся самостоятельно.
  • ❌ В файловой базе этот путь закрыт.

Если без SQL не обойтись, делайте его на копии базы. Остановите доступ пользователей, после правки выполните в Конфигураторе тестирование и исправление с пересчётом итогов. Сеансы на время работ будут прерваны, поэтому выбирайте нерабочее окно.

GUID в распределённой базе и обменах

В распределённой информационной базе (РИБ) GUID объекта одинаков во всех узлах. Это упрощает одно и усложняет другое.

Что работает в вашу пользу. Новый объект, созданный с УстановитьСсылкуНового() в главном узле, приходит в подчинённые с тем же идентификатором.

Что нужно учесть:

  • 📤 Замена ссылок регистрирует к обмену каждый изменённый документ и набор записей. После замены в популярном справочнике пакет обмена может вырасти в разы.
  • 🏢 Выполняйте замену в главном узле, когда все узлы синхронизированы. Затем проведите обмен со всеми узлами по очереди.
  • 🚫 Правка через SQL в РИБ не регистрирует изменения. Узлы разойдутся: в одном объект с новым GUID, в другом — со старым.

В обменах по правилам конвертации (базы с разными конфигурациями) смена GUID ломает сопоставление. Приёмник по старому идентификатору объекта не найдёт и создаст новый. В конфигурациях на БСП сопоставление хранится в регистре сведений «Соответствия объектов информационных баз». После смены GUID проверьте запись для этого объекта или выполните повторное сопоставление в настройках синхронизации.

Риски и откат, если что-то пошло не так

Что чаще всего ломается и как это исправить:

Диагностика: выберите симптом

Полный откат — только из резервной копии. Поэтому сохраняйте её до начала и не удаляйте, пока не убедитесь, что отчёты и обмены работают.

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

Можно ли поменять GUID у предопределённого элемента?
Нет. Предопределённые элементы связаны с конфигурацией по имени предопределённых данных. При конфликте после обмена правьте сопоставление по этому имени, а не идентификатор.
Сохранит ли новый объект номер и дату документа?
Метод Скопировать() переносит реквизиты и табличные части. Номер и дату проверьте у копии до записи и при необходимости присвойте прежние; при контроле уникальности номера действуйте так же, как с кодом справочника.
Можно ли сгенерировать GUID заранее, до создания объекта?
Да: Новый УникальныйИдентификатор() без параметров даёт случайный GUID. Его можно передать во внешнюю систему и потом создать объект с этой ссылкой.
Сколько времени займёт замена ссылок?
Зависит от числа мест, где встречается ссылка. Для контрагента с тысячами документов — от минут до часов, поэтому крупные замены запускают фоном и вне рабочего времени.
Нужен ли монопольный режим для замены через БСП?
Нет, функция работает при открытых сеансах. Но пользователи не должны редактировать затронутые документы, иначе возможны ошибки блокировки.