Как исправить появление пустых строк и битых ссылок в отчетах 1С после удаления номенклатуры

Программист 1С v8.3 (Обычные формы) Управленческий учет Торговля и дистрибуция
← На главную

Каждый специалист по работе с платформой 1С:Предприятие рано или поздно сталкивается с ситуацией, когда после «глобальной чистки» базы данных отчеты по остаткам (сток) начинают вести себя непредсказуемо. В них появляются пустые строки либо пугающие записи вида <Объект не найден> (уникальный идентификатор GUID), напротив которых отображаются вполне реальные цифры остатков и сумм.

В этой статье мы подробно разберем, почему возникает эта проблема, как устроена ссылочная целостность в 1С, и проанализируем по шагам все способы исправления ситуации — от стандартных утилит до написания корректирующего кода.

Выясняем причину: почему в отчетах отображается «непонятно что»?

Для того чтобы понять природу этой ошибки, нам необходимо заглянуть под капот платформы 1С. Когда пользователь удаляет элемент справочника (например, Номенклатуру) или документ, крайне важно делать это через типовой механизм контроля ссылок. Если же удаление происходит напрямую программным методом Удалить() или через сторонние «быстрые» обработки, отключающие проверку связей, данные стираются только из основной таблицы самого объекта.

Однако учет движений товаров, взаиморасчетов и остатков в 1С ведется в специальных физических таблицах — регистрах накопления и регистрах сведений. Записи в этих регистрах хранят не текстовые наименования, а уникальные 128-битные идентификаторы объектов — GUID (UUID).

При «жестком» удалении номенклатуры происходят следующие процессы:

  1. Запись в таблице справочника Справочник.Номенклатура полностью физически удаляется из базы данных SQL или файлового хранилища.
  2. Записи движений в регистре накопления (например, РегистрНакопления.ТоварыНаСкладах), которые ссылались на этот товар по его GUID, остаются нетронутыми, поскольку проверка связей была отключена.
  3. При формировании отчета система делает запрос к регистру накопления, считывает оттуда движения и пытается сопоставить сохраненный GUID с таблицей справочника Номенклатура, чтобы вывести красивое наименование товара.
  4. Не найдя соответствующей строки в справочнике, платформа выводит текстовую заглушку <Объект не найден> или просто пустую строку, но при этом выводит числовые показатели (остатки), которые «зависли» в регистре. В профессиональной среде такие ссылки называют «битыми».

Решение 1: Исправление проблемы через Конфигуратор («Тестирование и исправление»)

Самым надежным и стандартным способом решения проблемы является использование встроенной утилиты администрирования платформы. Разберем этот процесс по шагам.

Важно: Перед выполнением любых административных процедур в Конфигураторе строго обязательно создайте резервную копию вашей информационной базы! Любые операции по лечению битых ссылок необратимы.

  1. Запустите информационную базу в режиме Конфигуратор под пользователем с полными административными правами.
  2. Убедитесь, что в базе не работают другие пользователи. Для этого можно воспользоваться меню Администрирование — Активные пользователи.
  3. Перейдите в меню Администрирование — Тестирование и исправление....
  4. В открывшемся окне настроек установите флажок напротив пункта «Проверка ссылочной целостности информационной базы».
  5. В нижней части окна настройте правила обработки найденных ошибок:
    • «При наличии битых ссылок»: выберите переключатель «Очищать ссылки». В этом случае система найдет все «зависшие» движения в регистрах по удаленным товарам и корректно очистит их. Остатки по несуществующим позициям обнулятся и полностью исчезнут из отчетов.
    • Если вашей целью является восстановление удаленных объектов (например, если они были стерты по ошибке и вам нужно вручную вернуть им названия), выберите «Создавать объекты». Система сгенерирует новые пустые элементы-заглушки справочника с теми же GUID, и в отчетах вместо битых ссылок появятся пустые строки, которые вы сможете заполнить нужными именами.
  6. Также обязательно установите флажок «Пересчет итогов». После очистки ссылок таблицы предварительно рассчитанных итогов регистров могут остаться рассинхронизированными. Пересчет итогов обновит агрегированные данные, благодаря чему отчеты начнут показывать корректную информацию.
  7. Нажмите кнопку «Выполнить» и дождитесь завершения процесса.

