Как эффективно удалить проводки с удалённым регистратором в 1С, когда ТИИ не справляется?

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

При работе с крупными базами данных 1С, особенно после некорректного удаления документов или ошибок при обмене данными, мы часто сталкиваемся с проблемой "битых ссылок". Это ситуации, когда записи в регистрах (например, проводки в регистре бухгалтерии или движения в регистрах накопления) ссылаются на регистраторы (документы), которые фактически уже удалены из базы. Стандартные механизмы платформы 1С, такие как "Тестирование и исправление информационной базы" (ТИИ), могут не справляться с большим объемом таких повреждений, либо их выполнение занимает неприемлемо много времени и даже приводит к сбоям.

Давайте разберем, почему возникают такие ситуации и как мы можем эффективно удалить проводки с удалёнными регистраторами, используя как средства SQL, так и специализированные обработки 1С.

Причины возникновения битых ссылок

Прежде чем перейти к методам устранения, давайте выясним основные причины появления этих "битых" связей:

  1. Прямое удаление объектов без контроля: Наиболее частая причина. Если мы удаляем документ, не проверяя, используется ли он где-либо еще (особенно с использованием горячих клавиш Shift + Delete), его ссылки в регистрах остаются "висячими".
  2. Ошибки при синхронизации между базами: При обмене данными могут возникать ситуации, когда объект удаляется в одной базе, но не удаляется связанная информация в другой, или наоборот.
  3. Аварийное завершение работы: Сбои системы, отключение электроэнергии или аварийное завершение работы 1С в процессе записи данных могут привести к частичной фиксации изменений и появлению поврежденных ссылок.
  4. Некорректное обновление конфигурации: Иногда, после обновления конфигурации, метаданные могут быть повреждены, что влияет на целостность ссылок.
  5. Ручная правка данных через SQL: Это самый рискованный метод, который, если выполнен некорректно, может привести к массовому появлению битых ссылок.

Идентификация битых ссылок

Как мы можем понять, что у нас есть битые ссылки?

Подготовка к удалению: меры предосторожности и повышение производительности

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

  1. Полное резервное копирование базы данных: Это критически важный шаг. Перед любой операцией, которая предполагает массовое изменение или удаление данных, особенно прямыми SQL-запросами, мы обязаны сделать полную резервную копию. Это позволит нам вернуться к исходному состоянию в случае непредвиденных проблем.
  2. Работа на копии базы: Мы всегда должны сначала проводить все эксперименты и массовые операции на копии рабочей базы. Никогда не работаем с продуктивной базой напрямую, пока не будем полностью уверены в корректности и безопасности наших действий.
  3. Отключение итогов регистров: Это значительно ускорит процесс удаления движений. Когда итоги включены, каждое изменение или удаление записи в регистре приводит к их пересчету, что существенно замедляет операцию, особенно на больших объемах данных. Мы можем отключить итоги через конфигуратор или специальные обработки, такие как "Инструменты разработчика" (ИР) или "Консоль запросов", которые позволяют управлять состоянием итогов для регистров бухгалтерии и накопления.
  4. Оптимизация SQL-сервера (при использовании SQL-метода): Для больших баз и массовых операций очень важна производительность SQL-сервера. Мы можем обновить статистики, выполнить дефрагментацию индексов и реиндексацию таблиц. Это обеспечит наилучшую скорость выполнения наших запросов.

Метод 1: Прямое удаление через SQL-запросы

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

Почему SQL быстрее?

Инструменты 1С, даже такие как ТИИ, при удалении большого объема записей, как правило, используют оператор DELETE для каждой записи в цикле или для набора записей, что является транзакционной операцией. Это очень медленно, когда речь идет о десятках миллионов строк.

В то же время, SQL-сервер позволяет нам выполнять массовые операции гораздо быстрее:

Идентификация таблиц и полей 1С в SQL

Для работы с SQL нам необходимо знать, как называются таблицы и поля 1С в базе данных SQL. Платформа 1С использует свои внутренние имена, которые преобразуются в более сложные названия в СУБД.

Пример SQL-запроса для удаления

Давайте рассмотрим, как мы можем найти и удалить движения регистра, ссылающиеся на несуществующие регистраторы. Нам нужно будет выполнить два шага:

  1. Найти отсутствующие регистраторы: Сначала мы выберем все уникальные _RecorderRRef из таблицы регистра, которые не имеют соответствующей записи в таблице документов.
  2. Удалить движения: Затем мы удалим все записи из регистра, у которых _RecorderRRef находится в списке найденных отсутствующих регистраторов.

