Битые ссылки в 1С: находим причину и восстанавливаем объект
Содержание
Если в поле документа вместо контрагента или номенклатуры стоит <Объект не найден>, а при проведении вылетает ошибка Объект не найден (10:a1b2c3...) — значит, элемент справочника удалили из базы напрямую, а ссылки на него в документах остались. Это и есть битая ссылка.
Хорошая новость: сам документ цел, повреждена только одна ссылка внутри него. Восстановить можно двумя путями — либо вернуть сам объект (из резервной копии или воссоздать с тем же идентификатором), либо аккуратно вычистить мёртвые ссылки. Ниже — что делать по шагам в 1С 8.3 (интерфейс «Такси»), от безопасного способа к радикальному.
Как выглядит битая ссылка и откуда она берётся
Удалённый объект оставляет после себя внутренний идентификатор (GUID). Пока в базе остаётся хотя бы один документ, который на него ссылался, этот идентификатор «висит» без данных. Платформа показывает его по-разному:
- 🔸 в поле карточки — текст
<Объект не найден>в угловых скобках; - 🔸 при открытии или проведении документа — ошибка вида
Объект не найден (10:hhhhhh…), где первое число это внутренний тип, а дальше идёт идентификатор в шестнадцатеричном виде; - 🔸 в отчётах — пустая ячейка или тот же текст
<Объект не найден>в группировке; - 🔸 при проверке ссылочной целостности — список «битых» ссылок с указанием, какой документ на что ссылается.
Главная причина одна: объект удалили напрямую, минуя штатную пометку на удаление. Так бывает после прямого Удалить() во внешней обработке, после удаления через меню «Все функции», при неаккуратной выгрузке-загрузке или после прямого вмешательства в SQL-базу.
Находим все битые ссылки: проверка ссылочной целостности
Прежде чем что-то восстанавливать, нужно понять масштаб. Для этого есть штатная проверка.
- Сделайте резервную копию базы (
Конфигуратор → Администрирование → Выгрузить информационную базув файл.dt). Без свежей копии дальше не двигайтесь — любая правка структуры данных необратима. - Запустите
Конфигуратор → Администрирование → Тестирование и исправление. - Снимите все галочки, кроме «Проверка логической целостности» и «Проверка ссылочной целостности».
- В блоке действий при ссылочной целостности выберите режим обработки. Доступны три варианта поведения для несуществующих объектов:
| Режим | Что делает | Когда выбирать |
|---|---|---|
| Не изменять автоматически | Только показывает список битых ссылок | Первый прогон — чтобы оценить проблему |
| Создавать объекты | Воссоздаёт объект-заглушку с тем же идентификатором | Когда данные объекта можно восстановить вручную |
| Очищать ссылки | Обнуляет битые ссылки в документах | Когда объект уже не нужен |
Первый прогон всегда делайте в режиме «Не изменять автоматически». Платформа соберёт полный список: какой документ на какой пропавший объект ссылается. По этому списку вы поймёте, один объект потерян или целый справочник.
Режим «Создавать объекты» — это и есть встроенное создание заглушек. Платформа сама заведёт в нужном справочнике пустые элементы с правильными идентификаторами и наименованием вида <Объект не найден>. После этого ссылки перестанут быть битыми, а вам останется открыть эти заглушки и дозаполнить реквизиты по памяти или по первичным документам.
Журнал регистрации: кто и что удалил
Чтобы понимать, что именно восстанавливать, выясните, какой объект пропал. Для этого есть журнал регистрации.
Откройте Конфигуратор → Администрирование → Журнал регистрации или в режиме «Предприятие» — НСИ и администрирование → Администрирование → Журнал регистрации (в типовых конфигурациях на БСП путь именно такой; в некоторых базах раздел называется «Администрирование»).
Что искать:
- 🔹 отбор по событию «Данные. Удаление» — покажет, какие объекты и когда удаляли;
- 🔹 колонку с представлением объекта — там видно наименование и тип удалённого элемента;
- 🔹 пользователя и дату — по ним вы поймёте, из какой резервной копии данные ещё живы;
- 🔹 комментарий и имя рабочей станции — если удаление шло из внешней обработки.
Запишите наименование и, по возможности, идентификатор удалённого объекта. Идентификатор пригодится, если вы будете воссоздавать объект программно. Его же можно взять прямо из текста ошибки Объект не найден.
Если журнал регистрации был очищен или удаление делали прямым запросом в SQL (минуя платформу), события в журнале не будет. В этом случае опирайтесь только на резервную копию.
Восстановление из резервной копии — самый надёжный способ
Если потерян важный объект с заполненными реквизитами (контрагент с реквизитами и договорами, номенклатура с ценами), восстанавливать «на глаз» рискованно. Надёжнее поднять данные из копии, сделанной до удаления.
Полностью перезаписывать рабочую базу копией нельзя — потеряете все документы, введённые после резервного копирования. Поэтому действуют иначе:
- Разверните копию как отдельную информационную базу (создайте новую пустую базу и загрузите в неё
.dt, либо восстановите копию SQL в отдельную базу данных). - Найдите в этой копии нужный объект, откройте его карточку.
- Перенесите данные в рабочую базу одним из способов:
- вручную завести объект заново и дозаполнить реквизиты (но тогда у него будет новый идентификатор, и старые ссылки останутся битыми);
- либо выгрузить объект из копии и загрузить в рабочую базу внешней обработкой — так сохранится прежний идентификатор, и ссылки «оживут» сами.
Для переноса одного-двух объектов с сохранением идентификатора подходит типовая обработка выгрузки и загрузки данных в формате XML (поставляется в составе типовых конфигураций). В ней отмечают нужный объект в базе-копии, выгружают в файл, затем загружают файл в рабочую базу. Идентификатор при таком переносе не меняется, поэтому старые ссылки сразу находят восстановленный объект. Если объектов много или они связаны между собой (контрагент, его договоры и банковские счета) — это предпочтительный путь: вручную такую связку собрать сложно и легко ошибиться.
Именно сохранение прежнего идентификатора отличает полноценное восстановление от простого «завёл заново». Если завести новый элемент с тем же названием, документы его не подхватят — они ссылаются на конкретный GUID, а не на наименование.
Когда объект простой (один-два реквизита) и прежний идентификатор известен из ошибки или журнала — проще воссоздать его кодом, сохранив идентификатор. Об этом следующий раздел.
Воссоздаём объект с прежним идентификатором через обработку
Этот способ возвращает именно тот объект, на который ссылаются документы, — с тем же идентификатором. После записи битые ссылки превращаются в рабочие автоматически.
Код выполняют во внешней обработке, запущенной в режиме «Предприятие» (Файл → Открыть, нужны права администратора). Отлаживать обработку удобно из Конфигуратора — запуск в режиме отладки покажет, что именно происходит на каждом шаге.
Идентификатор берут из текста ошибки или из журнала регистрации. Пример для справочника «Контрагенты»:
// Идентификатор удалённого объекта (из ошибки или журнала)
Идентификатор = Новый УникальныйИдентификатор("a1b2c3d4-e5f6-7890-abcd-ef1234567890");
Ссылка = Справочники.Контрагенты.ПолучитьСсылку(Идентификатор);
// Проверяем, что объекта действительно нет
Если Ссылка.ПолучитьОбъект() = Неопределено Тогда
Объект = Справочники.Контрагенты.СоздатьЭлемент();
Объект.УстановитьСсылкуНового(Ссылка); // закрепляем прежний идентификатор
Объект.Наименование = "Восстановленный контрагент";
// здесь дозаполните остальные реквизиты
Объект.Записать();
Сообщить("Объект восстановлен: " + Объект.Ссылка);
Иначе
Сообщить("Объект с таким идентификатором уже существует.");
КонецЕсли;
Ключевой момент — метод УстановитьСсылкуНового. Он задаёт новому, ещё не записанному объекту конкретную ссылку, а значит и тот самый идентификатор, который ждут документы. Без него платформа выдала бы новому элементу случайный GUID.
Для документа используйте Документы.ВидДокумента.СоздатьДокумент(), для плана видов характеристик и прочих ссылочных типов — соответствующий менеджер. Логика та же: получить ссылку по идентификатору, проверить, что объекта нет, создать и закрепить ссылку.
После записи откройте любой документ, который давал ошибку. Поле со ссылкой должно показать восстановленный объект. Останется дозаполнить его реквизиты и перепровести документы, если восстановленный объект влияет на движения (например, счёт учёта или склад).
Если битых ссылок несколько и все они ведут на разные удалённые объекты, обработку можно доработать: собрать идентификаторы из проверки ссылочной целостности в таблицу и пройти её циклом, создавая объект под каждый идентификатор. Но если объектов действительно много, быстрее и надёжнее отработать их штатным режимом «Создавать объекты» в тестировании и исправлении, а кодом восстанавливать только единичные важные объекты, где нужно сразу задать осмысленные реквизиты.
Прямой запрос к SQL: когда оправдан и чем опасен
Для клиент-серверных баз на MS SQL или PostgreSQL иногда предлагают «починить» ссылки прямо в базе данных. Это крайняя мера, и в большинстве случаев она не нужна — проверка ссылочной целостности и восстановление из копии решают задачу безопаснее.
Что важно понимать про прямой доступ:
- 🔸 имена таблиц и полей в SQL не совпадают с именами объектов 1С. Элементы справочников лежат в таблицах вида
_ReferenceNN, а соответствие «имя объекта → имя таблицы» возвращает методПолучитьСтруктуруХраненияБазыДанных()— его вызывают из встроенного языка, а не угадывают; - 🔸 идентификаторы в SQL хранятся в бинарном виде, а не в том читаемом формате, что в тексте ошибки, — их ещё нужно правильно преобразовать;
- 🔸 прямая правка данных в обход платформы не поддерживается фирмой 1С и снимает гарантии корректной работы. Нарушите итоги регистров или индексы — получите проблемы хуже исходной битой ссылки.
Прямой SQL оправдан только как диагностика на чтение: посмотреть, сколько документов ссылается на пропавший идентификатор, оценить масштаб. Для изменения данных используйте встроенный язык и штатные механизмы платформы — они пишут данные так, как платформа ожидает.
Если решились на серверную операцию, делайте её на копии базы и только тогда, когда понимаете структуру хранения. На рабочей базе — никогда без проверенной резервной копии.
Профилактика: права доступа и правильное удаление
Битые ссылки почти всегда — результат прямого удаления. Убрать причину проще, чем потом чинить последствия.
- ✅ Запретите прямое удаление пользователям. В настройке ролей снимите право «Удаление» для рядовых пользователей на справочники. Пусть вместо удаления ставят пометку.
- ✅ Удаляйте только через «Удаление помеченных объектов». В режиме «Предприятие»:
НСИ и администрирование → Администрирование → Обслуживание → Удаление помеченных объектов. Эта обработка перед удалением проверяет, нет ли ссылок на объект, и не даёт удалить то, что используется. - ✅ Контролируйте внешние обработки. Прямой
Удалить()в обработке сносит объект без проверки ссылок. Ограничьте запуск внешних обработок правами и используйте их осознанно. - ✅ Настройте расписание резервного копирования. Ежедневная копия на сервере (а не раз в месяц) превращает любую потерю данных в мелкую неприятность.
Частые вопросы
Можно ли вернуть сами данные удалённого объекта, если копии нет?
Чем «Создавать объекты» в ТиИ отличается от воссоздания кодом?
<Объект не найден>. Код удобнее, когда объект один и вы хотите сразу задать ему осмысленное наименование.Что выбрать: «Создавать объекты» или «Очищать ссылки»?
Нужно ли перепроводить документы после восстановления?
Почему новый элемент с тем же названием не убирает ошибку?
УстановитьСсылкуНового или через режим «Создавать объекты».