Динамический список. Как это работает?

04 января 2013

Предисловие

Динамический список

Динамический список - это объект построения интерфейса, который предназначен для создания списка объектов или записей. Работа динамического списка основана на системе компоновке данных. Подробнее о нем вы можете прочитать здесь, мы же сегодня в статье разберем особенности его работы с базой данных.

В статье мы рассмотрим запросы к базе данных, которые формирует платформа при работе с динамическим списком. Определим, каким-образом его настройки влияют на работу платформы с SQL-базой.

Все примеры в статье сделаны на демонстрационной конфигурации, которую Вы можете скачать по ссылке в конце страницы.

Примечание: объект формы "Динамический список" появился в платформе 8.2. Его использование возможно только для управляемых форм.

Работа с базой данных

При открытии списка

В тестовой конфигурации создан справочник "Товары", в котором добавлен реквизит "Артикул" типа "Строка". Для примеров справочник заполнен пятью тысячами элементов. Заполнение произведено специальной обработкой "ЗаполнениеСправочникаТоваров", которая также находится в составе демонстрационной конфигурации.

При открытии формы списка справочника "Товары", динамический список будет содержать группы верхнего уровня, которые пользователь может разворачивать для просмотра вложенных элементов. SQL-запрос, формируемый платформой при открытии списка, будет выглядеть следующим образом:

При открытии списка

Опишем полученный запрос. Мы выбираем первые 42 записи из таблицы "_Reference7". Именно в этой таблице хранятся записи для всех элементов справочника "Товары". Почему выбирается именно 42 записи? Найти что-либо, что повлияет на эту цифру я не смог (ни размер экрана, ни общее количество записей в таблице). Делаю вывод, что платформа по умолчанию выбирает 42 записи при открытии динамического списка.

Предопределенный элемент

Поля выборки содержат те данные, которые будут отображаться непосредственно в динамическом списке. На рисунке подписано как каждое из полей отображается в режиме 1С:Предприятие. Может возникнуть логичный вопрос: "Для чего в выборке присутствует поле 'Предопределенный' и 'Пометка удаления'?". Нужны эти поля для того, чтобы платформа соответствующими пиктограммами могла выделять помеченные на удаление и предопределенные элементы. 

В разделе "ORDER BY" обозначены поля для сортировки результирующей выборки: "ЭтоГруппа", "Наименование", "Ссылка" (см. подписи полей выборки). В разделе наложения условий указывается отбор по родителю для выбираемых элементов. В нашем случае, поскольку динамический список был только открыт, отбираются записи без родительского элемента. В переменную условия "P1" передается пустое значение ссылки на элемент родителя.

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

Форма списка

При раскрытии группы с элементами

Раскрывая группу элементов в динамическом списке, платформа 1С:Предприятие формирует следующий запрос:

Раскрытие группы элементов

Полученный запрос похож на рассматриваемый нами ранее. Отличие заключается лишь в количестве выбираемых записей и накладываемом условии на выборку данных. В случае, когда происходит открытие группы элементов, то платформа задает выбор только для первых 22-х элементов.

Раскрытие группы элементов

Условие осталось прежним - выбираются записи только определенного родительского элемента, только в этом случае в параметр уже передается ссылка на открываемую группу элементов. На скриншоте вы видите ссылку на группу "Группа 1 - 1".

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

Пролистываем список элементов

Ранее уже было сказано, что при раскрытии группы справочника платформа формирует запрос на выборку первых 22-х элементов. Но что происходит, когда пользователь листает динамический список и выбранные элементы заканчиваются? В таком случае платформа формирует новый запрос и выбирает последующую порцию данных для просмотра:

Пролистываем список

Важным моментом в формировании данного запроса является условие выборки. В нем для тех полей, которые участвуют в сортировке результата запроса, накладываются дополнительные условия для получения последующих 22-х записей. В нашем случае это поля "_Foder", "_Description" и "_IDRRef". 

Примечание: поле "_Folder" указывает на принадлежность записи таблицы группе или элементу справочника. Если значение в поле равно "0x00", тогда это группа. Если же значение "0x01", тогда это элемент справочника. Для того, чтобы разработчику было удобно работать с данным полем, его преобразовывают обратным образом. В запросе имеется выражение: Это группа

То есть, если для платформы значение "0x00" (Ложь) указывает, что запись принадлежит группе, то для разработчика то же самое значение говорит, что запись принадлежит элементу.

