Ошибка «Обнаружено дублирование ключевых значений в колонках: Ссылка» в 1С 8.3

· 12 мин

Содержание

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

Лечится она по-разному, и выбор зависит от того, где дубли. Битый кэш снимается за минуту ключом /ClearCache. Настоящие дубли в регистре сведений удаляют руками или запросом. А если ошибка живёт только на одной доработанной форме — данные целы, чинить надо текст запроса списка. Ниже все пять сценариев по порядку: от безопасного к радикальному.

Что означает ошибка «Обнаружено дублирование ключевых значений в колонках: Ссылка»

Динамический список (справочник, журнал документов , форма выбора) строит выборку из СУБД. Каждой строке нужен уникальный ключ — обычно это поле Ссылка. Когда в результате запроса две строки получают одну и ту же ссылку, платформа не может однозначно сопоставить строку с объектом и выдаёт ошибку.

Ключевое слово здесь — «в колонках». Проблема не в самом объекте, а в том, как список собирает данные для колонок. Поэтому одна и та же запись может нормально открываться по гиперссылке, но валить список при попытке его показать.

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

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

Как устроен динамический список и почему ключ ломается

Динамический список — это не «таблица на экране», а запрос, который платформа выполняет порциями. Чтобы показать 20 строк из миллиона, ей нужен ключ, по которому она найдёт нужную страницу данных и подгрузит остальное при прокрутке.

Что происходит под капотом:

  • 🔑 Платформа сама назначает поле ключа — по умолчанию Ссылка основной таблицы.
  • 📄 Данные читаются постранично, с динамическим считыванием.
  • 🔗 Дополнительные колонки берутся из соединений с другими таблицами.
  • ⚠️ Если соединение возвращает на одну ссылку больше одной строки — ключ перестаёт быть уникальным, и список падает.

Отсюда два принципиально разных источника проблемы: данные (в таблице физически лежат дубли) и запрос (данные в порядке, но текст запроса размножает строки). Дальше их лечат совсем по-разному.

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

Основные сценарии, от частого к редкому:

  • 🗂️ Дубли в регистре сведений. Список показывает данные из регистра, где измерением или ресурсом идёт ссылка. Две записи с одинаковой ссылкой — и список падает. Самый частый случай на типовых конфигурациях.
  • 🧹 Битый кэш клиента. Локальные файлы сеанса устарели после обновления или обрыва связи. Данных-дублей нет, но клиент их «видит».
  • 🔧 Нарушение целостности после сбоя. Незавершённое обновление, аварийное отключение во время записи, прерванная реструктуризация — в таблице остаются физические дубли строк.
  • 🧩 Произвольный запрос списка с задвоением. Соединение «один ко многим», периодический регистр без среза, забытое измерение — классика доработок.
  • 🔁 Перенос и загрузка данных. Выгрузка-загрузка через XML, обмены, конвертация — при повторной загрузке пары ключей задвоились.
  • 🧾 Групповая обработка или самописный код, который записал в регистр набор дважды.

Чтобы не гадать, начните с быстрой диагностики.

Быстрая диагностика: с чего начать

Определите свой симптом — и сразу видно направление.

Диагностика: выберите симптом

Сравнение способов: что когда применять

СпособКогда применятьРискВремя
Очистка кэшаСразу после обновления, данные целыНет~1 мин
chdbfl + ТиИБаза падала, сбой обновления/СУБДНизкий (нужна копия)10–60 мин
«Все функции» + удалениеРеальные дубли в регистреСредний (удаляем данные)5–20 мин
Правка запроса спискаОшибка на доработанной формеНизкий (нужна копия конфигурации)20–60 мин
Отладка / OneDebuggerПричина не находится глазамиНизкийот 20 мин

Двигайтесь сверху вниз: сначала то, что ничего не ломает.

Способ 1. Очистка кэша (самый безопасный)

Если данные целы, а виноват локальный кэш — помогает за минуту.

  1. Закройте все окна 1С.
  2. Запустите ярлык программы с ключом очистки: в свойствах ярлыка в конце строки Объект допишите /ClearCache (через пробел).
  3. Либо вручную удалите каталог кэша пользователя. Путь вида:
C:\Users\<Пользователь>\AppData\Local\1C\1cv82\<длинный GUID базы>
C:\Users\<Пользователь>\AppData\Local\1C\1cv8\<длинный GUID базы>

Удаляйте только папку конкретной базы (её GUID виден в списке баз при выборе → «Изменить» → строка каталога). Данные это не тронет — кэш пересоберётся при следующем запуске.

Очистка кэша помогает, только если дублей в базе физически нет. Если после пересборки список падает снова — переходите к поиску настоящих дублей.

Способ 2. Тестирование и исправление базы

Годится, когда база пережила сбой: обрыв обновления, аварийное завершение, проблемы с СУБД.

Для файловой базы сначала проверьте физическую целостность утилитой chdbfl.exe (лежит в каталоге платформы, bin):

  1. Закройте базу для всех.
  2. Сделайте резервную копию каталога базы перед любыми правками.
  3. Запустите chdbfl.exe, укажите файл 1Cv8.1CD, поставьте галку «Исправлять обнаруженные ошибки», запустите.

Затем — штатное Тестирование и исправление в конфигураторе: Администрирование → Тестирование и исправление. Отметьте:

  • ✅ Реиндексация таблиц;
  • ✅ Проверка логической целостности;
  • ✅ Проверка ссылочной целостности;
  • ✅ Пересчёт итогов.

Для клиент-серверной базы (PostgreSQL / MS SQL) chdbfl не применяют — работают через Тестирование и исправление в конфигураторе и средства самой СУБД.

Тестирование лечит нарушенную целостность, но не всегда убирает логические дубли в регистре — их часто приходится искать руками.

Способ 3. Найти и удалить дубли через «Все функции»

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

Просмотр регистров через команду «Все функции»

Команда Все функции показывает регистры, минуя проблемный динамический список.

  1. Включите режим: Сервис → Параметры → Отображать команду "Все функции" (галка). В части конфигураций пункт называется Главное меню → Сервис.
  2. Откройте Все функции → Регистры сведений → <нужный регистр>.
  3. Отсортируйте по колонке Ссылка (или по нужному измерению) — задвоенные записи встанут рядом.

Нашли пару одинаковых строк — лишнюю удаляйте (Del), оставляя одну актуальную.

Найти дубли запросом

Если регистр большой, ищите дубли запросом в консоли запросов (внешняя обработка или через расширение):

ВЫБРАТЬ
    Т.Ссылка КАК Ссылка,
    КОЛИЧЕСТВО(*) КАК Сколько
ИЗ
    РегистрСведений.ВашРегистр КАК Т
СГРУППИРОВАТЬ ПО
    Т.Ссылка
ИМЕЮЩИЕ
    КОЛИЧЕСТВО(*) > 1

Запрос вернёт только те ссылки, что задвоились. Дальше — точечно удалить лишние записи.

Для периодического регистра добавьте период, иначе в выборку попадут нормальные исторические записи:

ВЫБРАТЬ
    Т.Ссылка,
    Т.Период,
    КОЛИЧЕСТВО(*) КАК Сколько
ИЗ
    РегистрСведений.ВашРегистр КАК Т
СГРУППИРОВАТЬ ПО
    Т.Ссылка, Т.Период
ИМЕЮЩИЕ
    КОЛИЧЕСТВО(*) > 1

Перед удалением поймите, чем строки отличаются (период, другие измерения). Иногда «дубль» по ссылке — это нормальные записи с разными измерениями, а падает список из-за неверно заданного ключа в самой форме. Тогда чинить надо запрос (Способ 4), а не данные.

Способ 4. Дублирование в произвольном запросе динамического списка

Данные в порядке, а список всё равно падает — значит строки размножает сам запрос. Четыре типовые причины.

Соединение «один ко многим» со связанной таблицей

К списку документов присоединили таблицу, где на одну ссылку несколько строк: строки табличной части, записи регистра, дополнительные реквизиты. Одна ссылка × три строки = три строки с одним ключом.

Проверка: уберите соединение из запроса. Ошибка ушла — виновник найден.

Соединение с периодическим регистром сведений без среза

Частая ловушка. Присоединяете РегистрСведений.ЦеныНоменклатуры напрямую — получаете всю историю цен по каждой номенклатуре.

Пример на числах: у товара 5 записей цены за год → в списке 5 строк вместо одной → падение.

Неполное указание измерений непериодического регистра

Регистр имеет три измерения, а в условии соединения указано одно. Платформа честно вернёт все комбинации остальных двух.

// так задвоится
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.Настройки КАК Н
    ПО Н.Объект = Д.Ссылка

// так нет
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.Настройки КАК Н
    ПО Н.Объект = Д.Ссылка
        И Н.Пользователь = &Пользователь
        И Н.Вид = &ВидНастройки

Неверные параметры и операции сравнения

Ещё один источник «странного» задвоения: соединение по неравенству (>=, <=, МЕЖДУ), сравнение полей разных типов, незаполненный параметр. Незаданный параметр превращает условие в «истина для всех строк» — и соединение перестаёт фильтровать.

Что проверить в тексте запроса:

  • 🔍 все параметры реально устанавливаются в УстановитьПараметр / в настройках списка;
  • 🔍 типы сопоставляемых полей совпадают (ссылка со ссылкой, а не ссылка со строкой);
  • 🔍 нет соединения по неравенству без дополнительного ограничения;
  • 🔍 не задвоилось само соединение двух таблиц с одинаковыми ключами.

Шаблоны исправления запроса

Три приёма закрывают почти все случаи задвоения.

Свёртка через вложенный запрос с группировкой

Если нужна сумма или количество из подчинённой таблицы — агрегируйте её отдельно, а потом присоединяйте уже свёрнутый результат.

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

Одна строка на документ — ключ снова уникален.

Срез последних вместо всей истории

Для периодического регистра берите виртуальную таблицу, а не физическую:

ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры.СрезПоследних(&Дата, ТипЦен = &ТипЦен) КАК Цены
    ПО Цены.Номенклатура = Т.Номенклатура

