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