При разработке и отладке обработок в 1С можно столкнуться с ситуацией, когда непроведенные документы формируют движения в подчиненных регистрах накопления. При этом в поле «Регистратор» у движений отображается «Объект не найден». Проанализируем, почему возникает подобное поведение платформы, как локализовать место записи в коде и как правильно очистить такие данные.
В платформе 1С:Предприятие для регистров накопления с режимом записи «Подчинен регистратору» контролируется только заполнение поля регистратора и соответствие его типа допустимым типам метаданных. При этом физическое существование документа в базе данных при программной записи набора платформа не проверяет.
Разберем механизм возникновения битых ссылок. Если в коде обработки или модуля вызывается метод получения новой ссылки ПолучитьСсылку() для еще не сохраненного документа, а затем создается набор записей регистра с отбором по этой ссылке, данные успешно сохраняются в СУБД. Однако сам объект документа не записывается и не проводится. В результате в базе появляется запись регистра, ссылающаяся на несуществующий идентификатор документа, что в пользовательском интерфейсе отображается как «Объект не найден».
Посмотрим на пример кода, который формирует движение в подчиненном регистре без записи и проведения документа:
// Получаем ссылку для еще не записанного документа
ДокПоступления = Документы.ПоступлениеТоваровУслуг.ПолучитьСсылку();
// Создаем набор записей регистра накопления
НаборЗаписей = РегистрыНакопления.ТоварыНаСкладах.СоздатьНаборЗаписей();
НаборЗаписей.Отбор.Регистратор.Установить(ДокПоступления.Ссылка);
// Формируем движение
ЗаписьВНабор = НаборЗаписей.Добавить();
ЗаписьВНабор.Период = ТекущаяДата();
ЗаписьВНабор.Количество = 1000;
ЗаписьВНабор.ВидДвижения = ВидДвиженияНакопления.Приход;
// Записываем набор в базу данных
НаборЗаписей.Записать();
После выполнения этого кода запись появится в регистре ТоварыНаСкладах, несмотря на то, что сам документ ПоступлениеТоваровУслуг физически не записан и не проведен.
Выясним, почему стандартный текстовый поиск по названию регистра часто не дает результатов, и какие способы помогают точно локализовать место записи.
РасчетЗарплатыБазовый.ЗаполнитьНДФЛиВзносы) имена регистров часто не прописываются явно. Они формируются через метаданные, структуры или общие функции. Из-за этого глобальный поиск по имени регистра (например, СведенияОДоходахНДФЛ) не находит точку вызова..Записать() у наборов записей или обращениям к модулям расчета зарплаты и налогов.РасчетЗарплатыБазовый.ЗаполнитьНДФЛиВзносы). В этих процедурах типовые механизмы сначала очищают старые движения, а затем формируют новые наборы записей.log.xml) с отбором по имени таблицы регистра СУБД (например, AccumRG<ID>) и событию обращения к СУБД. В поле стека вызовов (stktrc) отобразится конкретный модуль и строка кода 1С, выполнившая SQL-запрос INSERT.Рассмотрим способы очистки регистра накопления от зависших записей.
Способ 1. Программная очистка через пустой набор записей
Для удаления битых записей достаточно сформировать набор записей с отбором по несуществующей ссылке-регистратору и записать его пустым:
// Создаем набор записей
НаборЗаписей = РегистрыНакопления.УчетДоходовДляИсчисленияНДФЛ.СоздатьНаборЗаписей();
// Устанавливаем отбор по битой ссылке
НаборЗаписей.Отбор.Регистратор.Установить(СсылкаНаНесуществующийОбъект);
// Запись пустого набора удаляет движения из СУБД
НаборЗаписей.Записать();
Способ 2. Штатное тестирование и исправление
Запустим процедуру «Тестирование и исправление информационной базы» из режима Конфигуратора. Отметим флаг проверки ссылочной целостности и укажем вариант действия «При наличии ссылок на несуществующие объекты — Очищать ссылки» или «Удалять объект». Платформа автоматически найдет записи регистров с битыми ссылками на регистратор и удалит их.