Почему возникает ошибка дублирования ключевых значений в колонке Ссылка и как ее устранить?

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

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

Разберем по шагам механизм возникновения этой ошибки, выясним способы ее диагностики и рассмотрим практические варианты устранения.

Механизм возникновения ошибки в динамическом списке

Для отображения списков объектов в управляемом интерфейсе используется элемент формы ДинамическийСписок. По умолчанию он работает в режиме порционной выборки данных из базы.

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

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

Типовые причины появления дублей

Проанализируем распространенные сценарии, приводящие к дублированию ключа:

  1. Связи «один ко многим»: некорректное левое или внутреннее соединение с табличными частями, подчиненными справочниками или регистрами сведений. Например, если к номенклатуре присоединяется таблица дополнительных реквизитов со множественными значениями, то на одну позицию номенклатуры в выборке сформируется несколько строк.
  2. Неполное соединение по измерениям регистра: при связи с многомерными непериодическими регистрами сведений без указания всех ключевых измерений в условии соединения.
  3. Связь с периодическими регистрами сведений: обращение напрямую к таблице регистра вместо виртуальной таблицы СрезПоследних (или обращение к срезу без передачи точки времени).
  4. Логические дубли в данных: ошибки при обмене данными или сбои алгоритмов записи, из-за которых в регистрах или подчиненных структурах появились коллизии.

Способы диагностики и перехвата итогового запроса

Чтобы понять, какое именно соединение размножает строки, необходимо получить реальный исполняемый текст запроса, который формирует СКД со всеми наложенными отборами.

Рассмотрим два основных способа перехвата запроса:

  1. Программное получение макета компоновки данных:

    Мы можем программно сгенерировать исполняемый макет динамического списка в точке останова отладчика или во внешней обработке:

    
    Схема = Элементы.Список.ПолучитьИсполняемуюСхемуКомпоновкиДанных();
    Настройки = Элементы.Список.ПолучитьИсполняемыеНастройкиКомпоновкиДанных();
    Компоновщик = Новый КомпоновщикМакетаКомпоновкиДанных;
    Макет = Компоновщик.Выполнить(Схема, Настройки,,, Тип("ГенераторМакетаКомпоновкиДанныхДляКоллекцииЗначений"));
    // В свойстве Макет.НаборыДанных будет содержаться итоговый сгенерированный запрос
    
  2. Анализ через Технологический журнал:

    Если ошибка возникает в сложном контексте типовой конфигурации, настроим сбор событий DBMSSQL/DBPOSTGRS или EXCP в Технологическом журнале 1С. В журнале будет зафиксирован финальный SQL-запрос, отправленный к СУБД, в котором наглядно видны все присоединенные таблицы.

После получения текста запроса проверим его в консоли запросов на наличие дублей с помощью группировки:


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

Способы устранения проблемы

Разберем варианты исправления ошибки в зависимости от источника ее возникновения:

  1. Агрегация данных во вложенных запросах:

    Если к списку необходимо присоединить данные из таблицы, где на один объект может приходиться несколько записей (например, дополнительные реквизиты, штрихкоды, цены), предварительно сгруппируем их во вложенном запросе с использованием агрегатных функций (МИНИМУМ, МАКСИМУМ) либо срезов.

  2. Устранение коллизий и контроль дублей в данных:

    Если ошибка вызвана некорректно заполненными дополнительными реквизитами или записями регистров, очистим повторяющиеся значения и добавим программный контроль уникальности при записи объектов.

  3. Использование составного ключа:

    В ситуациях, когда бизнес-логика действительно требует отображения нескольких строк на один и тот же объект (например, номенклатура в разрезе складов или характеристик), в свойствах колонок динамического списка настроим составной ключ (например, пара Ссылка + Характеристика), сняв признак единственного ключа с поля Ссылка.

  4. Очистка свойства «Основная таблица»:

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

← На главную