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