Как устроен динамический список в 1С 8.3 и как его настроить в конфигураторе

· 9 мин

Содержание

Динамический список в 1С 8.3 — это реквизит управляемой формы типа ДинамическийСписок, который показывает данные из базы, но не загружает их в форму целиком. Платформа читает только ту порцию строк, которую видит пользователь, и дочитывает следующую при прокрутке. Поэтому список из миллиона документов открывается так же быстро, как из сотни.

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

Что такое динамический список и чем он отличается от обычной таблицы на форме

На управляемой форме есть два принципиально разных способа вывести таблицу:

  • 📋 Таблица значений (или табличная часть объекта) — данные целиком лежат в реквизите формы. Их передают на клиент вместе с формой, по ним можно пройти циклом, их можно редактировать прямо в ячейках.
  • 🔄 Динамический список — в форме хранится только описание выборки: источник, отбор, порядок, параметры. Сами строки живут в базе, на клиент приходит лишь видимая часть.
ПризнакТаблица значений на формеДинамический список
Где данныев реквизите формыв базе, читаются порциями
Объёмдесятки–сотни строк без проблемсотни тысяч и миллионы строк
Обход всех строк в кодеда, циклом Для Каждогонет, доступны только текущая и выделенные строки
Редактирование в ячейкахданет, изменение — через форму объекта
Актуальностьснимок на момент заполненияперечитывается из базы при обновлении
Отбор и сортировка пользователемнужно программироватьработают «из коробки»

Главное следствие: динамический список — инструмент просмотра и навигации. Он показывает свежие данные и не нагружает канал между клиентом и сервером. Но коллекции строк, которую можно перебрать или изменить, у него нет.

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

Как динамический список читает данные из базы

Механизм держится на трёх вещах: описании выборки, порционном чтении и ключе строки.

1. Описание выборки. Это либо основная таблица (справочник, документ, регистр), либо произвольный запрос. Поверх него платформа накладывает отбор, порядок и условное оформление. Всё это настройки системы компоновки данных, поэтому в коде вы работаете с объектами ЭлементОтбораКомпоновкиДанных, ПолеКомпоновкиДанных и подобными.

2. Порционное чтение. Когда включено свойство ДинамическоеСчитываниеДанных, платформа строит запрос с ограничением числа строк. Она читает столько записей, сколько помещается на экране, плюс небольшой запас. Пользователь листает вниз — уходит следующий запрос. Если свойство выключить, данные выборки читаются целиком.

3. Ключ строки. Чтобы помнить текущую и выделенные строки и продолжать чтение с нужного места, списку нужен уникальный ключ. Для основной таблицы это ссылка или набор измерений записи регистра. Если основная таблица не задана, а запрос произвольный, ключевое поле указывают вручную в настройках списка.

Отбор, который накладывает пользователь или код, попадает в условие запроса к СУБД. Поэтому фильтр по проиндексированному полю отрабатывает быстро даже на больших таблицах, а по неиндексированному — заметно медленнее.

Когда стоит выбрать динамический список, а когда нет

Динамический список подходит, если:

  • ✅ данных много или их количество заранее неизвестно — журналы, справочники, записи регистров;
  • ✅ пользователю нужно искать, фильтровать и сортировать без доработок;
  • ✅ важна актуальность: другие пользователи записали документ — после обновления он появится в списке;
  • ✅ строку открывают для редактирования в отдельной форме объекта.

Лучше взять таблицу значений или табличную часть, если:

  • ❌ нужно редактировать данные прямо в таблице и записывать пачкой;
  • ❌ строки получены расчётом и в базе в таком виде не хранятся (например, результат подбора с ручными правками);
  • ❌ нужно пройти по всем строкам на клиенте и что-то посчитать;
  • ❌ строк заведомо мало, а логика формы сложная.
Что вам нужно показать на форме?

Как создать динамический список в конфигураторе

Ниже — порядок для своей формы, например обработки или формы списка, которую вы делаете с нуля.

