Как удалить избыточное количество записей в регистре накопления 1С:Комплексная автоматизация 2

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

В процессе эксплуатации систем на базе 1С:Комплексная автоматизация 2 или 1С:ERP пользователи могут столкнуться с аномальным разрастанием регистров накопления. Типичная ситуация: из-за ошибок в алгоритмах закрытия месяца или некорректного сторнирования документов в регистре (например, КУДИР) создаются десятки миллионов дублирующихся записей по одному и тому же регистратору. Попытки стандартного удаления таких данных через отмену проведения документа или программную очистку набора записей часто заканчиваются неудачей с ошибкой numeric field overflow или разрывом соединения с сервером. Разберем детально, как решить эту проблему, сохранив работоспособность базы данных.

Выясним причину ошибки: почему 1С не дает удалить записи

Рассмотрим природу ошибки numeric field overflow. В СУБД (особенно часто это проявляется на PostgreSQL) для полей типа «число» задана определенная разрядность. В структуре таблиц 1С для регистров накопления существует служебное поле _LineNo (номер строки). Платформа накладывает ограничение на точность этого поля. Если количество строк по одному регистратору превышает 10 миллионов (10^7), СУБД блокирует любые операции с этим набором данных, так как внутренний счетчик строк выходит за пределы допустимого диапазона.

Кроме того, при попытке прочитать 34 миллиона записей в оперативную память через стандартный РегистрНакопленияНаборЗаписей, сервер 1С формирует огромный POST-запрос к СУБД, который может прерываться по таймауту или из-за нехватки ресурсов (ошибка /e1cib/logForm).

Способ 1: Программная очистка с отключением проверок

Если объем данных велик, но еще не достиг критического порога блокировки СУБД, первым делом стоит попробовать стандартный метод 1С с использованием свойства ОбменДанными.Загрузка. Это позволит пропустить часть проверок и ускорить процесс.

Проанализируем пример кода для очистки регистра по конкретному документу:


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

Важный нюанс: Если записей более 10 миллионов, метод Набор.Записать() все равно может выдать ошибку переполнения, так как платформа пытается вычислить итоги или проверить структуру таблицы перед транзакцией.

Способ 2: Отключение итогов регистра — обязательный шаг

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

  1. Переходим в консоль кода или создаем внешнюю обработку.
  2. Выполняем команду: РегистрыНакопления.КнигаУчетаДоходовИРасходов.УстановитьИспользованиеИтогов(Ложь);
  3. После этого пробуем выполнить очистку из Способа 1.
  4. По завершении обязательно возвращаем использование итогов: РегистрыНакопления.КнигаУчетаДоходовИРасходов.УстановитьИспользованиеИтогов(Истина); и запускаем полный пересчет итогов.

Способ 3: Прямое удаление через SQL (Direct SQL)

Если платформа 1С отказывается работать с набором данных из-за ошибки numeric field overflow, нам придется обратиться напрямую к средствам СУБД. Рассмотрим этот процесс на примере PostgreSQL.

Проанализируем последовательность действий:

  1. Выясним имя физической таблицы регистра в базе данных. Для этого в 1С воспользуемся функцией ПолучитьСтруктуруХраненияБазыДанных(). Имя таблицы будет выглядеть примерно как _AccumReg12345.
  2. Найдем внутренний идентификатор (UUID) документа-регистратора. В SQL-таблице он хранится в поле _RecorderRRef.
  3. Выполним запрос на удаление в консоли pgAdmin или DBeaver:

-- Будьте крайне осторожны! Сначала выполните SELECT для проверки
DELETE FROM _AccumReg12345 
WHERE _RecorderRRef = '\x80e1005056915b2211eb668661706692';

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

Способ 4: Радикальный метод (Выгрузка — Очистка — Загрузка)

Если прямая работа с SQL затруднена, а документ содержит 90% всех записей регистра, можно рассмотреть метод «переливки» данных. Разберем этот алгоритм:

  1. Выгружаем в XML-файл (используя стандартную обработку «Выгрузка загрузка данных XML») все записи регистра кроме тех, что относятся к проблемному регистратору.
  2. Выполняем в SQL-консоли команду TRUNCATE TABLE _AccumReg12345;. Это мгновенно очистит всю таблицу регистра.
  3. Загружаем обратно данные из созданного XML-файла.
  4. Выполняем пересчет итогов в конфигураторе.

Этот метод гарантированно решает проблему переполнения, так как полностью пересоздает структуру данных в таблице.

Рекомендации по предотвращению проблемы

Выясним, почему такая ситуация стала возможной. В конфигурациях КА 2 и ERP подобные проблемы в регистре КУДИР часто возникают при использовании механизма сторнирования в закрытии месяца. Если регламентная операция завершается с ошибкой или прерывается, система может не удалить временные записи и при следующем запуске создать их повторно.

Рекомендуем применить следующие меры:

Совместное применение программных методов 1С и инструментов СУБД позволяет эффективно очистить базу от «мусорных» миллионов записей и вернуть системе быстродействие.

← На главную