Пролистываем список

 Для всех полей, кроме ссылки, условие имеет вид "больше или равно". Для ссылки оно всегда "больше". В параметры передаются данные от последней выбранной записи в динамическом списке. Например, когда мы разворачивали группу элементов "Группа - 1 - 1", то последний из 22-х отобранных элементов был "Элемент - 1 - 1 - 118". В параметры запроса передается ссылка на родителя, флаг "ЭтоГруппа", наименование и ссылка на элемент "Элемент - 1 - 1 - 118" для, соответственно, "P1", "P2", "P3" и "P4". 

Прежде чем формировать выборку последующих 22-х элементов, платформа получает данные для последнего выбранного элемента:
Получение данных по последней выбранной записи

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

Настройка отображения списка

Отображение

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


В нашем примере мы работали с иерархическим справочником. Но какие запросы будут для справочника без иерархии, если режим просмотра для него установлен "списком"? Все просто. Запросы будут аналогичными, с учетом того, что поле "родитель" будет всегда пустым. Запросы, которые будет формировать платформа, походят на SQL-запросы при раскрытии группы с элементами и при прокрутке списка. 

Группировки динамического списка

При использовании группировок динамического списка, получаемые данные будут группироваться по выбранному полю (полям). Включение группировок приведет к усложнению SQL-запросов к базе, так как платформе необходимо получать дополнительные данные для группировок выборки:

Запрос группировки

Пролистываем список

Обратите внимание на появившееся дополнительное левое соединение и дополнительные операции для полей выборки.

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

Не смотря на то, что чтение будет происходить динамически (первая выборка при открытии списка будет содержать 42 записи), включение группировок  увеличивает нагрузку на сервер.

Динамическое считывание данных

Реквизит формы с типом "Динамический список" имеет настройку "Динамическое считывание данных" (см. след. скриншот).

Настройки списка

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

Вспомните, что порции, которыми платформа "дочитывала" просматриваемый список, составляли 22 записи. При отключенной опции запрос к базе данных будет выглядеть следующим образом:

Без динамического считывания

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

Динамическое считывание данных доступно только в том случае, если для динамического списка установлена основная таблица. В нашем примере это справочник "Товары". Если основной таблицы нет, то платформа не может определять порции выбираемых данных. Предполагается, что если нет основной таблицы, то невозможно определить позицию одной записи среди других по ссылке для объектных типов или ключу записи для регистров.

Отбор и сортировка

Поскольку динамические списки работают на системе компоновки данных, то для них есть возможность в пользовательском режиме устанавливать отборы и поля сортировки. При построении запросов  к базе данных в таких случаях платформа ведет себя весьма предсказуемо. Для примера, установим отбор по полю "Родитель" и сортировку по полю "Артикул". В результате платформой будет сформирован следующий запрос на выборку данных:

Запрос отбор и сортировка

В запросе добавилось условие выборки по параметру "P2" и сортировка по полю "_Fld8". На рисунке новые части запроса обведены серой линией. В параметр "Р2" передается ссылка на значение отбора, выбранного пользователем для родителя. В поле "_Fld8" хранятся значения артикула, и именно по этому полю была установлена сортировка. Таким образом, для пользователей платформа предоставляет очень удобный механизм настройки динамических списков данных, а основанный на системе компоновки данных. 

 

Выводы

Динамические списки, появившиеся в платформе версии 8.x, являются очень удобным интерфейсным объектом при работе с большими объемами данных. Они позволяют экономить ресурсы системы при работе с базой, а также имеют возможность гибкой настройки для пользователя. Причем каких-либо специфических знаний по работе на платформе 1С:Предприятие не нужно.

Мы рассмотрели поведение программы для самых распространенных событий динамического списка. Однако стоит отметить, что её поведение в некоторых случаях пока что не понятно. На первый взгляд, при выполнении простых действий, таких как настройка отборов или сортировки, программа выполняет излишние запросы к базе. В дальнейшем планирую разобраться со всеми действиями платформы, чтобы вести разработку на ней с максимальной эффективностью.

В одной из следующих статей будет идти речь об оптимизации работы динамических списков. Планирую также написать статью о нюансах построения интерфейса с помощью данного объекта.

P.S. Для трассировки SQL-запросов, формируемых платформой, был использован инструмент"DataWizard SQL Performance Profiler".



comments powered by Disqus