СрезПоследних возвращает по одной актуальной записи на комбинацию измерений.

Контроль всех измерений

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

Крайняя мера — ВЫБРАТЬ РАЗЛИЧНЫЕ. Она убирает полные дубли строк, но не спасает, если строки различаются хоть одним значением. И тормозит на больших выборках. Лучше чинить логику соединения.

Если менять запрос нельзя, второй путь — сменить поле ключа: в свойствах динамического списка задать Основная таблица и корректное Поле ключа, чтобы уникальность обеспечивалась другим реквизитом.

Способ 5. Точный поиск причины через отладку

Когда причина не находится глазами — ищем точное место в отладчике.

  1. В конфигураторе включите отладку: Сервис → Параметры → Запуск 1С:Предприятия → галка "Устанавливать режим разрешения отладки".
  2. Поставьте точку останова на открытие проблемной формы списка.
  3. Скопируйте текст запроса динамического списка в консоль запросов и выполните с теми же параметрами — дубли будут видны глазами.

Ускоряет разбор инструмент OneDebugger и подобные внешние обработки: они подсвечивают участок кода, из-за которого список получает неуникальный ключ, и позволяют пройти по стеку до конкретной строки.

Приём без отладчика: включите технологический журнал или замер производительности и посмотрите текст SQL-запроса, который платформа отправила в СУБД. Задвоение обычно видно уже по количеству возвращённых строк.

Порядок действий: пройдите по шагам

Пошаговый помощник
Сделайте резервную копию
Копия базы (файл 1Cv8.1CD или выгрузка .dt) до любых правок. Без неё дальше не двигайтесь.

Как избежать ошибок при работе с динамическими списками

  • 💾 Перед обновлением конфигурации и платформы — всегда резервная копия базы.
  • 🔌 Не выключайте сервер и не рвите сеанс во время реструктуризации и обновления.
  • 🧪 Периодически (например, раз в месяц) прогоняйте регламентное Тестирование и исправление в нерабочее время.
  • 🧷 Любое новое соединение в запросе списка проверяйте на количество строк: выборка до и после соединения должна совпадать.
  • 📐 Периодические регистры присоединяйте только через СрезПоследних, агрегаты — через вложенный запрос с группировкой.
  • 🧰 Тестируйте форму списка не на трёх строках, а на реальном объёме и с включёнными отборами.
  • 📦 После обменов и загрузок XML проверяйте регистры на дубли запросом с группировкой.
  • 🔐 Уникальность регистра сведений задавайте измерениями, а не кодом — платформа сама не даст записать дубль.

Если не помогло

Список всё ещё падает — сузьте область:

  • Проверьте, у всех ли пользователей ошибка. Только у одного — почти наверняка кэш или его профиль.
  • Откройте базу без расширений (Конфигуратор → Поддержка → Расширения, отключить) — если ошибка ушла, виновато расширение.
  • Сравните конфигурацию с типовой: возможно, в форму списка внесли правку, о которой забыли.
  • Проверьте, не падает ли список только при определённом отборе — тогда дело в параметрах запроса.
  • Выгрузите базу в .dt и загрузите в чистую копию — часть проблем целостности уходит при выгрузке-загрузке.
  • Соберите точный текст ошибки, название регистра/справочника и номер релиза — с этим быстрее найдёте причину или обратитесь к специалисту.

Проверьте себя

Проверьте себя
Ошибка появилась сразу после обновления, данные на месте. С чего начать?
Каким запросом искать задвоенные ссылки в регистре?
Что сделать в первую очередь перед удалением дублей?
Как правильно присоединить периодический регистр сведений к динамическому списку?

Частые вопросы

Что вообще значит «дублирование ключевых значений в колонках: Ссылка»?
Динамический список получил две строки с одинаковым ключом Ссылка и не может показать их в колонках. Причина — либо дубли в регистре/таблице, либо задвоение строк в запросе списка.
Удалит ли очистка кэша мои данные?
Нет. Кэш /ClearCache — это временные файлы сеанса на клиенте. Они пересобираются при следующем запуске, данные базы не затрагиваются.
Помогает ли Тестирование и исправление от этой ошибки?
Часто да — оно чинит нарушенную целостность после сбоев. Но логические дубли в регистре сведений нередко приходится искать и удалять вручную.
Как быстро посмотреть регистр, если сам список не открывается?
Через команду Все функции (включается в Сервис → Параметры). Она открывает регистр напрямую, минуя сломанный динамический список.
Ошибка только у одного пользователя — почему?
Почти всегда это его локальный кэш или профиль. Очистите кэш этого пользователя или откройте базу под другим пользователем для проверки.
В базе дублей нет, а список всё равно падает. Где искать?
В произвольном запросе динамического списка. Ищите соединение «один ко многим», периодический регистр без СрезПоследних или незаполненный параметр в условии.
Поможет ли просто добавить РАЗЛИЧНЫЕ в запрос?
Только если строки полностью идентичны. Различаются хоть одним полем — дубли ключа останутся. Правильнее свернуть подчинённую таблицу вложенным запросом с группировкой.