Почему в динамическом списке 1С пропадают дублирующие строки и как правильно использовать ОБЪЕДИНИТЬ ВСЕ

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

При разработке интерфейсов на платформе 1С:Предприятие 8 программисты часто сталкиваются с нестандартным поведением динамических списков. Одной из таких проблем является «схлопывание» или исчезновение строк при попытке вывести один и тот же объект (например, документ) несколько раз с разными дополнительными данными. В этой статье мы подробно разберем, почему динамический список в 1С (особенно в конфигурациях на обычных формах, таких как УПП 1.3) может вести себя некорректно при использовании объединений и инструкции ПЕРВЫЕ.

Разберем причину: Инструкция ПЕРВЫЕ в динамических списках

Первое, на что стоит обратить внимание — это использование конструкции ВЫБРАТЬ ПЕРВЫЕ внутри текста запроса динамического списка. Рассмотрим ситуацию: разработчик хочет получить по одной записи из разных источников для одного документа и использует ОБЪЕДИНИТЬ ВСЕ. Однако, согласно документации и практике, инструкция ПЕРВЫЕ на верхнем уровне запроса динамического списка либо игнорируется, либо приводит к непредсказуемым результатам.

Проанализируем механизм работы платформы. Когда мы открываем форму со списком, система не выполняет ваш запрос «как есть». Она оборачивает его в подзапрос, добавляет свои условия отбора, сортировки и, что самое важное, собственные ограничения количества записей (например, TOP 45) для обеспечения постраничного вывода. Наличие вашей инструкции ПЕРВЫЕ внутри этого механизма нарушает логику построения SQL-запроса. В режиме совместимости 8.2 использование ПЕРВЫЕ при указанной основной таблице вовсе запрещено платформой.

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

Выясним причину исчезновения дублей: Уникальность ключа строки

Вторая и самая важная проблема заключается в том, как динамический список идентифицирует строки. Каждая строка в списке должна иметь уникальный ключ. Рассмотрим ситуацию автора темы: он хочет вывести документ РеализацияТоваровУслуг дважды — один раз с данными по счету-фактуре, второй раз с данными по ТОРГ-12.

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

  1. При обновлении списка платформа видит два одинаковых ключа и «схлопывает» их в одну строку.
  2. При прокрутке (скроллинге) данные могут временно отображаться корректно, так как система подгружает их порциями и еще не успела перестроить внутренний индекс видимых строк.
  3. Возникают ошибки визуализации и позиционирования курсора.

Как правильно настроить динамический список для вывода дублей

Для того чтобы динамический список корректно отображал несколько строк для одного и того же документа, нам необходимо выполнить два условия: убрать основную таблицу и сформировать составной уникальный ключ. Рассмотрим этот процесс по шагам.

Шаг 1. Отказ от основной таблицы. В свойствах динамического списка в конфигураторе необходимо очистить поле «Основная таблица». Это переведет список в режим работы с произвольным запросом без жесткой привязки к метаданным одного объекта.

Шаг 2. Формирование уникального ключа в запросе. Нам нужно создать поле, которое будет уникальным для каждой строки в объединении. Давайте посмотрим на пример запроса, который решает эту задачу:


ВЫБРАТЬ
    Реализация.Ссылка КАК Документ,
    "СчетФактура" КАК ВидДокумента,
    Реализация.Ссылка.УникальныйИдентификатор() + "СФ" КАК КлючСтроки,
    ... данные по СФ ...
ИЗ
    Документ.РеализацияТоваровУслуг КАК Реализация

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
    Реализация.Ссылка,
    "ТОРГ12",
    Реализация.Ссылка.УникальныйИдентификатор() + "Т12",
    ... данные по ТОРГ-12 ...
ИЗ
    Документ.РеализацияТоваровУслуг КАК Реализация

Шаг 3. Настройка ключа в конфигураторе. После изменения запроса необходимо зайти в «Настройку списка» и в списке полей найти наше новое поле КлючСтроки. В колонке «Использовать как ключ» нужно установить флажок. Теперь платформа будет понимать, что это разные записи, несмотря на то, что ссылка на документ в них совпадает.

Проанализируем ситуацию с производительностью

Использование ОБЪЕДИНИТЬ ВСЕ в динамических списках (особенно в УПП на больших объемах данных) — это тяжелая операция. Когда мы убираем основную таблицу, мы лишаем платформу возможности эффективно использовать индексы для стандартных отборов. Система будет вынуждена выполнять объединение больших таблиц перед тем, как наложить фильтры.

Чтобы минимизировать нагрузку, рекомендуется:

Типичные ошибки при работе с УПП 1.3 и режимом совместимости 8.2

Автор темы упомянул, что «сломал базу», пытаясь изменить режим совместимости. Важно помнить, что в старых конфигурациях (УПП, ЗУП 2.5, КА 1.1) многие механизмы жестко завязаны на поведение платформы версии 8.2. Изменение режима совместимости меняет логику работы блокировок и трансляции запросов. Если вам нужно решить задачу в рамках 8.2.16, придерживайтесь следующих правил:

  1. Никогда не используйте РАЗЛИЧНЫЕ и ПЕРВЫЕ в запросах динамических списков, если хотите стабильной работы.
  2. Если данные в списке «прыгают» при прокрутке — проверяйте уникальность полей, выбранных в качестве ключей.
  3. Для объединений всегда используйте ОБЪЕДИНИТЬ ВСЕ вместо ОБЪЕДИНИТЬ, так как обычное объединение выполняет дополнительную операцию поиска дублей, что крайне медленно и часто бессмысленно для ДС.

Соблюдение этих рекомендаций позволит вам создавать сложные и функциональные динамические списки, которые будут работать предсказуемо и быстро даже в устаревших программных средах.

← На главную