При работе в конфигурациях на базе 1С:ERP (например, в подсистеме Казначейство при открытии взаимозачетов задолженности) мы можем столкнуться с ситуацией, когда динамические списки начинают сбоить или отображать пустые строки. Проанализируем эту ситуацию: чаще всего причиной такого поведения являются битые ссылки в служебном регистре сведений РеестрДокументов. Рассмотрим подробнее, откуда они берутся и как мы можем их корректно вычистить.
Регистр РеестрДокументов является вспомогательным и используется для оптимизации вывода списков. Данные в него пишутся подписками на события при проведении или записи документов. Разберем основные причины появления записей вида "Объект не найден":
ОбменДанными.Загрузка = Истина), ссылочная целостность нарушается. Документа больше нет, а запись в реестре осталась.Посмотрим на пример того, как правильно составить запрос для поиска. Распространенной ошибкой является попытка проверить саму ссылку на NULL (например, РеестрДокументов.Ссылка ЕСТЬ NULL). Это не сработает, так как в регистре физически хранится уникальный идентификатор (GUID), и поле не является пустым. Но сам объект по этому идентификатору отсутствует.
Выясним правильный подход: нам нужно обратиться к любому обязательному реквизиту ссылки через точку. При таком обращении платформа 1С на уровне СУБД выполнит левое соединение (LEFT JOIN) с таблицей документа. Так как документа нет, результат соединения для реквизита вернет NULL.
Рассмотрим рабочий пример запроса:
ВЫБРАТЬ
РеестрДокументов.Ссылка КАК Ссылка,
РеестрДокументов.ДатаДокументаИБ КАК ДатаДокументаИБ
ИЗ
РегистрСведений.РеестрДокументов КАК РеестрДокументов
ГДЕ
РеестрДокументов.ДатаДокументаИБ >= &ДатаНачала
И РеестрДокументов.ДатаДокументаИБ <= &ДатаОкончания
И РеестрДокументов.Ссылка.Номер ЕСТЬ NULL
В данном коде условие РеестрДокументов.Ссылка.Номер ЕСТЬ NULL является ключевым. Оно безошибочно выявляет все записи, где ссылка превратилась в "Объект не найден".
Проанализируем доступные методы исправления ситуации. Мы можем пойти несколькими путями в зависимости от масштаба проблемы.
Способ 1: Программное удаление через набор записей
Если мы нашли конкретные битые ссылки, мы можем написать небольшую обработку для их точечного удаления. Для регистра сведений необходимо создать набор записей, установить отбор и записать его пустым. Посмотрим на пример кода:
// Передаем выявленную битую ссылку в переменную БитаяСсылка
Набор = РегистрыСведений.РеестрДокументов.СоздатьНаборЗаписей();
// Устанавливаем отбор по ключевому измерению
Набор.Отбор.Ссылка.Установить(БитаяСсылка);
// Записываем пустой набор, что приводит к удалению записей по отбору
Набор.Записать(Истина);
Способ 2: Тестирование и исправление (ТиИ)
Если проблема массовая, воспользуемся конфигуратором. Запуск стандартной процедуры "Тестирование и исправление информационной базы" с установленными галочками на удаление несуществующих объектов (очистку ссылок) автоматически вычистит мусор. Этот процесс может занять время, поэтому его стоит выполнять на копии базы, а затем в рабочей базе во внерабочее время.
Способ 3: Перезапись "живых" документов
Если записи в реестре просто "разъехались" с реальными данными (например, документ есть, а в реестре его не видно, или он задвоен), мы можем применить групповую обработку справочников и документов. Отберем нужный вид документов и просто перепроведем или перезапишем их. Подписки на события отработают штатно и пересоздадут правильные строки в РеестрДокументов.
Способ 4: Использование инструментов разработчика
Рассмотрим альтернативный вариант. Существуют популярные расширения и подсистемы для разработчиков 1С, включающие продвинутые консоли запросов и редакторы регистров. С их помощью мы можем выполнить запрос, увидеть проблемные строки (часто они подсвечиваются красным) и удалить их прямо из интерфейса редактора наборов записей, не прибегая к написанию кода.
Применяя данные подходы, мы сможем быстро стабилизировать работу динамических списков и избавиться от назойливых фантомных записей в системе.