При работе в управляемых формах 1С (особенно в типовой конфигурации 1С:Бухгалтерия предприятия 3.0) пользователи часто сталкиваются с неприятным поведением списков документов. При открытии журнала платежных поручений, реализаций или отчетов о розничных продажах система аварийно завершает работу и выдает ошибку: «Обнаружено дублирование ключевых значений в колонках "Ссылка"». При попытке пересохранить или скопировать такой документ возникает сопутствующая ошибка блокировки: «Данные были изменены или удалены другим пользователем».
В этой статье мы подробно разберем природу этого явления, выясним технические причины сбоя в базе данных и рассмотрим пошаговые методы решения проблемы как на уровне метаданных, так и на уровне платформы.
Для начала проанализируем, почему динамический список вообще выдает подобное сообщение. Динамический список в 1С предназначен для порционного считывания данных из СУБД и отображения их на форме. Когда в свойствах динамического списка указана Основная таблица (например, Документ.ПлатежноеПоручение), платформа накладывает жесткое системное ограничение: каждая строка на экране должна строго соответствовать уникальному идентификатору (UUID) ссылки объекта.
Если в запросе динамического списка используется левое соединение (ЛЕВОЕ СОЕДИНЕНИЕ или LEFT JOIN) с другой таблицей (например, регистром сведений или табличной частью), и в этой присоединенной таблице для одной и той же ссылки содержится более одной записи, СУБД возвращает в результате запроса две или более строки с одинаковым значением поля Ссылка. Динамический список не может сопоставить две строки с одинаковым уникальным ключом одной строке на экране и генерирует исключение.
Рассмотрим реальный запрос динамического списка из конфигурации «Бухгалтерия предприятия», на который жалуются пользователи:
ВЫБРАТЬ
ДокументПлатежноеПоручение.Ссылка КАК Ссылка,
ДокументПлатежноеПоручение.ВидОперации КАК ВидОперации,
ДокументПлатежноеПоручение.ВерсияДанных КАК ВерсияДанных,
ДокументПлатежноеПоручение.Номер КАК Номер,
ДокументПлатежноеПоручение.Дата КАК Дата,
ДокументПлатежноеПоручение.Проведен КАК Проведен,
ДокументПлатежноеПоручение.Организация КАК Организация,
СостоянияБанковскихДокументов.Состояние КАК Состояние
ИЗ
Документ.ПлатежноеПоручение КАК ДокументПлатежноеПоручение
{ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.СостоянияБанковскихДокументов КАК СостоянияБанковскихДокументов
ПО ДокументПлатежноеПоручение.Ссылка = СостоянияБанковскихДокументов.СсылкаНаОбъект}
{ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.БанковскиеСчетаИнтеграцииСБанком КАК БанковскиеСчетаИнтеграцииСБанком
ПО ДокументПлатежноеПоручение.СчетОрганизации = БанковскиеСчетаИнтеграцииСБанком.БанковскийСчет}
В данном запросе соединение происходит по таблицам РегистрСведений.СостоянияБанковскихДокументов и РегистрСведений.БанковскиеСчетаИнтеграцииСБанком. Если в любом из этих регистров по какой-то причине образуются две записи для одного документа или банковского счета, запрос мгновенно вернет дубли строк, что приведет к падению формы списка.
Когда вы пытаетесь открыть дублирующийся документ напрямую из списка и пересохранить его, платформа часто сообщает: «Данные были изменены или удалены другим пользователем». Это признак нарушения физической целостности индексов СУБД или рассинхронизации транзакционного кэша платформы. При записи документа система пытается обновить его статус в регистрах сведений (например, в том же СостоянияБанковскихДокументов). Из-за наличия некорректного дублирующегося индекса транзакция натыкается на блокировку записи, ошибочно интерпретируя ее как изменение объекта в параллельном сеансе.
---
Для полного устранения неполадки нам необходимо действовать методично. Разберем пошагово все этапы диагностики и исправления.
Первым делом выясним, какая именно присоединенная таблица порождает фантомные строки. Откроем внешнюю обработку «Консоль запросов» и выполним отладочный запрос, который сгруппирует данные по ссылке и выведет количество совпадений:
ВЫБРАТЬ
ДокументПлатежноеПоручение.Ссылка КАК Ссылка,
КОЛИЧЕСТВО(РАЗЛИЧНЫЕ ДокументПлатежноеПоручение.Ссылка) КАК КоличествоСсылок,
КОЛИЧЕСТВО(ДокументПлатежноеПоручение.Ссылка) КАК КоличествоСтрокВРезультате
ИЗ
Документ.ПлатежноеПоручение КАК ДокументПлатежноеПоручение
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.СостоянияБанковскихДокументов КАК СостоянияБанковскихДокументов
ПО ДокументПлатежноеПоручение.Ссылка = СостоянияБанковскихДокументов.СсылкаНаОбъект
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.БанковскиеСчетаИнтеграцииСБанком КАК БанковскиеСчетаИнтеграцииСБанком
ПО ДокументПлатежноеПоручение.СчетОрганизации = БанковскиеСчетаИнтеграцииСБанком.BankСчет
СГРУППИРОВАТЬ ПО
ДокументПлатежноеПоручение.Ссылка
ИМЕЮЩИЕ
КОЛИЧЕСТВО(ДокументПлатежноеПоручение.Ссылка) > 1
Если запрос вернул конкретные документы, поочередно убирайте из связей таблицы левого соединения (сначала один регистр, затем второй), чтобы точно локализовать виновника задвоения. Чаще всего проблема кроется в регистре СостоянияБанковскихДокументов, так как он активно перезаписывается фоновыми процессами при интеграции со Сбербанком или ДиректБанком.
Если виновником оказался непериодический регистр сведений, у которого измерением является ссылка на документ, наличие двух записей для одного документа указывает на физическое повреждение индексов СУБД. В нормальном состоянии СУБД физически не позволит записать дубль уникального ключа. Нам необходимо выполнить процедуру восстановления таблиц:
bin) и запустите утилиту проверки физической целостности файлов базы данных chdbfl.exe. Укажите путь к файлу вашей информационной базы 1Cv8.1CD, установите флаг «Исправлять обнаруженные ошибки» и запустите проверку.
DBCC CHECKDB ('ИмяВашейБазы', REPAIR_ALLOW_DATA_LOSS);
Если база является абсолютно типовой, но в ней установлены отраслевые или сервисные Расширения конфигурации, обратите внимание на них. Очень часто расширения добавляют свои поля в стандартные формы списков. При этом разработчики расширений модифицируют запросы динамических списков некорректными связями без учета уникальности записей.
Попробуйте временно отключить все активные расширения в меню Администрирование — Свойства программы — Расширения и проверьте работу динамического списка документов. Если ошибка пропала, необходимо скорректировать программный код запроса в расширении.
Также не забывайте про Дополнительные реквизиты и сведения. Если пользователи вывели дополнительные свойства в колонки списка через механизм «Изменить форму», платформа 1С автоматически подтягивает левое соединение к табличной части дополнительных реквизитов. Если у скопированного документа записалось два одинаковых значения свойств, список начнет двоить именно по этой причине. Проверьте карточку проблемного документа на вкладке дополнительных свойств.
Проанализируем технологическую сторону проблемы. Ошибка часто проявляется на конкретных релизах платформы (например, в ветке 8.3.16.1063). Это связано с зарегистрированной ошибкой кэширования метаданных и некорректной трансляцией запросов СКД (Системы компоновки данных) в SQL-код.
Существует два пути решения платформенного сбоя:
8.3.15.2107) данная ошибка не воспроизводилась благодаря другой схеме оптимизации запросов СУБД.8.3.18, 8.3.21 или выше, где ошибки работы с кэшем динамических списков полностью устранены.После проведения любых работ по обновлению платформы не забудьте очистить локальный кэш конфигурации на рабочих станциях пользователей. Для этого достаточно удалить базу из списка запуска 1С и добавить её заново либо очистить содержимое каталогов в папках %userprofile%\AppData\Local\1C\1Cv8 и %userprofile%\AppData\Roaming\1C\1Cv8.