Как удалить строки табличной части несуществующего документа в 1С

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

В процессе эксплуатации информационных баз 1С, особенно после аварийных сбоев, прерывания транзакций или некорректных обновлений конфигурации, можно столкнуться с нарушением ссылочной целостности данных. Типичный пример такой проблемы — появление «осиротевших» строк в табличных частях: физически строки в таблице существуют, но родительский документ был удален или поврежден, из-за чего обращение к ссылке возвращает <Объект не найден> или NULL.

Проанализируем ситуацию на примере запроса к табличной части документа:


ВЫБРАТЬ
    ЗаказКлиентаТовары.Ссылка КАК Ссылка,
    ЗаказКлиентаТовары.НомерСтроки КАК НомерСтроки,
    ЗаказКлиентаТовары.Номенклатура КАК Номенклатура
ИЗ
    Документ.ЗаказКлиента.Товары КАК ЗаказКлиентаТовары
ГДЕ
    ЗаказКлиентаТовары.Ссылка.Номер ЕСТЬ NULL

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

Способ 1. Штатное «Тестирование и исправление» информационной базы

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

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

Способ 2. Программное воссоздание документа по Уникальному Идентификатору

Если требуется удалить конкретные осиротевшие строки без полного тестирования всей базы данных, можно восстановить родительский документ по его УникальныйИдентификатор, связать его с висящими строками и затем удалить стандартными методами платформы.

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


// 1. Получаем список битых ссылок
Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ РАЗЛИЧНЫЕ
    |	ЗаказКлиентаТовары.Ссылка КАК Ссылка
    |ИЗ
    |	Документ.ЗаказКлиента.Товары КАК ЗаказКлиентаТовары
    |ГДЕ
    |	ЗаказКлиентаТовары.Ссылка.Номер ЕСТЬ NULL";

Выборка = Запрос.Выполнить().Выбрать();

Пока Выборка.Следующий() Цикл
    // Получаем GUID битой ссылки
    СсылкаНаОбъект = Выборка.Ссылка;
    
    // Создаем новый документ и явно назначаем ему сохраненную ссылку
    НовыйДокумент = Документы.ЗаказКлиента.СоздатьДокумент();
    НовыйДокумент.УстановитьСсылкуНового(СсылкаНаОбъект);
    
    // Записываем документ, чтобы восстановить ссылочную целостность
    НовыйДокумент.Записать();
    
    // Теперь документ существует в базе вместе со своими строками ТЧ
    // Удаляем его непосредственно или помечаем на удаление
    НовыйДокумент.Удалить();
КонецЦикла;

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

Способ 3. Прямая очистка на уровне СУБД (для клиент-серверного варианта)

В случаях, когда повреждения базы слишком масштабны или тестирование средствами конфигуратора завершается аварийно, можно прибегнуть к очистке на уровне реляционной СУБД (Microsoft SQL Server, PostgreSQL и др.).

  1. С помощью функции ПолучитьСтруктуруХраненияБазыДанных() определяем имя физической таблицы документа (шапки) и имя таблицы табличной части, а также имена полей ссылок.
  2. Составляем SQL-запрос для удаления строк из таблицы табличной части, у которых нет соответствия в таблице шапки документа:
    
    DELETE FROM _Document123_VT456
    WHERE _Document123_IDRRef NOT IN (
        SELECT _IDRRef FROM _Document123
    );
    
  3. После выполнения прямых изменений в СУБД необходимо обязательно очистить серверный кэш и перезапустить службу сервера 1С:Предприятие.

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

← На главную