При разработке интерфейсов на платформе 1С:Предприятие 8.3 программисты часто сталкиваются с ситуацией, когда динамический список (ДС) начинает вести себя непредсказуемо. Одной из самых неприятных ошибок является сообщение: «Обнаружено дублирование ключевых значений в колонках...». Самое странное здесь то, что при проверке того же самого запроса в «Консоли запросов» результат выглядит идеально — никаких дублей нет. Разберемся детально в механизмах работы динамического списка, выясним причины такого поведения и найдем надежные способы решения проблемы.
Прежде всего, нам необходимо понять, что текст запроса, который мы пишем в настройках динамического списка, — это не тот финальный запрос, который отправляется на SQL-сервер. Динамический список — это сложный программный объект, который «оборачивает» ваш код своей логикой. Рассмотрим, что именно делает платформа:
ВЫБРАТЬ ПЕРВЫЕ....Проанализируем ситуацию: если платформа теряет понимание того, какое поле является уникальным, она начинает пытаться вычислить ключ самостоятельно, объединяя значения всех доступных колонок. Именно на этом этапе чаще всего и возникает ошибка дублирования.
Как выяснилось в ходе обсуждения, наиболее частой причиной ошибки является поведение Конструктора запроса. Рассмотрим этот момент подробнее. В настройках динамического списка есть критически важное поле — Основная таблица. Если оно заполнено, платформа точно знает, что поле Ссылка из этой таблицы является уникальным ключом.
Однако при использовании Конструктора запроса, если вы добавляете сложные соединения (особенно ЛЕВОЕ СОЕДИНЕНИЕ), Конструктор может «решить», что запрос стал слишком сложным для автоматического определения связей, и самопроизвольно очистить поле Основная таблица на вкладке «Дополнительно». Как только это происходит:
Ссылка как единственному ключу.Решение: Всегда проверяйте заполнение поля Основная таблица после использования Конструктора запроса. Если оно очистилось — верните его вручную.
Еще один важный нюанс связан с использованием полей составного типа в условиях соединения. Если поле, по которому выполняется ЛЕВОЕ СОЕДИНЕНИЕ, может содержать ссылки на разные типы объектов, СУБД выполняет это соединение через сложную структуру внутренних JOIN-ов к разным таблицам метаданных.
Проанализируем, почему это вызывает ошибку:
CASE.Для решения этой проблемы рекомендуется использовать оператор ВЫРАЗИТЬ(...) КАК (...). Например:
ВЫБРАТЬ
ОсновнаяТаблица.Ссылка,
ПрисоединеннаяТаблица.Наименование
ИЗ
Документ.РеализацияТоваровУслуг КАК ОсновнаяТаблица
ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Контрагенты КАК ПрисоединеннаяТаблица
ПО (ВЫРАЗИТЬ(ОсновнаяТаблица.Контрагент КАК Справочник.Контрагенты)) = ПрисоединеннаяТаблица.Ссылка
Автор темы нашел «обходной путь» — обернуть присоединяемую таблицу во вложенный запрос. Выясним, почему это сработало. Использование конструкции (ВЫБРАТЬ ... ИЗ ...) КАК ВложенныйЗапрос создает для платформы и оптимизатора СУБД жесткую границу.
Когда мы соединяем основную таблицу с вложенным запросом:
ВЫБРАТЬ ПЕРВЫЕ...), которые платформа накладывает сверху.Если вы столкнулись с ошибкой дублирования ключевых значений, выполните следующие шаги:
ПриСозданииНаСервере или через отдельную кнопку отладки проанализируйте реальную схему ДС.TOP, ORDER BY и дополнительные условия.ВЫРАЗИТЬ.Таким образом, динамический список — это не просто «окно» для отображения результата запроса, а сложный механизм управления данными. Понимание того, как платформа трансформирует ваш запрос и как Конструктор запроса влияет на настройки Основной таблицы, позволяет быстро решать технические проблемы и создавать отзывчивые интерфейсы.