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