В процессе работы с конфигурациями на платформе 1С:Предприятие 8.3, такими как Управление торговлей 11, ERP 2 или Комплексная автоматизация, пользователи часто сталкиваются с неприятной ошибкой при просмотре списков документов: «Обнаружено дублирование ключевых значений в колонке "Ссылка"». Особенно часто это проявляется в журнале ЧекиККМ или при работе с фискальными операциями. В этой статье мы подробно разберем, почему возникает эта проблема, как ее диагностировать и какие существуют способы решения — от простой чистки данных до корректировки программного кода.
Для начала выясним причину. Ошибка локализована в объекте платформы под названием ДинамическийСписок. Когда мы открываем форму списка (например, список чеков ККМ), система выполняет запрос к базе данных. Чтобы корректно отображать строки, прокручивать их (скроллинг) и выбирать объекты, платформе необходим уникальный идентификатор для каждой строки. По умолчанию этим идентификатором выступает поле Ссылка основной таблицы.
Проблема возникает в тот момент, когда в запросе динамического списка используется ЛЕВОЕ СОЕДИНЕНИЕ (или любое другое соединение) с другой таблицей, и для одной записи из основной таблицы находится две или более соответствующих записей в присоединяемой таблице. В результате в выборке запроса появляются две строки с абсолютно одинаковым значением в колонке Ссылка. Платформа 1С «теряется», не понимая, какую именно строку отрисовывать, и выдает ошибку дублирования.
Разберем ситуацию на примере стандартного журнала чеков ККМ. Чтобы понять, где именно происходит «размножение» строк, нам необходимо заглянуть в конфигуратор и найти текст запроса, который питает форму списка. Рассмотрим типичный запрос, который часто становится источником проблем:
ВЫБРАТЬ
ЧекиККМ.Ссылка,
ЧекиККМ.Дата,
ЧекиККМ.Номер,
ЧекиККМ.Статус,
ЖурналФискальныхОпераций.ФискальнаяОперацияНомерЧекаККМ КАК НомерЧекаККМ,
ЧекиККМ.КассаККМ,
ЧекиККМ.СуммаДокумента
ИЗ
ЖурналДокументов.ЧекиККМ КАК ЧекиККМ
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЖурналФискальныхОпераций КАК ЖурналФискальныхОпераций
ПО ЧекиККМ.Ссылка = ЖурналФискальныхОпераций.ДокументОснование
Проанализируем ситуацию: здесь основной таблицей выступает ЖурналДокументов.ЧекиККМ. К ней присоединяется РегистрСведений.ЖурналФискальныхОпераций. Ошибка «дублирование ключевых значений» прямо указывает на то, что для одного документа-основания (чека) в регистре фискальных операций создано несколько записей. Это может произойти из-за сбоев оборудования, когда чек пробивался несколько раз, или из-за ошибок логики расширений.
Чтобы быстро найти «виновника», мы воспользуемся консолью запросов. Нам нужно сгруппировать данные по ссылке и найти те объекты, количество которых превышает единицу. Выполним следующий запрос в консоли:
ВЫБРАТЬ
ЧекиККМ.Ссылка КАК ПроблемныйДокумент,
КОЛИЧЕСТВО(ЧекиККМ.Ссылка) КАК КоличествоДублей
ИЗ
ЖурналДокументов.ЧекиККМ КАК ЧекиККМ
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЖурналФискальныхОпераций КАК ЖурналФискальныхОпераций
ПО ЧекиККМ.Ссылка = ЖурналФискальныхОпераций.ДокументОснование
СГРУППИРОВАТЬ ПО
ЧекиККМ.Ссылка
ИМЕЮЩИЕ
КОЛИЧЕСТВО(ЧекиККМ.Ссылка) > 1
Если запрос вернул строки — значит, мы нашли те самые документы, из-за которых список «падает» в ошибку. Теперь мы точно знаем, по каким ссылкам в регистре ЖурналФискальныхОпераций (или другом проблемном регистре) есть лишние записи.
Если база типовая и программисты не меняли код, то самым быстрым способом будет удаление лишних записей в регистре. Рассмотрим этот процесс:
Журнал фискальных операций.После удаления дублей в регистре ошибка в динамическом списке пропадет мгновенно, так как условие уникальности ключа Ссылка снова будет соблюдено.
Если проблема возникает регулярно (например, бизнес-процесс предполагает наличие нескольких записей в регистре для одного документа), то просто удалять данные нельзя — мы потеряем историю. В этом случае проанализируем, как изменить сам запрос динамического списка, чтобы он всегда возвращал только одну запись. Рассмотрим пример корректировки запроса с использованием вложенного запроса для получения максимального периода или уникального номера:
ВЫБРАТЬ
ЧекиККМ.Ссылка,
ЧекиККМ.Дата,
// ... другие поля ...
ПоследниеФискальныеОперации.ФискальнаяОперацияНомерЧекаККМ
ИЗ
ЖурналДокументов.ЧекиККМ КАК ЧекиККМ
ЛЕВОЕ СОЕДИНЕНИЕ (
ВЫБРАТЬ
МаксОперации.ДокументОснование,
МАКС(МаксОперации.НомерЧекаККМ) КАК ФискальнаяОперацияНомерЧекаККМ
ИЗ
РегистрСведений.ЖурналФискальныхОпераций КАК МаксОперации
СГРУППИРОВАТЬ ПО
МаксОперации.ДокументОснование
) КАК ПоследниеФискальныеОперации
ПО ЧекиККМ.Ссылка = ПоследниеФискальныеОперации.ДокументОснование
Используя группировку (СГРУППИРОВАТЬ ПО) во вложенном запросе, мы гарантируем, что для каждой ссылки документа будет возвращена ровно одна строка, даже если в физической таблице регистра их несколько. Это самый надежный программный способ защиты от ошибки дублирования.
Иногда корень зла кроется не в фискальных данных. Проанализируем другие возможные варианты:
Обновление ключей доступа к данным или использование типовой обработки «Редактирование ключей доступа».ДополнительныеСведения.Чтобы ситуация не повторялась, рекомендуем выполнить следующие действия:
Во-первых, проверьте наличие расширений, которые работают с кассовым оборудованием или эквайрингом. Зачастую некорректная запись в ЖурналФискальныхОпераций — результат работы стороннего кода.
Во-вторых, убедитесь, что в свойствах динамического списка в конфигураторе корректно указана Основная таблица. Если поле «Основная таблица» не заполнено, платформа не может эффективно управлять выборкой данных, что повышает риск возникновения ошибок при сложных соединениях.
В-третьих, регулярно проводите регламентные операции по обслуживанию базы данных (ТИИ), включая проверку логической и ссылочной целостности, однако помните, что ТИИ не всегда находит дубли в регистрах сведений, так как с точки зрения БД они могут иметь разные наборы измерений и не являться ошибкой структуры.
Подводя итог, можно сказать, что ошибка дублирования ключевых значений — это всегда сигнал о том, что связь «один-к-одному» превратилась в «один-ко-многим». Внимательный анализ связей в запросе и диагностика данных через консоль запросов позволяют решить эту задачу максимально оперативно.