Шаг 1. Добавьте реквизит формы

  1. Откройте форму в конфигураторе, перейдите на вкладку Реквизиты.
  2. Добавьте новый реквизит, задайте имя, например Список.
  3. В поле Тип выберите ДинамическийСписок.

Шаг 2. Задайте источник данных

В палитре свойств реквизита найдите строку настройки списка и откройте её. В окне настройки:

  • для простого случая выберите Основную таблицу — например, Справочник.Контрагенты;
  • для выборки из нескольких таблиц включите флажок Произвольный запрос и напишите текст запроса или откройте конструктор запроса.

При произвольном запросе всё равно укажите основную таблицу, если в запросе есть её ссылка. Тогда двойной щелчок по строке откроет форму объекта, а команды «Создать», «Скопировать», «Пометить на удаление» заработают штатно.

Флажок динамического считывания данных оставьте включённым — это и есть порционное чтение.

Шаг 3. Выведите список на форму

  1. Перетащите реквизит Список из окна реквизитов в дерево элементов формы.
  2. Платформа создаст элемент Таблица и предложит колонки.
  3. Лишние колонки удалите, нужные расставьте в удобном порядке.

Шаг 4. Пример произвольного запроса

Допустим, в списке номенклатуры нужно показать остаток на выбранном складе. Если у регистра остатков измерения Номенклатура и Склад, запрос может выглядеть так:

ВЫБРАТЬ
    Номенклатура.Ссылка КАК Ссылка,
    Номенклатура.Наименование КАК Наименование,
    Номенклатура.Артикул КАК Артикул,
    ЕСТЬNULL(Остатки.КоличествоОстаток, 0) КАК Остаток
ИЗ
    Справочник.Номенклатура КАК Номенклатура
        ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах.Остатки(, Склад = &Склад) КАК Остатки
        ПО Номенклатура.Ссылка = Остатки.Номенклатура

Имена регистра и реквизитов здесь условные — подставьте свои. Условие Склад = &Склад внутри параметров виртуальной таблицы даёт одну строку на товар. Без него получилась бы строка на каждую пару «товар — склад», и ключ строки перестал бы быть уникальным.

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

Параметры запроса

Каждый параметр из текста запроса нужно заполнить до первого чтения данных, обычно в ПриСозданииНаСервере:

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    Список.Параметры.УстановитьЗначениеПараметра("Склад", Параметры.Склад);
КонецПроцедуры

Сменился склад в поле на форме — установите новое значение тем же методом. Список перечитается сам.

Отбор

Отбор программиста добавляют в коллекцию Список.Отбор:

ЭлементОтбора = Список.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Контрагент");
ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
ЭлементОтбора.ПравоеЗначение = Контрагент;
ЭлементОтбора.Использование = Истина;

В типовых конфигурациях на БСП удобнее вызвать ОбщегоНазначенияКлиентСервер.УстановитьЭлементОтбораДинамическогоСписка. Процедура находит существующий элемент по имени поля и меняет его, а не добавляет дубль при каждом вызове.

Сортировка

ЭлементПорядка = Список.Порядок.Элементы.Добавить(Тип("ЭлементПорядкаКомпоновкиДанных"));
ЭлементПорядка.Поле = Новый ПолеКомпоновкиДанных("Дата");
ЭлементПорядка.ТипУпорядочивания = НаправлениеСортировкиКомпоновкиДанных.Убыв;
ЭлементПорядка.Использование = Истина;

Текущая строка и поля, которых нет на экране

Данные текущей строки берут через Элементы.Список.ТекущиеДанные, выделенные строки — через Элементы.Список.ВыделенныеСтроки. В ТекущиеДанные попадают только поля, которые читаются из базы. Если колонка скрыта, а значение нужно в коде, включите для поля обязательное использование:

Список.УстановитьОбязательноеИспользование("Ответственный", Истина);

Обновление после записи

