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

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

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

Суть проблемы и механизм «ВидДляСписка»

В конфигурациях на базе Библиотеки стандартных подсистем (БСП) контактная информация хранится в табличных частях справочников или в специальном регистре сведений. Для оптимизации работы динамических списков разработчики фирмы «1С» внедрили специальное служебное поле — ВидДляСписка. Рассмотрим подробнее, зачем оно нужно.

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

Чтобы этого избежать, БСП использует следующий алгоритм:

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

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

Диагностика: ищем дубли в контактной информации

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


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

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    ВТ_Дубли.Ссылка КАК Объект,
    ВТ_Дубли.ВидДляСписка КАК ВидКИ,
    КИ.НомерСтроки КАК НомерСтроки,
    КИ.Представление КАК Представление
ИЗ
    ВТ_Дубли КАК ВТ_Дубли
ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.Партнеры.КонтактнаяИнформация КАК КИ
    ПО ВТ_Дубли.Ссылка = КИ.Ссылка
    И ВТ_Дубли.ВидДляСписка = КИ.ВидДляСписка
УПОРЯДОЧИТЬ ПО
    Объект,
    НомерСтроки

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

Разбор запроса динамического списка

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


ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Партнеры.КонтактнаяИнформация КАК ПартнерыКонтактнаяИнформация
    ПО (ПартнерыКонтактнаяИнформация.Ссылка = ДокументЗаказКлиента.Партнер
    И ПартнерыКонтактнаяИнформация.ВидДляСписка = &П)

Здесь крайне важно наличие параметра &П (ссылка на вид КИ) и фильтра по ВидДляСписка. Если вы пишете запрос вручную, убедитесь, что вы не забыли это условие. Без него вы получите столько строк в списке, сколько всего записей контактной информации у данного партнера.

Как правильно исправлять данные

Если вы обнаружили дубли, просто «зачистить» представления недостаточно. Нужно восстановить логику БСП. Рассмотрим два способа решения:

Способ 1: Использование типового программного интерфейса

Чтобы в будущем не сталкиваться с подобными ошибками при программном изменении телефонов или адресов, никогда не работайте с табличной частью контактной информации напрямую через Объект.КонтактнаяИнформация.Добавить(). Используйте методы программного интерфейса БСП. Разберем пример:


// Правильный способ записи КИ, который сам обновит поле ВидДляСписка
УправлениеКонтактнойИнформацией.ЗаписатьКонтактнуюИнформацию(СсылкаНаОбъект, ТаблицаНовойКИ, Ложь);

Метод ЗаписатьКонтактнуюИнформацию автоматически проанализирует состав записей, создаст нужную сводную строку с запятыми и корректно расставит значения в поле ВидДляСписка.

Способ 2: Ручное исправление «битых» записей

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

Почему возникает ошибка про «Расширения конфигурации»?

Многих смущает текст ошибки, упоминающий расширения. Выясним причину: это особенность работы платформы 1С 8.3. Когда в системе подключены расширения, механизмы проверки уникальности ключей в динамических списках становятся более строгими. Платформа проверяет соответствие результирующей выборки метаданным. Если Ссылка заказа перестает быть уникальной из-за неверного JOIN, 1С предполагает, что структура данных была изменена расширением некорректно, и выдает стандартное системное предупреждение. Отключение расширений может скрыть ошибку (список откроется, но будет содержать дубли строк), но это не решение проблемы, а лишь маскировка симптомов.

Альтернативный вариант: ПриПолученииДанныхНаСервере

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

Проанализируем этот подход:

  1. В запросе динамического списка создается пустое текстовое поле (колонку).
  2. В событии ПриПолученииДанныхНаСервере для тех 20-40 строк, которые реально отображаются на экране, одним запросом выбираются все телефоны и программно устанавливаются в созданную колонку.

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

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

← На главную