Почему пропадают или некорректно отображаются документы в динамическом списке 1С?

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

Работа с динамическими списками в 1С — это не просто написание запроса. Это взаимодействие со сложным механизмом платформы, который оптимизирует получение данных для интерфейса. Часто разработчики сталкиваются с ситуацией: в консоли запросов всё отображается идеально, а в форме динамического списка данные начинают «прыгать», пропадать или дублироваться. Особенно остро это проявляется, когда в запросе используются соединения, группировки и временные таблицы.

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

Причина 1: Отсутствие или неверная настройка основной таблицы

Разберем, как платформа 1С работает с динамическим списком. В отличие от обычного запроса, динамический список считывает данные порциями (динамическое считывание). Чтобы понимать, какие именно строки сейчас отображаются на экране, платформе нужен уникальный идентификатор строки — ключ.

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

Причина 2: Проблемы с временными таблицами и группировками

Рассмотрим технический нюанс использования временных таблиц (ВТ) в динамических списках. Платформа «оборачивает» ваш текст запроса в подзапрос, добавляя свои условия отбора, сортировки и ограничения количества строк (например, ВЫБРАТЬ ПЕРВЫЕ 45...).

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

Посмотрим на пример некорректной логики в запросе:


// Пример проблемного кода в динамическом списке
ВЫБРАТЬ
    Заявка.Ссылка КАК Ссылка,
    МАКСИМУМ(Размещение.Дата) КАК ДатаПоследнегоРазмещения
ПОМЕСТИТЬ ВтПоследниеДокументы
ИЗ
    Документ.Заявка КАК Заявка
ЛЕВОЕ СОЕДИНЕНИЕ Документ.Размещение КАК Размещение
    ПО Размещение.Заявка = Заявка.Ссылка
ГРУППИРОВАТЬ ПО
    Заявка.Ссылка
;

ВЫБРАТЬ
    Т.Ссылка,
    Вт.ДатаПоследнегоРазмещения
ИЗ
    Документ.Заявка КАК Т
ЛЕВОЕ СОЕДИНЕНИЕ ВтПоследниеДокументы КАК Вт
    ПО Т.Ссылка = Вт.Ссылка

Такой подход часто приводит к тому, что при появлении новой строки в списке (или при прокрутке), данные в старых строках могут затираться или отображаться некорректно, так как контекст временной таблицы может конфликтовать с механизмом порционного считывания 1С.

Причина 3: Использование «Среза последних» и группировок для поиска связанных документов

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

Выясним, как правильно реализовать получение «последнего» документа:

  1. Коррелированные подзапросы: Вместо временных таблиц и группировок попробуйте использовать вложенный запрос в полях выбора или в соединении. Это более «понятно» для оптимизатора 1С при работе со списками.
  2. Физические поля: Самый надежный и производительный способ — записывать ссылку на актуальное «Размещение» или «Бронирование» прямо в реквизит документа «Заявка» в момент проведения этих связанных документов. Тогда в динамическом списке вам не придется строить сложные связи, вы просто выберете поле Заявка.АктуальноеРазмещение.
  3. Регистры сведений: Используйте вспомогательный регистр сведений, где в качестве измерения будет «Заявка», а в ресурсе — ссылка на последний документ. Соединение с физической таблицей регистра работает в разы стабильнее, чем запросы с группировками.

Рекомендация: Отключение динамического считывания

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

Что это даст: Запрос будет выполняться целиком, как в консоли запросов. Платформа не будет пытаться «резать» его на порции и добавлять свои условия ГДЕ для пагинации. Минусы: Если данных в таблице много (более нескольких тысяч), производительность формы резко упадет, так как клиент будет ждать получения всего объема данных от сервера СУБД.

Практические шаги по исправлению

Рассмотрим алгоритм действий для стабилизации работы списка:

  1. Проверьте ключевые поля: Зайдите в настройку списка -> Настройка списка -> Вкладка «Запрос» -> Кнопка «Настройка списка». Убедитесь, что для всех полей, которые не входят в основную таблицу, правильно определены роли (особенно роль «Ключ»).
  2. Упростите связи: Замените ГРУППИРОВАТЬ ПО на ВЫБРАТЬ РАЗЛИЧНЫЕ или перенесите логику вычисления максимума в отдельную функцию (но помните о производительности).
  3. Используйте Вложенные запросы вместо ВТ: В динамических списках 1С Вложенные запросы зачастую работают стабильнее, так как платформа лучше интегрирует в них свои условия отбора.

Посмотрим на пример правильного соединения для получения связанного документа без использования группировки во всем списке:


ВЫБРАТЬ
    Заявка.Ссылка,
    (ВЫБРАТЬ ПЕРВЫЕ 1
        Размещение.Ссылка
    ИЗ
        Документ.Размещение КАК Размещение
    ГДЕ
        Размещение.Заявка = Заявка.Ссылка
    УПОРЯДОЧИТЬ ПО
        Размещение.Дата УБЫВ) КАК ПоследнееРазмещение
ИЗ
    Документ.Заявка КАК Заявка

Такой подход (коррелированный подзапрос) гарантирует, что для каждой строки будет найдено свое «Размещение», и данные не будут «пропадать» при обновлении списка или добавлении новых записей. Помните, что динамический список — это в первую очередь инструмент отображения, и перегружать его сложной аналитикой в запросе не стоит.

← На главную