Список сам перечитывается по команде «Обновить» или при оповещении. Если объект изменили программно в другой форме, вызовите ОповеститьОбИзменении(Ссылка) — открытые списки этого типа обновятся. Принудительно обновить конкретный список можно методом Элементы.Список.Обновить().

Фильтрация и большие объёмы: как сохранить скорость списка

На базе в десятки гигабайт медленный список чаще всего тормозит не из-за платформы, а из-за запроса. Что помогает:

  • ⚡ Отбор по индексированным полям. Дата и ссылка в документах индексируются всегда, реквизиты — только если в конфигураторе задан индекс. Частый фильтр по неиндексированному реквизиту — повод его добавить.
  • ⚡ Условия внутри виртуальных таблиц. Отбор по складу или организации задавайте в параметрах Остатки(...) и Обороты(...), а не в ГДЕ после соединения.
  • ⚡ Без лишних соединений. Каждое соединение с табличной частью размножает строки и тяжелеет. Колонку «первый товар документа» лучше вывести отдельным реквизитом-кешем.
  • ⚡ Динамическое считывание включено. Без него запрос читает всю выборку при каждом обновлении.
  • ⚡ Осторожно с полнотекстовым поиском. Он быстрый, если индекс актуален, но без регулярного обновления индекса пользователь не найдёт свежие документы.

Событие ПриПолученииДанныхНаСервере позволяет дописать данные в строки перед показом. Оно вызывается на каждую порцию, поэтому тяжёлые запросы внутри него делают список заметно медленнее. Не обращайтесь к базе в цикле по строкам — соберите ключи и выполните один запрос на порцию.

Для проверки, куда уходит время, включите замер производительности в отладке или посмотрите технологический журнал: там видно, какой текст запроса платформа отправила в СУБД и сколько он выполнялся.

Что пользователь может сделать с динамическим списком сам

Пользователю не нужен программист, чтобы:

  • 🔍 найти строку — Ctrl+F или строка поиска над списком;
  • 🗂️ отфильтровать по значению ячейки — команда отбора по текущему значению в контекстном меню;
  • ↕️ отсортировать — щелчок по заголовку колонки;
  • ⚙️ сохранить свой вид — в меню Ещё есть команда настройки списка: отбор, порядок, группировка, условное оформление (например, красным просроченные счета);
  • 📤 выгрузить — команда вывода списка в табличный документ, дальше его можно сохранить в Excel.

Настройки сохраняются для каждого пользователя отдельно. Если список «сломался» — пропали строки или колонки, — в том же меню Ещё верните стандартные настройки. Частая причина «пропавших документов» — забытый отбор по организации или периоду, а не ошибка в базе.

Ошибки при работе с динамическими списками и как их избежать

Диагностика: выберите симптом

Ещё одна ловушка — путать отбор программиста и пользовательский. Отбор, установленный кодом в Список.Отбор, пользователь не всегда может снять. Если фильтр должен оставаться под контролем пользователя, выводите его в пользовательские настройки или на форму отдельным полем.

Частые вопросы

Можно ли получить из динамического списка все строки в коде?
Нет. Список хранит только описание выборки. Выполните на сервере запрос с тем же текстом и отбором или используйте ВыделенныеСтроки, если нужны отмеченные пользователем записи.
Есть ли динамический список в обычных формах?
В обычных формах 8.x используется табличное поле со списком справочника или документа — оно тоже читает данные порциями. Тип ДинамическийСписок с произвольным запросом относится к управляемым формам.
Как вывести итоги по колонке?
Посчитайте сумму на сервере отдельным запросом с тем же отбором и параметрами, положите её в реквизит формы и покажите в подвале колонки через путь к данным подвала. Пересчитывайте её при смене отбора.
Почему в списке не видно только что записанный документ?
Список перечитывается при обновлении или оповещении. Если документ записан программно, вызовите ОповеститьОбИзменении, иначе проверьте, не попадает ли он под активный отбор.
Влияют ли права доступа на динамический список?
Да. Запрос выполняется с правами текущего пользователя, поэтому при ограничениях на уровне записей он увидит только разрешённые строки.