Предположим, у нас есть регистр бухгалтерии с именем таблицы _AccRgNNNN и таблица документов (например, "Реализация товаров и услуг") с именем _DocumentNNNN.


-- Шаг 1: Определение таблицы регистра бухгалтерии (пример)
-- SELECT TOP 100 * FROM _AccRgXXXX; -- Замените XXXX на реальный номер регистра
-- SELECT TOP 100 * FROM _DocumentXXXX; -- Замените XXXX на реальный номер таблицы документа

-- Шаг 2: Отключаем итоги для регистра (если не сделали это ранее через 1С)
-- Это может потребовать специфических SQL-команд, зависящих от конфигурации,
-- но обычно проще сделать через 1С или просто быть готовыми к долгому пересчету.

-- Шаг 3: Удаление проводок с удаленным регистратором
DELETE FROM _AccRgNNNN -- Имя таблицы вашего регистра бухгалтерии (например, _AccRg15974)
WHERE _RecorderRRef IN (
    SELECT AccRg._RecorderRRef
    FROM _AccRgNNNN AS AccRg -- Таблица регистра
    LEFT JOIN _DocumentNNNN AS Doc -- Таблица соответствующего документа (например, _Document12345)
        ON AccRg._RecorderRRef = Doc._IDRRef
    WHERE Doc._IDRRef IS NULL
);

-- Важно: Если вы удаляли документ полностью, то ссылка на него в AccRg._RecorderRRef
-- будет указывать на несуществующий _IDRRef в соответствующей таблице документов.
-- Если же документ был помечен на удаление, но не удален физически, то
-- Doc._Marked будет = 1. В таком случае условие WHERE Doc._IDRRef IS NULL
-- не сработает, и нам нужно будет адаптировать запрос.
-- В данной задаче мы говорим об УДАЛЁННОМ регистраторе, то есть физически отсутствующем.

Особенности удаления движений по субконто: Удаление проводок из основной таблицы регистра может не удалить движения по субконто. При работе с SQL-запросами нам необходимо учитывать все связанные таблицы регистров, например, таблицы субконто для регистра бухгалтерии (_AccRgNNNNDt, _AccRgNNNNCt для дебетовых и кредитовых субконто). Для каждого регистра бухгалтерии могут быть свои таблицы субконто, которые также нужно будет очищать по полю _RecorderRRef.

Особенности работы с датами: В некоторых случаях, даты в SQL-таблицах 1С могут храниться со смещением года. Для корректной работы с датами через SQL мы можем учитывать значение из таблицы _YearOffset, хотя для удаления по _RecorderRRef это обычно не критично.

Выполнение таких операций требует глубоких знаний структуры базы данных 1С и SQL, а также крайней осторожности, так как некорректные действия могут привести к фатальным последствиям.

Метод 2: Использование специализированных обработок 1С

Если мы не имеем прямого доступа к SQL-серверу или не обладаем достаточными знаниями для прямого манипулирования базой данных, мы можем использовать специализированные внешние обработки 1С. Такие обработки могут работать медленнее, но они более безопасны, так как используют штатные механизмы платформы.

Принцип работы обработки

Специализированная обработка для удаления движений с неопределенным регистратором обычно выполняет следующие шаги:

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

Преимущества и недостатки метода 1С

Преимущества:

Недостатки:

Завершающие шаги после удаления

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

  1. Включение и пересчет итогов: Если мы отключали итоги регистров на этапе подготовки, теперь нам необходимо их включить и полностью пересчитать. Это можно сделать через стандартные средства 1С (конфигуратор, специальная обработка). Этот процесс может занять значительное время, но он важен для корректной работы отчетов и расчетов остатков/оборотов.
  2. Проверка целостности данных: После всех операций, мы должны запустить полное тестирование и исправление информационной базы в режиме конфигуратора (без попытки исправления, только с проверкой ссылочной целостности), чтобы убедиться, что проблема с битыми ссылками решена и не возникли новые. Также рекомендуем сформировать ключевые отчеты, чтобы проверить корректность данных.

Заключение

Удаление проводок с удалёнными регистраторами – это сложная и ответственная задача, требующая глубоких знаний и осторожности. Мы рассмотрели два основных подхода: быстрый и мощный SQL-метод, требующий высокой квалификации, и более безопасный, но медленный метод с использованием специализированных обработок 1С. Независимо от выбранного метода, всегда начинаем с резервного копирования и работаем только на копии базы! Такой подход поможет нам эффективно решить проблему, минимизируя риски для нашей информационной системы.

← На главную