Решение 2: Программное исправление и поиск битых ссылок

Если база данных имеет огромный объем (сотни гигабайт), запуск полного «Тестирования и исправления» может занять слишком много времени (вплоть до нескольких суток простоя системы). В таких случаях программисты используют точечные программные методы локализации и устранения проблемы.

Рассмотрим, как обнаружить битую ссылку в конкретном регистре накопления с помощью запроса. В языке запросов 1С при попытке обратиться к реквизитам удаленного объекта через точку (например, Номенклатура.Наименование) система вернет значение NULL. Мы можем использовать это свойство для выявления ошибок.

Проанализируем пример кода для поиска битых ссылок в регистре остатков товаров:


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |	ТоварыНаСкладах.Номенклатура КАК БитыйТовар,
    |	ТоварыНаСкладах.Склад КАК Склад,
    |	ТоварыНаСкладах.КоличествоОстаток КАК Количество
    |ИЗ
    |	РегистрНакопления.ТоварыНаСкладах.Остатки КАК ТоварыНаСкладах
    |ГДЕ
    |	ТоварыНаСкладах.Номенклатура.ВерсияДанных ЕСТЬ NULL
    |	И ТоварыНаСкладах.Номенклатура <> ЗНАЧЕНИЕ(Справочник.Номенклатура.ПустаяСсылка)";

РезультатЗапроса = Запрос.Выполнить();
Если Не РезультатЗапроса.Пустой() Тогда
    Выборка = РезультатЗапроса.Выбрать();
    Пока Выборка.Следующий() Цикл
        // Здесь мы можем зафиксировать битые ссылки или программно очистить движения
        ЗаписьЖурналаРегистрации("ОшибкиДанных", УровеньЖурналаРегистрации.Предупреждение, , , 
            "Найден битый товар: " + Выборка.БитыйТовар + " на складе " + Выборка.Склад);
    КонецЦикла;
КонецЕсли;

Для исправления таких записей без полного тестирования базы можно использовать специализированные внешние обработки с порталов Инфостарт или встроенные инструменты из состава «Библиотеки стандартных подсистем» (БСП), такие как обработка «Поиск и замена дублей» или «Поиск и удаление битых ссылок». Они позволяют перенаправить все движения с битого GUID на один специально созданный технический элемент справочника (например, элемент с наименованием «Удаленный товар»).

Рекомендации для разработчиков: как не допустить появления битых ссылок в будущем?

Для того чтобы ситуация не повторилась, необходимо полностью отказаться от практики непосредственного жесткого удаления объектов из базы данных программным путем. Метод Удалить() должен использоваться только в исключительных случаях на этапе отладки или первоначального заполнения пустой базы.

Рассмотрим правильный подход к удалению данных на примере кода. Вместо удаления объекта мы должны лишь устанавливать пометку удаления, позволяя платформе контролировать связи:


// ПРИМЕР НЕПРАВИЛЬНОГО И ОПАСНОГО УДАЛЕНИЯ (вызывает появление битых ссылок):
// СсылкаНаОбъект.ПолучитьОбъект().Удалить(); 

// ПРИМЕР ПРАВИЛЬНОГО И БЕЗОПАСНОГО УДАЛЕНИЯ:
СсылкаНаНоменклатуру = Справочники.Номенклатура.НайтиПоКоду("0000000125");
Если Не СсылкаНаНоменклатуру.Пустая() Тогда
    ОбъектНоменклатуры = СсылкаНаНоменклатуру.ПолучитьОбъект();
    // Устанавливаем пометку удаления для самого элемента и его подчиненных структур
    ОбъектНоменклатуры.УстановитьПометкуУдаления(Истина, Истина);
    ОбъектНоменклатуры.Записать();
КонецЕсли;

После того как все ненужные объекты помечены на удаление, их окончательное физическое удаление должен производить только администратор базы через стандартный интерактивный интерфейс «Удаление помеченных объектов» (в режиме предприятия). Этот механизм гарантирует, что ни один объект не будет удален, если на него ссылается хотя бы один документ, проводка или запись регистра в системе.

← На главную