Проблема появления «битых» записей или строк с пустыми значениями в поле Объект в регистре сведений КонтактнаяИнформация является классической для конфигураций на базе 1С:Предприятие 8.2, таких как «Бухгалтерия предприятия 2.0». Такие записи не только замусоривают базу данных, но и становятся критическим препятствием при выполнении синхронизации данных (например, с «Управление торговлей 11.4»), так как механизмы обмена не могут сопоставить данные и выдают ошибки сериализации.
В этой статье мы подробно разберем, почему возникают такие ситуации, почему стандартные методы удаления не срабатывают и как программно очистить регистр, используя профессиональные инструменты разработчика.
Прежде чем переходить к очистке, проанализируем ситуацию и поймем, откуда берутся записи без владельца. Основной объект (будь то контрагент, физическое лицо или организация) является ключевым измерением в регистре контактной информации. «Сироты» появляются в следующих случаях:
Удалить() вместо УстановитьПометкуУдаления(), при этом не контролируя ссылочную целостность, записи в независимых регистрах сведений остаются «подвешенными».Как отмечалось в обсуждении, попытка просто нажать кнопку «Удалить» или использовать стандартную обработку очистки часто заканчивается ошибкой: «Не удалось записать: Контактная информация!». Разберем по шагам, почему так происходит.
В конфигурации БП 2.0 регистр КонтактнаяИнформация имеет встроенную логику в модуле набора записей. В обработчике ПередЗаписью прописана проверка заполнения ключевых полей. Если поле Объект пустое или содержит значение Неопределено, система генерирует отказ в записи. Поскольку удаление в 1С технически является записью пустого набора по определенному фильтру, срабатывают те же самые проверки, которые «видят» некорректную запись и блокируют операцию.
Рассмотрим самый надежный способ очистки — написание небольшой обработки, которая принудительно удалит записи по фильтру пустого объекта. Для этого нам понадобится использовать объект РегистрСведенийНаборЗаписей.
Основная идея заключается в том, чтобы установить отбор по пустому значению и записать этот пустой набор в базу данных. Посмотрим на пример кода:
Процедура ОчиститьБитыеЗаписи()
// Создаем объект набора записей для нашего регистра
НаборЗаписей = РегистрыСведений.КонтактнаяИнформация.СоздатьНаборЗаписей();
// Устанавливаем фильтр по пустому объекту.
// Важно: тип объекта может быть разным (Справочник.Контрагенты, Справочник.ФизическиеЛица и т.д.)
// Если в поле битая ссылка, используем Неопределено или Пустую ссылку.
НаборЗаписей.Отбор.Объект.Установить(Справочники.Контрагенты.ПустаяСсылка());
// Попытка записи пустого набора приведет к удалению всех строк, попавших в фильтр
Попытка
НаборЗаписей.Записать();
Сообщить("Записи с пустыми контрагентами успешно удалены.");
Исключение
Сообщить("Ошибка при удалении: " + ОписаниеОшибки());
КонецПопытки;
КонецПроцедуры
Однако, как мы уже выяснили, простая запись может не сработать из-за проверок в модуле регистра. Поэтому перейдем к более мощному инструменту.
Для того чтобы обойти программные проверки в обработчиках ПередЗаписью и ПриЗаписи, программисты 1С используют специальное свойство набора записей — ОбменДанными.Загрузка = Истина. Рассмотрим подробнее, как это работает.
Когда это свойство установлено, платформа игнорирует прикладную логику, прописанную разработчиком конфигурации, и выполняет запись данных «как есть». Это именно то, что нужно для удаления «невозможных» с точки зрения логики программы данных.
Процедура УдалитьЗаписиСОбходомПроверок()
Набор = РегистрыСведений.КонтактнаяИнформация.СоздатьНаборЗаписей();
// Если нужно удалить вообще ВСЕ записи, где объект не определен
// Пройдемся в цикле по всем возможным типам или используем Неопределено
Набор.Отбор.Объект.Установить(Неопределено);
// Включаем режим загрузки для обхода встроенных проверок
Набор.ОбменДанными.Загрузка = Истина;
Попытка
Набор.Записать();
Сообщить("Очистка завершена успешно.");
Исключение
Сообщить("Даже режим загрузки не помог: " + ОписаниеОшибки());
КонецПопытки;
КонецПроцедуры
Проанализируем ситуацию, когда записей очень много или ссылки в поле Объект отображаются как «Объект не найден». В этом случае эффективно помогает штатный механизм «Тестирование и исправление», доступный в режиме Конфигуратора.
Разберем по шагам, как настроить ТиИ для нашей задачи:
Система автоматически просканирует все таблицы, включая КонтактнаяИнформация, обнаружит записи, ссылающиеся на удаленных контрагентов, и удалит их, так как они нарушают целостность базы данных.
Почему очистка так важна для обмена? При синхронизации через планы обмена система регистрирует изменения объектов. Когда очередь доходит до регистра сведений, XDTO-сериализатор пытается прочитать владельца (Объект). Если ссылка пустая или битая, тип объекта не может быть определен, и процесс выгрузки аварийно завершается с технической ошибкой. После удаления таких записей по методам, описанным выше, синхронизация должна возобновиться в штатном режиме.
Чтобы подобные «фантомные» записи не появлялись вновь, рекомендуем придерживаться следующих правил:
Во-первых, всегда удаляйте объекты через пометку удаления и стандартную обработку «Удаление помеченных объектов». Это гарантирует проверку всех связей.
Во-вторых, если вы используете сторонние обработки для загрузки данных, убедитесь, что в них реализован контроль заполнения обязательных полей перед вызовом метода Записать().
В-третьих, если база файловая, периодически проверяйте её утилитой chdbfl.exe. Она помогает исправить физические повреждения таблиц и индексов, которые иногда проявляются как «временные глюки» при записи или удалении данных.