Как выгрузить данные из динамического списка в таблицу значений в 1С?

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

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

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

Основной подход: использование Компоновщика Макета

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

Разберем этот процесс по шагам.

  1. Получаем настройки компоновки данных. У каждого динамического списка есть свойство КомпоновщикНастроек. Именно в нем хранятся все пользовательские настройки: порядок, условное оформление и фильтры, включая расширенные возможности, такие как «подобно» в списке. Мы забираем их с помощью метода ПолучитьНастройки().
  2. Создаем компоновщик макета. Это ключевой объект СКД, который отвечает за "сборку" итогового макета на основе схемы и настроек. Мы инициализируем его типом КомпоновщикМакетаКомпоновкиДанных.
  3. Генерируем макет компоновки. С помощью метода Выполнить() компоновщика макета мы создаем сам макет. На вход ему нужно подать схему компоновки данных (которая лежит в основе динамического списка), полученные нами настройки и, опционально, данные расшифровки.
  4. Инициализируем процессор компоновки. После того как макет готов, его нужно обработать. Для этого используется объект ПроцессорКомпоновкиДанных.
  5. Выводим результат в таблицу значений. Наконец, мы используем ПроцессорВыводаРезультатаКомпоновкиДанныхВТаблицуЗначений. Этот объект принимает результат работы процессора компоновки и выгружает его в созданную нами таблицу значений.

Пример реализации в коде

Посмотрим на практический пример кода, который можно разместить в команде на форме. Предположим, что наш динамический список на форме называется Список.


&НаКлиенте
Процедура ВыгрузитьСписокВТЗ(Команда)
    ТаблицаНаСервере = ПолучитьТаблицуСпискаНаСервере();
    // Далее можно работать с полученной таблицей на клиенте
    // Например, вывести количество строк
    Сообщить("Выгружено строк: " + ТаблицаНаСервере.Количество());
КонецПроцедуры

&НаСервере
Функция ПолучитьТаблицуСпискаНаСервере()
    // 1. Получаем настройки компоновки из динамического списка
    // Объект "Список" - это реквизит формы типа ДинамическийСписок
    НастройкиКД = ЭтотОбъект.Список.КомпоновщикНастроек.ПолучитьНастройки();

    // 2. Создаем компоновщик макета и инициализируем его
    КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;

    // 3. Получаем схему компоновки данных из динамического списка
    СхемаКД = ЭтотОбъект.Список.ПолучитьСхемуКомпоновкиДанных();

    // 4. Генерируем макет на основе схемы и настроек
    // Третий параметр (ДанныеРасшифровки) нам не нужен, поэтому передаем Неопределено
    МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКД, НастройкиКД, Неопределено);

    // 5. Создаем и инициализируем процессор компоновки данных
    ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
    ПроцессорКомпоновки.Инициализировать(МакетКомпоновки);

    // 6. Создаем таблицу, в которую будем выгружать результат
    ТаблицаРезультат = Новый ТаблицаЗначений;

    // 7. Создаем и настраиваем процессор вывода
    ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТаблицуЗначений;
    ПроцессорВывода.УстановитьОбъект(ТаблицаРезультат);

    // 8. Выполняем вывод результата
    ПроцессорВывода.Вывести(ПроцессорКомпоновки);

    // 9. Возвращаем заполненную таблицу значений
    Возврат ТаблицаРезультат;
КонецФункции

Рассмотрим подробнее, что происходит в этом коде:

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

На сервере мы последовательно выполняем все шаги, описанные выше. Важно понимать, что объект ЭтотОбъект.Список — это наш реквизит формы с типом ДинамическийСписок. Через него мы получаем доступ ко всем необходимым данным: схеме компоновки (ПолучитьСхемуКомпоновкиДанных) и текущим настройкам (КомпоновщикНастроек.ПолучитьНастройки).

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

Альтернативный вариант: получение текста запроса

В некоторых, более сложных случаях, может потребоваться не просто выгрузить данные, а получить сам текст запроса, который генерирует динамический список со всеми настройками. Это может быть полезно для отладки (для чего отлично подойдет Консоль запросов УФ) или для использования этого запроса в других механизмах. Сделать это можно похожим образом.

Основное отличие в том, что вместо процессора вывода в таблицу значений мы используем другой метод для получения информации о запросе. Это менее распространенная задача, но полезно знать о такой возможности.


&НаСервере
Функция ПолучитьТекстЗапросаСписка()
    // Шаги 1-3 аналогичны предыдущему примеру
    НастройкиКД = ЭтотОбъект.Список.КомпоновщикНастроек.ПолучитьНастройки();
    СхемаКД = ЭтотОбъект.Список.ПолучитьСхемуКомпоновкиДанных();
    
    // Используем специальный объект для получения информации о данных компоновки
    ДанныеКомпоновки = Новый ДанныеКомпоновкиДанных(СхемаКД);

    // Создаем макет компоновки, но для другого объекта
    Макет = Новый МакетКомпоновкиДанных;
    Макет.Выполнить(ДанныеКомпоновки, НастройкиКД);
    
    // Из полученного макета можно извлечь текст запроса
    ТекстЗапроса = Макет.НаборыДанных[0].Запрос;

    Возврат ТекстЗапроса;
КонецФункции

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

Итоги

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

  1. Выполнять все операции на сервере. Это обязательное условие для работы с данными.
  2. Использовать связку объектов СКД: КомпоновщикМакетаКомпоновкиДанных, ПроцессорКомпоновкиДанных и ПроцессорВыводаРезультатаКомпоновкиДанныхВТаблицуЗначений.
  3. Получать исходные данные (схему и настройки) непосредственно из реквизита формы типа ДинамическийСписок.
  4. В результате вы получите объект ТаблицаЗначений, полностью идентичный представлению данных в списке на форме.

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

← На главную