При переносе данных между базами 1С (особенно при переходе на новые редакции программ или создании «чистых» рабочих баз) технические специалисты часто сталкиваются со странным поведением системы. Вроде бы перенос завершен успешно, но при попытке завести нового клиента программа выдает критическую ошибку: «Контрагент с ИНН таким-то уже существует». При этом в стандартном списке справочника данного контрагента нет. Если же зайти через технический режим «Все функции» (или «Функции для технического специалиста»), контрагент обнаруживается, но открыть его карточку невозможно — система сразу предлагает создать новый элемент и снова блокирует запись из-за дублирования ИНН.
В этой статье мы подробно проанализируем, почему возникает эта классическая проблема в конфигурации «1С:Управление торговлей 11» (а также в «1С:ERP» и «1С:Комплексная автоматизация 2»), разберем её внутреннюю архитектурную суть и рассмотрим четыре практических способа полного устранения этой ошибки.
---
Чтобы понять природу возникновения «фантомов», нам необходимо детально рассмотреть логику работы современных конфигураций 1С. Начиная с 11-й версии «Управления торговлей», разработчики разделили сущности клиентов и поставщиков на два независимых уровня:
Справочник.Партнеры) — это объекты управленческого учета. Партнером может выступать весь холдинг в целом, бренд, торговая сеть или просто розничный покупатель. В карточке партнера хранится маркетинговая информация: сегменты, скидки, классификация, а также иерархия (например, головной офис и его филиалы).Справочник.Контрагенты) — это объекты регламентированного учета. Сюда заносятся юридические и физические лица с их официальными реквизитами (ИНН, КПП, ОГРН, адреса регистрации и банковские счета). Именно с контрагентами заключаются договоры и оформляются первичные документы (УПД, счета-фактуры).В базе данных каждый контрагент жестко связан со своим партнером через обязательный реквизит Партнер. По умолчанию в системе может быть включен совмещенный режим работы (когда опция независимого ведения отключена). В этом случае для пользователя в интерфейсе существует один общий справочник «Клиенты» или «Поставщики». Программа сама «под капотом» создает и партнера, и связанного с ним контрагента, синхронизируя их данные.
Что происходит при некорректном переносе данных?
Когда мы выполняем перенос данных с помощью универсальной выгрузки/загрузки XML (или через правила конвертации) и переносим только справочник Контрагенты, нарушается ссылочная целостность базы данных:
Контрагенты успешно записываются в новую информационную базу.Партнер у этих контрагентов записывается уникальный идентификатор (GUID) партнера из старой базы.Партнеры мы не переносили, в новой базе этих GUID просто нет.Партнер образуется так называемая битая ссылка, отображаемая в системе как <Объект не найден> (уникальный идентификатор...).Именно из-за этих битых ссылок система начинает вести себя некорректно. Обычные формы списков не могут отобразить контрагента, у которого партнер равен «Объект не найден», и отфильтровывают такие записи. Однако низкоуровневая таблица базы данных хранит эти записи, поэтому они видны во «Всех функциях» и вызывают конфликт уникальности ИНН.
---
Если вы хотите сохранить полную структуру связей и корректно перенести всю историю клиентов из старой базы, этот способ является самым правильным и безопасным.
Разберем процесс по шагам:
Партнеры. Никакие связанные регистры и документы в данном случае выбирать не нужно.Почему это сработает? При выгрузке и загрузке XML-платформа сопоставляет объекты по их внутренним уникальным идентификаторам (GUID). Когда новые партнеры запишутся в базу данных с теми же GUID, битые ссылки <Объект не найден> у контрагентов мгновенно «оживут» и заменятся на реальные элементы справочника Партнеры. Проблема с видимостью и открытием карточек полностью исчезнет.
---
Если вы не планируете переносить старых партнеров (например, решили завести структуру клиентов заново), вы можете исправить ситуацию стандартными интерактивными средствами, временно изменив настройки системы.
Рассмотрим этот алгоритм подробнее:
---
Платформа «1С:Предприятие» имеет встроенный мощный механизм проверки логической и ссылочной целостности базы данных. Мы можем использовать его для автоматической очистки поля Партнер у «сломанных» контрагентов.
Проанализируем шаги выполнения этой процедуры:
1Cv8.1CD для файловой базы).Платформа просканирует таблицу контрагентов. Обнаружив в поле Партнер битые ссылки вида <Объект не найден>, она запишет туда пустые значения. После этого контрагенты перестанут вызывать критические ошибки при открытии, их можно будет найти поиском дублей и корректно отредактировать.
---
Если вы хотите точечно и быстро решить проблему без изменения настроек системы и запуска длительного тестирования базы данных, можно написать небольшую внешнюю обработку. Проанализируем программный код, который находит поврежденных контрагентов и безопасно очищает битые связи или помечает фантомы на удаление.
Для поиска записей с битыми ссылками мы используем запрос к базе данных. Проверить ссылку на «битость» в языке запросов 1С проще всего путем обращения к какому-либо реквизиту связанного объекта (например, к его коду или версии данных). Если связанный объект отсутствует в СУБД, система вернет значение НЕОПРЕДЕЛЕНО или NULL.
Посмотрим на пример кода для удаления «фантомных» контрагентов:
// Создаем запрос для поиска контрагентов с отсутствующими партнерами
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Контрагенты.Ссылка КАК Ссылка
|ИЗ
| Справочник.Контрагенты КАК Контрагенты
|ГДЕ
| Контрагенты.Партнер.Код ЕСТЬ NULL
| И Контрагенты.Партнер <> ЗНАЧЕНИЕ(Справочник.Партнеры.ПустаяСсылка)";
РезультатЗапроса = Запрос.Выполнить();
Если Не РезультатЗапроса.Пустой() Тогда
Выборка = РезультатЗапроса.Выбрать();
НачатьТранзакцию();
Попытка
Пока Выборка.Следующий() Цикл
// Получаем объект контрагента для редактирования
КонтрагентОбъект = Выборка.Ссылка.ПолучитьОбъект();
// Вариант А: Очищаем битую ссылку, если контрагента нужно сохранить
// КонтрагентОбъект.Партнер = Справочники.Партнеры.ПустаяСсылка();
// КонтрагентОбъект.Записать();
// Вариант Б: Полностью удаляем фантомного контрагента из базы
КонтрагентОбъект.УстановитьПометкуУдаления(Истина);
// Если требуется непосредственное удаление:
// КонтрагентОбъект.Удалить();
Сообщить("Обработан контрагент: " + Выборка.Ссылка);
КонецЦикла;
ЗафиксироватьТранзакцию();
Сообщить("Очистка успешно завершена!");
Исключение
ОтменитьТранзакцию();
Сообщить("Произошла ошибка при обработке: " + ОписаниеОшибки());
КонецПопытки;
Иначе
Сообщить("Фантомных контрагентов с битыми ссылками не обнаружено.");
КонецЕсли;
Этот скрипт можно запустить через внешнюю обработку в режиме «1С:Предприятие». Он эффективно находит все проблемные записи, где реквизит Партнер ссылается на несуществующий GUID, и помечает их на удаление, освобождая ИНН для создания новых корректных карточек.
---
Чтобы избежать подобных проблем при переносе данных в будущем, всегда придерживайтесь следующих правил:
Контрагенты всегда включайте в пакет выгрузки справочник Партнеры. Они представляют собой неделимую логическую пару.