К статье
Практический материал

Разработка и Конфигурация · 11 мин

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

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

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

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

Почему у динамического списка нет метода «Выгрузить»

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

Поэтому задача формулируется иначе: не «выгрузить список», а «получить те же данные, что показывает список, в виде таблицы значений». Для этого нужно взять запрос и настройки (отборы, сортировку) динамического списка и выполнить их самостоятельно — через объект СКД или через обычный запрос.

Способ 1: выгрузка через СКД с настройками списка

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

// Получаем текст запроса и параметры динамического списка

ТекстЗапроса = Список.ТекстЗапроса;

СхемаКомпоновки = Новый СхемаКомпоновкиДанных;

Источник = СхемаКомпоновки.ИсточникиДанных.Добавить();

Источник.Имя = "Источник1";

Источник.ТипИсточникаДанных = "Local";

Набор = СхемаКомпоновки.НаборыДанных.Добавить(Тип("НаборДанныхЗапросСхемыКомпоновкиДанных"));

Набор.Имя = "Набор1";

Набор.Запрос = ТекстЗапроса;

Набор.ИсточникДанных = "Источник1";

// Переносим настройки (отборы, сортировку) из списка

Настройки = Список.ПолучитьИсполняемыеНастройкиКомпоновкиДанных();

КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;

Макет = КомпоновщикМакета.Выполнить(СхемаКомпоновки, Настройки);

ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;

ПроцессорКомпоновки.Инициализировать(Макет);

ТаблицаРезультат = Новый ТаблицаЗначений;

ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений;

ПроцессорВывода.УстановитьОбъект(ТаблицаРезультат);

ПроцессорВывода.Вывести(ПроцессорКомпоновки);

Метод ПолучитьИсполняемыеНастройкиКомпоновкиДанных() возвращает настройки с учётом пользовательских отборов — именно то, что список реально показывает. Если нужны только настройки «по умолчанию», используйте свойство Список.НастройкиКомпоновкиДанных или Список.КомпоновщикНастроек.Настройки.

Способ 2: выполнить запрос списка напрямую

Если отборы пользователя не нужны или их можно перенести вручную, проще выполнить обычный запрос с тем же текстом, что и у списка. У объекта «Запрос» есть метод Выполнить().Выгрузить(), который сразу возвращает таблицу значений.

Запрос = Новый Запрос;

Запрос.Текст = Список.ТекстЗапроса;

// Переносим параметры списка

Для Каждого Параметр Из Список.Параметры.Элементы Цикл

Если Параметр.Использование Тогда

Запрос.УстановитьПараметр(Строка(Параметр.Параметр), Параметр.Значение);

КонецЕсли;

КонецЦикла;

ТаблицаРезультат = Запрос.Выполнить().Выгрузить();

Минус подхода: отборы, которые пользователь установил интерактивно, в текст запроса не попадут — они применяются платформой поверх запроса через СКД. Чтобы учесть их, придётся динамически дополнять текст запроса условиями либо вернуться к способу через компоновку данных.

Сравнение вариантов

Через СКД с настройками списка

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

Прямое выполнение запроса

Простой и быстрый код, но без интерактивных отборов. Подходит, когда состав данных известен заранее.

Построчный обход строк формы

Даёт только загруженные в форму строки. Подходит для небольших списков и когда нужны именно видимые данные.

Способ 3: обход строк списка на форме

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

ТаблицаРезультат = Новый ТаблицаЗначений;

ТаблицаРезультат.Колонки.Добавить("Ссылка");

Для Каждого ИдентификаторСтроки Из Элементы.Список.ВыделенныеСтроки Цикл

ДанныеСтроки = Список.НайтиПоИдентификатору(ИдентификаторСтроки);

НоваяСтрока = ТаблицаРезультат.Добавить();

НоваяСтрока.Ссылка = ДанныеСтроки.Ссылка;

КонецЦикла;

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

Учёт параметров и отборов: частые детали

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

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

Порядок действий для выгрузки через СКД
  1. 1
    Определите, какой запрос лежит в основе списка: свойство ТекстЗапроса или основная таблица.
  2. 2
    Создайте схему компоновки данных программно и поместите запрос в набор данных.
  3. 3
    Получите настройки списка через ПолучитьИсполняемыеНастройкиКомпоновкиДанных() или КомпоновщикНастроек.Настройки.
  4. 4
    Перенесите значения параметров списка в настройки компоновки.
  5. 5
    Скомпонуйте макет, выполните процессор компоновки и выведите результат в таблицу значений.
  6. 6
    Проверьте: количество строк и итоги таблицы должны совпадать с данными списка при тех же отборах.

Проверка результата и типичные ошибки

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

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

Типичные ошибки
01
Вызов Список.Выгрузить() — у динамического списка нет такого метода, код падает с ошибкой.
02
Игнорирование параметров списка — запрос выполняется без обязательных параметров или возвращает лишние данные.
03
Использование настроек по умолчанию вместо исполняемых — пользовательские отборы теряются, таблица не совпадает с экраном.
04
Обход списка построчно для больших таблиц — зависание клиента и неполные данные из-за порционной подгрузки.
05
Попытка выполнить клиентский метод на сервере — ПолучитьИсполняемыеНастройкиКомпоновкиДанных() недоступен вне контекста формы.
Контрольные точки

Как проверить результат

Количество строк
Норма

Совпадает с числом записей списка при тех же отборах

Тревожный признак

Строк больше или меньше — не перенесены отборы или параметры

Состав колонок
Норма

В таблице есть все поля, нужные для дальнейшей обработки

Тревожный признак

Отсутствуют поля, не включённые в выборку запроса

Значения параметров
Норма

Период, организация и другие параметры соответствуют установленным в списке

Тревожный признак

Данные за другой период или по другой организации

Альтернатива: выгрузка в табличный документ

Если конечная цель — печать или передача пользователю файла, таблица значений может быть лишним промежуточным звеном. Процессор вывода результата компоновки данных умеет выводить сразу в табличный документ (ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент), который затем сохраняется в Excel или PDF. Это короче и даёт форматированный результат.

Таблица значений оправдана, когда данные нужны для дальнейшей программной обработки: свёртки, сравнения, загрузки в другой объект, передачи через COM или веб-сервис.

Итог

Что важно запомнить

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

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

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

Нет, встроенного метода у динамического списка нет. Минимальный короткий вариант — выполнить запрос с текстом списка: Запрос.Текст = Список.ТекстЗапроса; ТЗ = Запрос.Выполнить().Выгрузить();, но он не учтёт интерактивные отборы пользователя.

Как выгрузить список с учётом отборов, которые поставил пользователь?

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

Что делать, если у списка пустой ТекстЗапроса?

Значит, список построен на основной таблице без произвольного запроса. Сформируйте запрос сами по шаблону «ВЫБРАТЬ ... ИЗ ИмяТаблицы», где имя таблицы возьмите из свойства ОсновнаяТаблица списка, и примените к нему настройки компоновки.

Почему выгруженная таблица не совпадает с тем, что видно в списке?

Чаще всего причины две: не перенесены значения параметров запроса или использованы настройки по умолчанию вместо исполняемых. Проверьте параметры через Список.Параметры и берите настройки методом ПолучитьИсполняемыеНастройкиКомпоновкиДанных().

Можно ли выгрузить только выделенные пользователем строки?

Да, обойдите коллекцию Элементы.Список.ВыделенныеСтроки, получите данные каждой строки через Список.НайтиПоИдентификатору() и добавьте нужные поля в таблицу значений. Это стандартный приём для команд «Обработать выбранные документы».

Есть ли ограничения по объёму при выгрузке?

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