Почему удаленные элементы справочника отображаются в отчетах и реквизитах 1С и как это исправить?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

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

Причина 1. Нарушение ссылочной целостности и появление «битых ссылок»

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

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

Выясним причины, по которым это происходит, ведь пользователь может быть уверен, что удалял элементы через стандартную «Пометку на удаление» и «Удаление помеченных объектов»:

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

Причина 2. Почему пустой регистр все равно выводит данные в отчетах

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

Большинство отчетов в 1С строятся не на реальных таблицах движений регистров, а на базе виртуальных таблиц (например, РегистрНакопления.Продажи.Обороты или РегистрНакопления.ТоварыНаСкладах.Остатки). Для повышения быстродействия СУБД хранит уже рассчитанные итоги на начало каждого месяца в специальных таблицах итогов.

Если транзакция удаления документов или записей регистра прервалась аварийно, либо объект был удален некорректно программным путем, таблицы реальных движений очищаются, а вспомогательные таблицы итогов остаются заполненными. Из-за этого расхождения отчет продолжает «видеть» несуществующие остатки по удаленным элементам номенклатуры.

Причина 3. Особенности работы механизма «История выбора»

Даже после полного удаления объекта он может продолжать отображаться в выпадающем списке при вводе первых букв в поле реквизита. Это не баг, а штатное поведение платформы, выполняющее роль кэширования для удобства пользователя.

История выбора сохраняется индивидуально для каждого пользователя в специальной системной таблице базы данных (ХранилищеСистемныхНастроек). При открытии формы или начале ввода платформа не делает тяжелых запросов к базе данных для проверки существования элементов в истории — она просто выводит закэшированные строки. Проверка актуальности ссылки происходит только в момент непосредственного клика по строке, из-за чего и возникает ошибка выбора.


Решение 1. Использование механизма «Тестирование и исправление» (ТиИ)

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

Рассмотрим по шагам процесс запуска этой процедуры:

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

Решение 2. Очистка истории выбора (удаление «призраков» из кэша)

Если элементы были удалены корректно, но продолжают мозолить глаза пользователям в подсказках при вводе, необходимо очистить историю выбора. Сделать это можно несколькими способами.

Способ А. Интерактивная очистка через интерфейс (для конфигураций на БСП):

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

Способ Б. Программная очистка для администратора:

Если вам необходимо быстро очистить историю выбора по определенному пользователю или по всем пользователям сразу без монопольного режима, вы можете запустить внешнюю обработку со следующим кодом:


// Очистка истории выбора для конкретного пользователя
ИмяПользователя = "ИвановИИ";
ХранилищеСистемныхНастроек.Удалить("ИсторияВыбора", , ИмяПользователя);

// Способ полной очистки истории выбора для текущего пользователя
ХранилищеСистемныхНастроек.Удалить("ИсторияВыбора", , ИмяПользователяИнформационнойБазы());

Также разработчик может превентивно отключить сохранение истории выбора для конкретного реквизита на форме. Для этого в свойствах поля ввода (в конфигураторе) нужно установить свойство ИсторияВыбораПриВводе в значение Не использовать.

Решение 3. Поиск и исправление битых ссылок без монопольного режима

На крупных предприятиях остановить работу базы данных для проведения «Тестирования и исправления» в Конфигураторе бывает крайне проблематично. Выясним, как найти и устранить битые ссылки в режиме «1С:Предприятие» («на лету»):

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

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

РезультатЗапроса = Запрос.Выполнить();
Если Не РезультатЗапроса.Пустой() Тогда
    Выборка = РезультатЗапроса.Выбрать();
    Пока Выборка.Следующий() Цикл
        Сообщить("Найден битый элемент в документе: " + Выборка.ДокументСсылка);
    КонецЦикла;
КонецЕсли;

Этот метод основан на том, что у удаленного элемента отсутствует представление в базе данных (оно возвращает значение NULL), в то время как сама ссылка заполнена и не равна ПустаяСсылка.

Решение 4. Восстановление элемента по GUID

Если элемент справочника был удален случайно, но у вас сохранилась копия базы данных (даже старая), где этот элемент еще существовал, вы можете восстановить его с сохранением оригинального идентификатора (GUID). Для этого:

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

Проанализировав все возможные варианты, мы видим, что наиболее быстрым и комплексным решением для файловых и небольших клиент-серверных баз является штатное Тестирование и исправление, дополненное периодической очисткой кэша истории выбора пользователей.

← На главную