Как исправить ошибку «Попытка вставки неуникального значения в уникальный индекс» в таблице итогов регистра бухгалтерии

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

При выполнении регламентного пересчета итогов, проведении документов или реструктуризации базы данных разработчики и администраторы 1С могут столкнуться с критической ошибкой СУБД: «Попытка вставки неуникального значения в уникальный индекс» по таблице с именем вида dbo._AccRgAT<N>. Разберем детально, что представляет собой эта таблица, почему возникает коллизия уникальности и какими способами можно полностью восстановить работоспособность базы данных.

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

Обратим внимание на отображение дат в СУБД: значения вида 4016-09-01 или 5999-11-01 в колонке _Period не являются признаком повреждения. Это стандартный механизм платформы 1С при работе с Microsoft SQL Server — смещение дат на 2000 лет вперед (смещение 2000 года), предназначенное для корректной обработки пустых и ранних дат.

Выясним основные причины возникновения дублей в уникальном индексе:

  1. Изменение структуры плана счетов: добавление, удаление или изменение порядка видов субконто на счетах без корректного обновления движений за прошлые периоды.
  2. Повреждение записей в таблице движений (_AccRg<N>): появление «битых» ссылок (неразрешенные GUID), некорректных значений NULL или физических дубликатов строк проводок.
  3. Прерванные транзакции или сбои обменов (РИБ): неполная фиксация пакетов данных, оставившая несогласованные проводки.
  4. Физическое повреждение страниц индекса в СУБД: разрушение B-дерева индекса без фактического наличия логических дублей.

Рассмотрим пошагово все способы исправления данной ошибки.

Способ 1. Программное отключение и пошаговый пересчет итогов

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

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


ИмяРегистра = "Хозрасчетный"; // Укажите имя вашего регистра бухгалтерии
МенеджерРегистра = РегистрыБухгалтерии[ИмяРегистра];

// Отключаем использование итогов
МенеджерРегистра.УстановитьИспользованиеИтогов(Ложь);

// Включаем использование итогов заново
МенеджерРегистра.УстановитьИспользованиеИтогов(Истина);

// Если ошибка возникает на конкретном интервале дат, выполняем пошаговый пересчет
ДатаСтарта = '20200101';
ДатаОкончания = ТекущаяДата();

ТекущийПериод = ДатаСтарта;
Пока ТекущийПериод <= ДатаОкончания Цикл
    КонецИнтервала = КонецМесяца(ТекущийПериод);
    МенеджерРегистра.ПересчитатьИтогиЗаПериод(ТекущийПериод, КонецИнтервала);
    ТекущийПериод = ДобавитьМесяц(ТекущийПериод, 1);
КонецЦикла;

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

Способ 2. Очистка таблицы итогов в СУБД (TRUNCATE) с последующим пересчетом

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

Разберем порядок действий:

  1. Обязательно создаем полную резервную копию базы данных перед любыми манипуляциями в Management Studio.
  2. Переводим информационную базу в монопольный режим и останавливаем службу сервера 1С:Предприятия.
  3. В среде SQL выполняем команду полной очистки проблемной таблицы оборотов: TRUNCATE TABLE dbo._AccRgAT21056;
  4. Запускаем службу сервера 1С, открываем базу в режиме Конфигуратор.
  5. Переходим в меню Администрирование — Тестирование и исправление....
  6. Устанавливаем флаги «Реструктуризация таблиц информационной базы» и «Пересчет итогов», после чего запускаем выполнение.

При выполнении этой процедуры платформа заново сформирует агрегированные обороты на основе существующих документов движения.

Способ 3. Поиск и исправление поврежденных проводок

Если после очистки таблицы агрегатов ошибка возникает снова на том же периоде, проанализируем исходные движения в основной таблице _AccRg<N>. Повторение ошибки свидетельствует о наличии дублирующихся строк в первичных движениях регистра.

Разберем алгоритм поиска:

  1. Определяем имя основной таблицы движений регистра через обработку получения структуры хранения базы данных или функцию ПолучитьСтруктуруХраненияБазыДанных().
  2. Выполняем группировочный SQL-запрос к таблице движений для поиска дублей по периоду, регистратору и строкам:
    
    SELECT _RecorderTRef, _RecorderRRef, _LineNo, COUNT(*) 
    FROM dbo._AccRg21056 
    GROUP BY _RecorderTRef, _RecorderRRef, _LineNo 
    HAVING COUNT(*) > 1;
    
  3. По полученным ссылкам находим проблемные документы-регистраторы в пользовательском режиме.
  4. Распроводим найденные документы, очищаем некорректные строки и проводим их повторно.

Способ 4. Обход через выгрузку в файловую базу (.dt)

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

  1. Выполняем выгрузку информационной базы в файл .dt через Конфигуратор.
  2. Создаем пустую локальную файловую базу и загружаем в нее полученный файл.
  3. В файловой базе запускаем полное Тестирование и исправление с пересчетом итогов (файловая СУБД использует собственный механизм перестроения таблиц).
  4. После успешного завершения выгружаем исправленную базу обратно в .dt и загружаем на рабочий SQL-сервер.

Важное предостережение: никогда не выполняйте прямых операций DELETE или UPDATE в основной таблице движений _AccRg на стороне СУБД. Это нарушит целостность ссылок между аналитикой, субконто и документами. Очищать вручную разрешается только вторичные агрегатные таблицы итогов (_AccRgAT, _AccRgED, _AccRgOpt), так как они полностью восстанавливаются платформой 1С при пересчете.

← На главную