Разработка и Конфигурация · 11 мин
Как выгрузить динамический список в таблицу значений в 1С
Разбираем, как выгрузить динамический список в таблицу значений в 1С: ограничения платформы, обходные решения через СКД, запрос и построчную выборку, примеры кода.
Динамический список в 1С — это объект формы, который автоматически выполняет запрос к базе данных и отображает результат с поддержкой отборов, сортировки и динамического обновления. У него нет встроенного метода «Выгрузить()», как у таблицы значений или табличного документа, поэтому прямое обращение вида ДинамическийСписок.Выгрузить() вызовет ошибку. Тем не менее выгрузить данные динамического списка в таблицу значений можно несколькими рабочими способами.
Выбор способа зависит от того, нужны ли текущие отборы и сортировка, установленные пользователем, важна ли производительность и где выполняется код — на форме, в модуле объекта или во внешней обработке. Ниже разобраны основные подходы: через схему компоновки данных, через программное выполнение запроса списка и через построчный обход элементов формы.
Почему у динамического списка нет метода «Выгрузить»
Динамический список — это не хранилище данных, а представление. Он подгружает записи порциями по мере прокрутки, поэтому в памяти одновременно находится только видимая часть. Платформа сознательно не даёт метода выгрузки всего содержимого: для больших таблиц (журналы документов, регистры с миллионами записей) такая операция исчерпала бы память сервера или клиента.
Поэтому задача формулируется иначе: не «выгрузить список», а «получить те же данные, что показывает список, в виде таблицы значений». Для этого нужно взять запрос и настройки (отборы, сортировку) динамического списка и выполнить их самостоятельно — через объект СКД или через обычный запрос.
Способ 1: выгрузка через СКД с настройками списка
Это основной и рекомендуемый способ, когда динамический список построен на произвольном запросе и нужно учесть отборы, которые пользователь установил в форме. Идея: создать схему компоновки данных на основе текста запроса списка, перенести в неё настройки списка и выполнить компоновку с выводом в таблицу значений.
// Получаем текст запроса и параметры динамического списка
ТекстЗапроса = Список.ТекстЗапроса;
СхемаКомпоновки = Новый СхемаКомпоновкиДанных;
Источник = СхемаКомпоновки.ИсточникиДанных.Добавить();
Источник.Имя = "Источник1";
Источник.ТипИсточникаДанных = "Local";
Набор = СхемаКомпоновки.НаборыДанных.Добавить(Тип("НаборДанныхЗапросСхемыКомпоновкиДанных"));
Набор.Имя = "Набор1";
Набор.Запрос = ТекстЗапроса;
Набор.ИсточникДанных = "Источник1";
// Переносим настройки (отборы, сортировку) из списка
Настройки = Список.ПолучитьИсполняемыеНастройкиКомпоновкиДанных();
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
Макет = КомпоновщикМакета.Выполнить(СхемаКомпоновки, Настройки);
ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(Макет);
ТаблицаРезультат = Новый ТаблицаЗначений;
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений;
ПроцессорВывода.УстановитьОбъект(ТаблицаРезультат);
ПроцессорВывода.Вывести(ПроцессорКомпоновки);
Метод ПолучитьИсполняемыеНастройкиКомпоновкиДанных() возвращает настройки с учётом пользовательских отборов — именно то, что список реально показывает. Если нужны только настройки «по умолчанию», используйте свойство Список.НастройкиКомпоновкиДанных или Список.КомпоновщикНастроек.Настройки.
Способ 2: выполнить запрос списка напрямую
Если отборы пользователя не нужны или их можно перенести вручную, проще выполнить обычный запрос с тем же текстом, что и у списка. У объекта «Запрос» есть метод Выполнить().Выгрузить(), который сразу возвращает таблицу значений.
Запрос = Новый Запрос;
Запрос.Текст = Список.ТекстЗапроса;
// Переносим параметры списка
Для Каждого Параметр Из Список.Параметры.Элементы Цикл
Если Параметр.Использование Тогда
Запрос.УстановитьПараметр(Строка(Параметр.Параметр), Параметр.Значение);
КонецЕсли;
КонецЦикла;
ТаблицаРезультат = Запрос.Выполнить().Выгрузить();
Минус подхода: отборы, которые пользователь установил интерактивно, в текст запроса не попадут — они применяются платформой поверх запроса через СКД. Чтобы учесть их, придётся динамически дополнять текст запроса условиями либо вернуться к способу через компоновку данных.
Сравнение вариантов
Учитывает пользовательские отборы и сортировку. Подходит для списков на произвольном запросе. Код длиннее, требует аккуратности с параметрами.
Простой и быстрый код, но без интерактивных отборов. Подходит, когда состав данных известен заранее.
Даёт только загруженные в форму строки. Подходит для небольших списков и когда нужны именно видимые данные.
Способ 3: обход строк списка на форме
Когда нужны только те строки, которые реально загружены в таблицу формы (например, пользователь уже отфильтровал список и хочет обработать видимое), можно обойти элементы коллекции формы. Для динамического списка доступ к данным строк идёт через идентификаторы строк таблицы формы.
ТаблицаРезультат = Новый ТаблицаЗначений;
ТаблицаРезультат.Колонки.Добавить("Ссылка");
Для Каждого ИдентификаторСтроки Из Элементы.Список.ВыделенныеСтроки Цикл
ДанныеСтроки = Список.НайтиПоИдентификатору(ИдентификаторСтроки);
НоваяСтрока = ТаблицаРезультат.Добавить();
НоваяСтрока.Ссылка = ДанныеСтроки.Ссылка;
КонецЦикла;
Пример выше обрабатывает выделенные строки — частый сценарий для кнопок «Обработать выбранное». Для обхода всех загруженных строк используйте коллекцию данных списка, но помните: платформа подгружает записи порциями, и полного состава большого списка на клиенте может не быть.
Учёт параметров и отборов: частые детали
Динамический список почти всегда имеет параметры (период, организация, склад), которые задаются через Список.Параметры.УстановитьЗначениеПараметра(). При выгрузке через СКД или запрос эти параметры нужно перенести явно — иначе запрос либо упадёт с ошибкой «Параметр не задан», либо вернёт данные без ограничений.
Отдельная ситуация — отборы, заданные в свойствах динамического списка в конфигураторе (фиксированный отбор). Они хранятся в Список.Отбор и автоматически входят в исполняемые настройки, поэтому способ через СКД их учитывает без дополнительного кода.
- 1Определите, какой запрос лежит в основе списка: свойство ТекстЗапроса или основная таблица.
- 2Создайте схему компоновки данных программно и поместите запрос в набор данных.
- 3Получите настройки списка через ПолучитьИсполняемыеНастройкиКомпоновкиДанных() или КомпоновщикНастроек.Настройки.
- 4Перенесите значения параметров списка в настройки компоновки.
- 5Скомпонуйте макет, выполните процессор компоновки и выведите результат в таблицу значений.
- 6Проверьте: количество строк и итоги таблицы должны совпадать с данными списка при тех же отборах.
Проверка результата и типичные ошибки
После выгрузки сверьте результат с тем, что видит пользователь: количество строк в таблице значений должно соответствовать количеству записей списка при текущих отборах. Проще всего проверить на маленьком отборе — например, за один день или по одному контрагенту.
Если список построен не на произвольном запросе, а на основной таблице (свойство «Основная таблица» заполнено, а «Произвольный запрос» снят), то ТекстЗапроса будет пустым. В этом случае сформируйте запрос вручную вида ВЫБРАТЬ * ИЗ Документ.РеализацияТоваровУслуг и применяйте настройки компоновки к нему.
Как проверить результат
Совпадает с числом записей списка при тех же отборах
Строк больше или меньше — не перенесены отборы или параметры
В таблице есть все поля, нужные для дальнейшей обработки
Отсутствуют поля, не включённые в выборку запроса
Период, организация и другие параметры соответствуют установленным в списке
Данные за другой период или по другой организации
Альтернатива: выгрузка в табличный документ
Если конечная цель — печать или передача пользователю файла, таблица значений может быть лишним промежуточным звеном. Процессор вывода результата компоновки данных умеет выводить сразу в табличный документ (ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент), который затем сохраняется в Excel или PDF. Это короче и даёт форматированный результат.
Таблица значений оправдана, когда данные нужны для дальнейшей программной обработки: свёртки, сравнения, загрузки в другой объект, передачи через COM или веб-сервис.
Что важно запомнить
Динамический список — это представление, а не хранилище, поэтому выгрузка делается через повторное выполнение его запроса. Способ через СКД с исполняемыми настройками учитывает пользовательские отборы, прямой запрос проще, но без интерактивных отборов, а построчный обход годится только для небольших видимых данных. Всегда переносите параметры и проверяйте результат сверкой количества строк.
Частые вопросы
Можно ли выгрузить динамический список в таблицу значений одной строкой кода?
Нет, встроенного метода у динамического списка нет. Минимальный короткий вариант — выполнить запрос с текстом списка: Запрос.Текст = Список.ТекстЗапроса; ТЗ = Запрос.Выполнить().Выгрузить();, но он не учтёт интерактивные отборы пользователя.
Как выгрузить список с учётом отборов, которые поставил пользователь?
Используйте метод ПолучитьИсполняемыеНастройкиКомпоновкиДанных() динамического списка на клиенте, передайте эти настройки в компоновщик макета и выполните компоновку с выводом в таблицу значений. Только так гарантированно попадут все интерактивные отборы.
Что делать, если у списка пустой ТекстЗапроса?
Значит, список построен на основной таблице без произвольного запроса. Сформируйте запрос сами по шаблону «ВЫБРАТЬ ... ИЗ ИмяТаблицы», где имя таблицы возьмите из свойства ОсновнаяТаблица списка, и примените к нему настройки компоновки.
Почему выгруженная таблица не совпадает с тем, что видно в списке?
Чаще всего причины две: не перенесены значения параметров запроса или использованы настройки по умолчанию вместо исполняемых. Проверьте параметры через Список.Параметры и берите настройки методом ПолучитьИсполняемыеНастройкиКомпоновкиДанных().
Можно ли выгрузить только выделенные пользователем строки?
Да, обойдите коллекцию Элементы.Список.ВыделенныеСтроки, получите данные каждой строки через Список.НайтиПоИдентификатору() и добавьте нужные поля в таблицу значений. Это стандартный приём для команд «Обработать выбранные документы».
Есть ли ограничения по объёму при выгрузке?
Таблица значений целиком размещается в памяти, поэтому для очень больших выборок (сотни тысяч и более строк) разумнее обрабатывать результат запроса выборкой построчно или порциями, а не выгружать в таблицу значений полностью.