При обновлении крупных или сильно доработанных баз данных на платформе 1С:Предприятие 8.3 (особенно конфигураций 1С:Бухгалтерия предприятия 3.0 КОРП) администраторы и программисты часто сталкиваются с неприятной системной ошибкой. Она блокирует запись, проведение или удаление ручных операций и любых других документов, формирующих проводки. Ошибка сопровождается длинным сообщением СУБД, в котором упоминается нарушение уникальности индекса.
Типичный текст ошибки выглядит следующим образом:
«Не удалось обработать данные документа Операция... Ошибка при вызове метода контекста (Записать). НаборЗаписей.Записать(Замещать); по причине: Попытка вставки неуникального значения в уникальный индекс: Microsoft SQL Server Native Client: Не удается вставить повторяющуюся строку ключа в объект "dbo._AccRgAT28408" с уникальным индексом "_AccRgAT28408_ByPeriod".»
В этой статье мы подробно разберем, почему возникает эта ошибка, рассмотрим внутреннюю структуру хранения итогов в 1С и изучим четыре практических метода ее решения — от самого безопасного (штатными средствами программы) до продвинутых манипуляций на уровне СУБД MS SQL Server.
---
Для начала проанализируем ситуацию и поймем, что скрывается под загадочным именем таблицы _AccRgAT28408. В платформе 1С все таблицы базы данных имеют стандартизированные префиксы:
_AccRg указывает на принадлежность таблицы к механизму Регистров бухгалтерии (Журнал проводок)._AccRgED означает таблицу дополнительных движений._AccRgAT обозначают таблицу итогов по счетам с субконто. Именно в ней хранятся рассчитанные остатки и обороты в разрезе периодов (обычно кратность составляет один месяц), счетов и субконто._ByPeriod является уникальным кластерным или некластерным индексом, который обеспечивает уникальность записей по ключевым полям: Период + Счет + Субконто + Измерения.Когда вы записываете ручную операцию или проводите документ, 1С не просто заносит данные в таблицу движений. Она параллельно пытается обновить или рассчитать новые физические итоги в таблице _AccRgAT. Если в процессе обновления конфигурации (например, при переходе на новые релизы БП 3.0 КОРП, когда меняется структура субконто на 81, 68.01 или других счетах) регламентные обработчики обновления отработали некорректно, в таблице итогов могут образоваться логические дубли.
С точки зрения СУБД MS SQL Server, попытка записать в уникальный индекс _ByPeriod строку с ключом, который там уже существует, является грубым нарушением целостности данных. В результате СУБД аварийно прерывает транзакцию (ошибка HRESULT=80040E2F, SQLSTATE=23000), и 1С сообщает о невозможности записать документ.
---
Многие специалисты первым делом запускают утилиту chdbfl.exe или выполняют Тестирование и исправление (ТИИ) в Конфигураторе. Однако в данной ситуации эти действия оказываются бесполезными:
Для исправления ситуации нам придется применить обходные технологические пути. Рассмотрим их по шагам.
---
Этот метод является самым мягким, так как он выполняется полностью штатными средствами платформы 1С:Предприятие, не требует прямого вмешательства в базу данных через SQL-запросы и подходит как для клиент-серверных, так и для файловых баз данных.
Рассмотрим по шагам, как обмануть систему записи итогов и восстановить работоспособность:
Администрирование — Обслуживание — раздел Регламентные операции. Найдите и откройте ссылку «Управление итогами и агрегатами» (в некоторых версиях этот инструмент доступен через «Функции для технического специалиста» -> Стандартные -> Управление итогами).Журнал проводок (бухгалтерский и налоговый учет).Итоги на панели инструментов и выберите команду «Выключить использование итогов». Также обязательно выполните команду «Выключить использование текущих итогов».Что произошло в этот момент? Платформа 1С временно деактивировала таблицы итогов (включая ту самую проблемную таблицу _AccRgAT28408). Теперь при проведении документов или ручных операций система будет писать движения напрямую в основную таблицу регистра, игнорируя расчет итогов.
Операция (бухгалтерский и налоговый учет), который вызывал ошибку) и выполните нужное действие: запишите ее, скорректируйте проводки или просто пометьте на удаление. Операция запишется мгновенно и без каких-либо ошибок со стороны MS SQL Server!При включении итогов платформа 1С автоматически инициирует фоновый полный пересчет итоговых таблиц с самого начала ведения учета. Поскольку логический тупик в движениях документов был нами устранен на шаге 6, пересчет завершится успешно, а структура индекса _ByPeriod будет сформирована в СУБД заново в абсолютно корректном виде.
---
Если база данных имеет огромный объем (сотни гигабайт или терабайты), стандартное отключение и последующее включение итогов через интерфейс 1С может затянуться на долгие часы или даже дни. В таком случае программисты и системные администраторы используют более радикальный, но очень быстрый способ сброса таблицы итогов через СУБД SQL Server.
Критически важно: Перед выполнением любых операций на уровне СУБД обязательно сделайте резервную копию (бэкап) базы данных! Некорректные действия в SQL Management Studio могут безвозвратно испортить данные.
Проанализируем этот метод по шагам:
New Query (Новый запрос)._AccRgAT28408). Для этого воспользуемся быстрой операцией очистки TRUNCATE TABLE. Вставьте в окно запроса следующий код:
USE [ИмяВашейБазыДанных];
GO
TRUNCATE TABLE _AccRgAT28408;
GO
1С:Предприятие.Администрирование — Тестирование и исправление....Платформа увидит, что таблица итогов _AccRgAT28408 абсолютно пуста, и заново рассчитает все итоги на основании записей из таблицы движений регистра бухгалтерии. После завершения операции верните пометки удаления с документов, если это необходимо.
---
Если вы не хотите полностью очищать таблицу итогов (например, хотите точечно решить проблему без длительного пересчета всей таблицы с нуля), можно временно удалить только сам уникальный индекс, мешающий записи данных.
Рассмотрим эту последовательность действий:
Tables — найдите таблицу dbo._AccRgAT28408 — разверните ветку Indexes._AccRgAT28408_ByPeriod).1С:Предприятие и спокойно запишите, проведите или удалите нужные ручные операции. Повторяющиеся записи запишутся в таблицу, не вызывая конфликта СУБД.Администрирование — Тестирование и исправление....В процессе реиндексации платформа 1С автоматически обратится к SQL-серверу, проанализирует структуру метаданных и заново создаст удаленный нами индекс _AccRgAT28408_ByPeriod, попутно исправив логические расхождения.
---
Этот способ по праву считается самым профессиональным. Он позволяет детально разобраться в причинах сбоя и устранить исключительно те записи, которые нарушают уникальность индекса, вообще не затрагивая остальные данные и не требуя монопольного пересчета итогов всей базы данных.
Давайте разберем по шагам, как выявить дублирующиеся записи:
SELECT COUNT(*) as [КоличествоДублей], _Period, _AccountRRef, _Fld28409RRef, _Fld28410RRef
FROM _AccRgAT28408
GROUP BY _Period, _AccountRRef, _Fld28409RRef, _Fld28410RRef
HAVING COUNT(*) > 1;
Примечание: Поля с префиксом _Fld представляют собой измерения регистра или реквизиты субконто. Вы можете посмотреть точный состав полей вашего уникального индекса в свойствах индекса в SSMS.
DELETE с указанием конкретных идентификаторов (GUID) или значений ключевых полей.---
Мы подробно разобрали природу ошибки нарушения уникальности индекса в таблицах итогов регистров бухгалтерии 1С и изучили различные методы борьбы с ней.
Для большинства рядовых ситуаций оптимальным решением будет использование Способа 1 (Временное отключение итогов через интерфейс программы) — он безопасен, не требует навыков работы с базами данных SQL и гарантирует стопроцентный результат без рисков повреждения структуры БД. Если же вы имеете дело с высоконагруженной системой и большими объемами данных, использование команд СУБД TRUNCATE TABLE или точечное удаление индексов помогут вам существенно сэкономить время восстановления системы.