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