При работе со штатной обработкой «Регистрация изменений обмена данными» или при разработке собственных динамических списков разработчики и администраторы могут столкнуться с платформенной ошибкой: «Обнаружено дублирование ключевых значений в колонке "Ссылка.Объект"». Ошибка возникаем при попытке перейти к определенному метаданному или узлу обмена.
Разберем подробно причины возникновения этой нештатной ситуации и рассмотрим варианты ее решения.
Проанализируем ситуацию изнутри. Динамический список платформы 1С:Предприятие требователен к уникальности ключевых полей, по которым происходит идентификация строк и построение порционной выборки СУБД. В запросе динамического списка обработки регистрации изменений выполняется соединение таблицы изменений с основной таблицей объекта метаданных:
ВЫБРАТЬ
ТаблицаИзменений.Ссылка КАК Ссылка,
ТаблицаИзменений.НомерСообщения КАК НомерСообщения,
ВЫБОР
КОГДА ТаблицаИзменений.НомерСообщения ЕСТЬ NULL ТОГДА ИСТИНА
ИНАЧЕ ЛОЖЬ
КОНЕЦ КАК НеВыгружалось,
ОсновнаяТаблица.Ссылка КАК СсылкаОбъекта
ИЗ
&ИмяТаблицы КАК ОсновнаяТаблица
ПРАВОЕ СОЕДИНЕНИЕ
&ИмяТаблицыИзменения КАК ТаблицаИзменений
ПО
ОсновнаяТаблица.Ссылка = ТаблицаИзменений.Ссылка
ГДЕ
ТаблицаИзменений.Узел = &ВыбранныйУзел
Если из базы данных был удален объект (например, справочник или документ), но запись о нем по какой-то причине осталась в таблице изменений (.Изменения) плана обмена, то при выполнении ПРАВОГО СОЕДИНЕНИЯ реквизит ОсновнаяТаблица.Ссылка возвращает значение NULL.
Платформа 1С воспринимает значение NULL как нераспределенное одинаковое значение. Если таких «битых» ссылок в таблице регистрантов несколько, в ключевой колонке СсылкаОбъекта образуется несколько значений NULL, что платформа трактует как дублирование ключевых полей.
Если необходимо быстро восстановить работоспособность формы обработки (сделав ее внешней), можно скорректировать текст запроса динамического списка, добавив условие отсечения несуществующих элементов:
ВЫБРАТЬ
ТаблицаИзменений.Ссылка КАК Ссылка,
ТаблицаИзменений.НомерСообщения КАК НомерСообщения,
ВЫБОР
КОГДА ТаблицаИзменений.НомерСообщения ЕСТЬ NULL ТОГДА ИСТИНА
ИНАЧЕ ЛОЖЬ
КОНЕЦ КАК НеВыгружалось,
ОсновнаяТаблица.Ссылка КАК СсылкаОбъекта
ИЗ
&ИмяТаблицы КАК ОсновнаяТаблица
ПРАВОЕ СОЕДИНЕНИЕ
&ИмяТаблицыИзменения КАК ТаблицаИзменений
ПО
ОсновнаяТаблица.Ссылка = ТаблицаИзменений.Ссылка
ГДЕ
ТаблицаИзменений.Узел = &ВыбранныйУзел
И НЕ ОсновнаяТаблица.Ссылка ЕСТЬ NULL
После добавления условия НЕ ОсновнаяТаблица.Ссылка ЕСТЬ NULL записи с «несуществующими» объектами перестанут попадать в динамический список, и ошибка исчезнет.
Скрытие удаленных объектов из списка не решает проблему в самой базе данных. Чтобы корректно очистить таблицу изменений от битых ссылок, воспользуемся методом ПланыОбмена.УдалитьРегистрациюИзменений().
Разберем пример кода для очистки таблицы изменений от несуществующих элементов:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ТаблицаИзменений.Ссылка КАК Ссылка
|ИЗ
| Справочник.Номенклатура.Изменения КАК ТаблицаИзменений
| ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Номенклатура КАК ОсновнаяТаблица
| ПО ТаблицаИзменений.Ссылка = ОсновнаяТаблица.Ссылка
|ГДЕ
| ТаблицаИзменений.Узел = &Узел
| И ОсновнаяТаблица.Ссылка ЕСТЬ NULL";
Запрос.УстановитьПараметр("Узел", ВыбранныйУзел);
Результат = Запрос.Выполнить().Выбрать();
Пока Результат.Следующий() Цикл
// Удаляем регистрацию изменений для битой ссылки
ПланыОбмена.УдалитьРегистрациюИзменений(ВыбранныйУзел, Результат.Ссылка);
КонецЦикла;
Появление ссылок на несуществующие объекты часто связано со сбоями при физическом удалении данных или нерегламентными операциями. Для очистки информационной базы рекомендуется выполнить штатную процедуру Тестирование и исправление в режиме Конфигуратора:
В типовых конфигурациях на платформе 1С:Предприятие 8.3 (использующих Библиотеку Стандартных Подсистем) предусмотрены штатные механизмы очистки некорректных регистраций. Для этого выполним следующие шаги: