В практике разработки на платформе 1С:Предприятие мы часто сталкиваемся с задачами по очистке данных. Казалось бы, механизмы платформы отлажены годами: если мы используем независимый регистр сведений и устанавливаем для измерения флаг «Ведущее», мы ожидаем, что платформа сама позаботится о целостности данных. Логика проста: удаляем элемент справочника — автоматически удаляются все записи регистра, где этот элемент выступал в роли ведущего измерения. При необходимости полностью очистить базу от данных конкретной фирмы в типовых конфигурациях применяется обработка для рекурсивного выборочного удаления организаций.
Однако иногда возникает ситуация, когда этот механизм дает сбой. Вы удаляете объект, а запись в регистре остается, но вместо красивого названия элемента вы видите пугающую надпись <Объект не найден...>. Давайте подробно разберем, почему так происходит, какие скрытые механизмы платформы на это влияют и как правильно выполнять программное удаление данных.
Для начала давайте вспомним теорию. В независимых регистрах сведений свойство измерения Ведущее (Master) играет критическую роль в поддержании ссылочной целостности базы данных.
Когда вы устанавливаете этот флаг, вы сообщаете платформе следующее:
В штатном режиме работы, когда пользователь или программный код удаляет элемент справочника (или документ), платформа автоматически инициирует транзакцию, в которой ищет все записи регистров, где этот объект является ведущим измерением, и удаляет их. Это называется каскадным удалением.
Также стоит отметить важный нюанс, который мы выяснили в ходе анализа: если в регистре сведений несколько ведущих измерений, то работает логика «ИЛИ». Удаление значения любого из ведущих измерений влечет за собой удаление всей записи регистра.
Вернемся к нашей проблеме. Мы выполняем удаление объекта, но каскадное удаление не срабатывает. В регистре остается запись, хранящая уникальный идентификатор (GUID) удаленного объекта, которому в базе данных уже ничего не соответствует. Визуально это отображается как <Объект не найден>.
Если мы исключим очевидные ошибки (например, забыли поставить флаг «Ведущее» в конфигураторе), то наиболее вероятная причина кроется в режиме выполнения кода удаления.
Разберем свойство ОбменДанными.Загрузка.
У любого ссылочного объекта (СправочникОбъект, ДокументОбъект и т.д.) есть свойство ОбменДанными, у которого, в свою очередь, есть булево свойство Загрузка.
// Пример кода, который приводит к ошибке
Объект = СсылкаНаНоменклатуру.ПолучитьОбъект();
Объект.ОбменДанными.Загрузка = Истина;
Объект.Удалить();
Давайте проанализируем, что делает платформа, когда видит ОбменДанными.Загрузка = Истина:
Установка этого свойства в Истина при удалении говорит системе: «Просто физически удали эту запись из таблицы справочника, не трать время на поиск связей». Именно поэтому запись из справочника исчезает, а связанная запись в регистре сведений остается нетронутой, превращаясь в «битую ссылку».
Если ваша задача — удалить объект так, чтобы сработали все механизмы платформы, включая очистку ведущих измерений, вы не должны включать режим загрузки данных.
Правильный код для программного удаления выглядит так:
Попытка
Объект = СсылкаНаУдаление.ПолучитьОбъект();
// Явно указываем Ложь (по умолчанию оно и так Ложь, но для наглядности)
// или просто не трогаем это свойство.
Объект.ОбменДанными.Загрузка = Ложь;
Объект.Удалить();
Исключение
// Обработка ошибки, если удалить нельзя (например, есть ссылки не в ведущих измерениях)
Сообщить("Не удалось удалить объект: " + ОписаниеОшибки());
КонецПопытки;
При выполнении метода Удалить() без флага загрузки, платформа:
Если в процессе удаления записей регистра произойдет ошибка (например, сработает запрет в подписке на событие регистра), то отменится и удаление основного объекта.
Если вы обнаружили в базе записи с <Объект не найден> в ведущих измерениях, это свидетельствует о нарушении ссылочной целостности (логической целостности данных). Такое часто случается после некорректно написанных обработок очистки данных или загрузок обменов. Для комплексного выявления таких записей во всей информационной базе подойдёт обработка для поиска битых ссылок «Объект не найден».
Исправить это можно стандартными средствами платформы: при большом количестве информационных баз процедура автоматизируется через программу для пакетного архивирования, обновления и тестирования 1С.
Будьте осторожны с тестированием и исправлением на рабочих базах, обязательно делайте резервную копию перед запуском. В качестве альтернативы полному тестированию базы для точечной очистки или корректировки данных можно использовать универсальную обработку регистров сведений для удаления и замены записей по фильтрам.
Подведем итог нашему расследованию:
ОбменДанными.Загрузка = Истина.Удалить() без модификации параметров обмена данными.