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

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

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

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

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

Для понимания корня проблемы проанализируем, как платформа 1С работает со свойством ОсновнаяТаблица в динамическом списке:

  1. Динамическое считывание порциями: когда у динамического списка задана основная таблица, платформа переходит в режим динамической подгрузки данных. Для корректной пагинации, прокрутки, позиционирования курсора и работы стандартных команд («Создать», «Скопировать», «Пометить на удаление») каждой строке на экране должен строго соответствовать единственный уникальный ключ (поле Ссылка для ссылочных типов или набор измерений с периодом для регистров).
  2. Системная колонка ГруппировкаСтроки: формируется платформой автоматически при включении группировок в списке. В нее помещается идентификатор узла дерева. Если при левом соединении таблиц одна ссылка задваивается, платформа получает несколько записей с одинаковым ключом в рамках одного уровня группировки, что приводит к критическому сбою.
  3. Автоматическое расширение запроса: когда пользователь выводит в список реквизиты через точку (например, контактную информацию или свойства контрагента), платформа неявно достраивает SQL-запрос. Если присоединенная таблица содержит более одной записи на один объект, результирующая выборка размножает строки основной таблицы.

Способ 1. Локализация задвоений через консоль запросов

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

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


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

Если запрос возвращает строки, значит, в динамическом списке присутствует связь «один-ко-многим», которая и ломает механизм динамического считывания.

Способ 2. Исключение связей «один-ко-многим» и корректная фильтрация соединений

Чаще всего дублирование возникает при соединении с регистрами сведений (контактная информация, актуальные статусы, срезы последних) или табличными частями. Если у контрагента добавлено два телефона или два адреса электронной почты, стандартное ЛЕВОЕ СОЕДИНЕНИЕ вернет две строки вместо одной.

Рассмотрим, как правильно организовать соединение, чтобы гарантировать уникальность ключевых полей:

  1. Жесткая фильтрация по виду сведений: накладываем фильтр непосредственно в условии соединения или во вложенной таблице.
  2. Использование агрегатных функций: сворачиваем присоединенные данные до одной строки.

Посмотрим на пример корректного запроса с получением только одного номера телефона:


ВЫБРАТЬ
    Контрагенты.Ссылка КАК Ссылка,
    Контрагенты.Наименование КАК Наименование,
    Контрагенты.ИНН КАК ИНН,
    Телефоны.НомерТелефона КАК Телефон
ИЗ
    Справочник.Контрагенты КАК Контрагенты
    ЛЕВОЕ СОЕДИНЕНИЕ (
        ВЫБРАТЬ
            КИ.Объект КАК Объект,
            МАКСИМУМ(КИ.Представление) КАК НомерТелефона
        ИЗ
            РегистрСведений.КонтактнаяИнформация КАК КИ
        ГДЕ
            КИ.Вид = &ВидТелефона
        СГРУППИРОВАТЬ ПО
            КИ.Объект
    ) КАК Телефоны
        ПО Контрагенты.Ссылка = Телефоны.Объект

Способ 3. Сворачивание итоговой выборки запроса

Обратите внимание: использование ключевого слова РАЗЛИЧНЫЕ (DISTINCT) не решает проблему дублирования ключа, если другие присоединенные колонки содержат разные значения. В этом случае строки все равно будут уникальными по всей совокупности полей, но не по полю Ссылка.

Для полного устранения дублей применяем конструкцию СГРУППИРОВАТЬ ПО для всех полей основной таблицы, а зависимые данные сворачиваем функциями МАКСИМУМ или МИНИМУМ:


ВЫБРАТЬ
    Сотрудники.Ссылка КАК Ссылка,
    Сотрудники.Код КАК Код,
    Сотрудники.Наименование КАК Наименование,
    МАКСИМУМ(СрезСтатусов.Статус) КАК АктуальныйСтатус
ИЗ
    Справочник.Сотрудники КАК Сотрудники
    ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.СтатусыСотрудников.СрезПоследних(&Период, ) КАК СрезСтатусов
        ПО Сотрудники.Ссылка = СрезСтатусов.Сотрудник
СГРУППИРОВАТЬ ПО
    Сотрудники.Ссылка,
    Сотрудники.Код,
    Сотрудники.Наименование

Способ 4. Альтернативные варианты настройки динамического списка

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

  1. Очистка свойства «Основная таблица» и ручные команды:

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

  2. Явное указание ключевых полей:

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

  3. Организация интерфейса по паттерну Master-Detail:

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

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

После исправления запроса в конфигураторе ошибка может временно сохраняться у конечных пользователей из-за кэшированных настроек формы и старых группировок, сохраненных в системном хранилище. Рекомендуется выполнить следующие действия:

  1. В пользовательском режиме в меню формы нажать «Еще» → «Установить стандартные настройки».
  2. Если дублирование вызвано нарушением ссылочной целостности в регистрах сведений (например, после некорректного обмена данными), выполнить процедуру «Тестирование и исправление информационной базы» в режиме Конфигуратора с включенными опциями проверки логической целостности и реиндексации таблиц.
  3. Перезаписать проблемные записи регистров сведений, содержащие дублирующиеся комбинации измерений.
← На главную