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

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

В практике разработки на платформе 1С:Предприятие 8.3 часто возникает задача: получить данные, которые пользователь видит в форме списка, для их дальнейшей обработки или формирования печатной формы. Сложность заключается в том, что ДинамическийСписок не является коллекцией данных в памяти сервера (как, например, ТаблицаЗначений). Это объект, который лишь предоставляет механизм отображения данных из базы. В этой статье мы подробно разберем, как "вытащить" данные из списка, сохранив при этом все настройки, которые наложил пользователь: отборы, сортировки и группировки.

Проблема прямого обхода динамического списка

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

Основной метод: Использование схемы компоновки данных

Начиная с версии платформы 8.3.6, у динамического списка появились мощные методы, позволяющие получить его внутреннюю схему и текущие настройки. Проанализируем самый эффективный алгоритм решения этой задачи на стороне сервера.

Для реализации нам потребуется выполнить следующие шаги:

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

Рассмотрим пример кода, который реализует этот алгоритм:


&НаСервере
Функция ПолучитьТаблицуИзСписка()

    // 1. Извлекаем схему и настройки из элемента формы "Список"
    Схема = Элементы.Список.ПолучитьИсполняемуюСхемуКомпоновкиДанных();
    Настройки = Элементы.Список.ПолучитьИсполняемыеНастройкиКомпоновкиДанных();

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

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

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

    Возврат МояТаблицаЗначений;

КонецФункции

Разбор ключевых объектов и методов

Разберем подробнее, что происходит в данном фрагменте кода, чтобы понимать механику процесса:

Особенности работы в конфигурации ЗУП (Зарплата и Управление Персоналом)

Часто задача усложняется спецификой прикладного решения. Рассмотрим ситуацию из практики: пользователю в ЗУП нужно вывести в таблицу "Полное наименование подразделения" со всей иерархией. В самом динамическом списке может отображаться только краткое наименование.

Проанализируем, как можно дополнить полученную таблицу значений. После того как мы получили МояТаблицаЗначений, мы можем программно обработать её в цикле, чтобы добавить недостающие данные:


Для Каждого СтрокаТЗ Из МояТаблицаЗначений Цикл
    // Используем функции типовых общих модулей ЗУП для получения представления
    СтрокаТЗ.ПодразделениеПолное = ЗарплатаКадрыКлиентСервер.ПолучитьПредставлениеПодразделенияДляПечати(СтрокаТЗ.Подразделение);
КонецЦикла;

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

Альтернативный подход: Выгрузка выделенных строк

Выясним причину, почему иногда метод со схемой может быть избыточным. Если пользователю не нужен весь отфильтрованный список, а только конкретные строки, которые он выделил мышкой (Shift/Ctrl + клик), алгоритм будет иным. Мы используем свойство элемента формы ВыделенныеСтроки.

Рассмотрим пример реализации:


&НаСервере
Функция ПолучитьТаблицуВыделенныхСтрок()

    ВыделенныеСтроки = Элементы.Список.ВыделенныеСтроки;
    
    // Если список ссылочный, формируем запрос по массиву ссылок
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ
        |   Т.Ссылка,
        |   Т.Наименование,
        |   Т.Код
        |ИЗ
        |   Справочник.Сотрудники КАК Т
        |ГДЕ
        |   Т.Ссылка В(&МассивСсылок)";
    
    Запрос.УстановитьПараметр("МассивСсылок", ВыделенныеСтроки);
    
    Возврат Запрос.Выполнить().Выгрузить();

КонецФункции

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

Типичные ошибки при реализации

Проанализируем ситуации, в которых код может работать некорректно:

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

← На главную