Как исправить ошибку: Обнаружено дублирование ключевых значений в колонках: Ссылка1

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

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

Почему появляется поле Ссылка1 и что оно означает

Для начала проанализируем внутренние механизмы платформы. Когда мы настраиваем динамический список с произвольным запросом и указываем Основную таблицу, система берет на себя управление выборкой данных, навигацией и выделением строк. Для этого ей необходим уникальный идентификатор каждой строки. Платформа автоматически добавляет в итоговый SQL-запрос поле уникального идентификатора.

Если в нашем запросе уже присутствует поле с псевдонимом Ссылка, или если платформа при автоматической генерации технического запроса сталкивается с конфликтом имен, она присваивает внутреннему идентификатору псевдоним Ссылка1. Ошибка возникает тогда, когда в результате соединений (JOIN) в итоговую выборку попадают две или более строки с одинаковым значением в этом ключевом поле. Система теряет возможность однозначно идентифицировать строку в списке, что и приводит к остановке вывода данных.

Шаг 1. Проверка основной таблицы и ключевых полей

Первым делом нам необходимо проверить настройки самого динамического списка в конфигураторе. Рассмотрим свойства объекта ДинамическийСписок. Поле Основная таблица должно быть заполнено правильно. Если мы работаем с журналом документов, там должна быть указана таблица журнала, например ЖурналДокументов.ЖурналУведомленийWMS.

Если же мы сознательно не указываем основную таблицу (например, при объединении нескольких несвязанных источников), нам крайне важно убедиться, что в колонке Ключ объекта выбрано поле, которое гарантированно уникально для каждой строки. Но помните: в 90% случаев проблема кроется именно в неявном размножении записей из-за левых соединений.

Шаг 2. Диагностика запроса на наличие дублей

Рассмотрим ситуацию, когда в консоли запросов все чисто, а список выдает ошибку. Это происходит потому, что консоль выводит все записи сразу, а динамический список работает порциями. Чтобы найти «виновника», проанализируем структуру наших соединений. Чаще всего дубли вызывают соединения вида «один ко многим» (1:N).

Например, если мы присоединяем к журналу документов таблицу Документ.РеализацияТоваровУслуг по полю ЗаказКлиента, а на один заказ было оформлено две реализации, то строка журнала продублируется. Выясним это с помощью специального диагностического запроса:


ВЫБРАТЬ
    Журнал.Ссылка КАК Ссылка,
    1 КАК Количество
ПОМЕСТИТЬ ВТ_Данные
ИЗ
    ЖурналДокументов.ЖурналУведомленийWMS КАК Журнал
        ЛЕВОЕ СОЕДИНЕНИЕ Документ.РеализацияТоваровУслуг КАК Реализация
        ПО (ВЫРАЗИТЬ(Журнал.ДокументОснование КАК Документ.ЗаказКлиента) = Реализация.ЗаказКлиента)
        ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.СтатусОбработкиУведомленияСкладом КАК Статусы
        ПО (Журнал.Ссылка = Статусы.Уведомление);

//////////////////////////////////////////////////////
ВЫБРАТЬ
    ВТ.Ссылка КАК Ссылка,
    СУММА(ВТ.Количество) КАК КолВоЗаписей
ИЗ
    ВТ_Данные КАК ВТ
СГРУППИРОВАТЬ ПО
    ВТ.Ссылка
ИМЕЮЩИЕ
    СУММА(ВТ.Количество) > 1

Если этот запрос вернул хотя бы одну строку — мы нашли причину. Каждое такое уведомление будет вызывать ошибку в динамическом списке.

Шаг 3. Устранение дублей в соединениях

Теперь разберем, как нам исправить логику запроса. Если нам нужно вывести информацию, которая может дублироваться (например, номер реализации), у нас есть два пути:

  1. Сгруппировать данные: Если нам не важны все реализации, а нужна, например, только последняя, мы должны сначала выбрать максимальные значения в отдельном подзапросе или временной таблице, а уже потом соединять их с основным списком.
  2. Использовать вложенные запросы: Вместо прямого соединения всей таблицы РеализацияТоваровУслуг, проанализируем возможность использования конструкции ВЫБРАТЬ ПЕРВЫЕ 1 или агрегатных функций.

Также обратим внимание на корректность типов данных. В исходном запросе автора была допущена ошибка типизации ISNULL:

ЕСТЬNULL(РеализацияТоваровУслуг.Ссылка, "")

Так делать не рекомендуется. Платформа может некорректно обрабатывать смешанные типы (Ссылка и Строка) при построении индекса для динамического списка. Правильнее будет использовать пустую ссылку того же типа:

ЕСТЬNULL(РеализацияТоваровУслуг.Ссылка, ЗНАЧЕНИЕ(Документ.РеализацияТоваровУслуг.ПустаяСсылка))

Шаг 4. Влияние RLS и пользовательских настроек

Бывает так, что запрос идеален, но ошибка остается. Проанализируем влияние RLS (Row Level Security). Механизм ограничения прав доступа на уровне записей неявно модифицирует ваш запрос перед отправкой на SQL-сервер. Если в правилах RLS прописаны сложные условия с соединениями, они могут добавлять дубли, которые не видны программисту под полными правами. Обязательно протестируйте список под учетной записью обычного пользователя.

Другой важный момент — настройки компоновки данных. Динамические списки в управляемых формах работают на базе СКД. Пользователь мог установить отбор или группировку по реквизиту, который заставляет систему присоединять дополнительные таблицы. Попробуем выполнить следующие действия:

  1. Зайти в меню «Еще» — «Установить стандартные настройки».
  2. Зайти в «Изменить форму» — «Еще» — «Установить стандартные настройки».
  3. Очистить настройки пользователя в справочнике «Настройки пользователей» (или через администрирование), чтобы исключить влияние закэшированных некорректных планов запроса.

Шаг 5. Работа с журналами документов

При работе с журналами документов (как в нашем примере) важно помнить, что это виртуальная таблица. Если мы соединяем журнал с физической таблицей документа, входящего в этот журнал, риск конфликта имен Ссылка крайне велик.

Рассмотрим совет опытных разработчиков: если динамический список на базе журнала с соединениями продолжает «сыпаться», попробуем заменить запрос на ОБЪЕДИНЕНИЕ ВСЕХ (UNION ALL) по всем типам документов, входящих в журнал. Это позволит жестко типизировать каждое соединение и избежать ситуации, когда платформа путается в метаданных составного типа ДокументОснование.

Итоги и рекомендации

Подведем итог нашему исследованию. Для решения проблемы дублирования Ссылка1 мы должны:

Соблюдение этих шагов позволит вам создать стабильный и быстрый интерфейс, а ошибка Ссылка1 больше не будет препятствием в вашей работе.

← На главную