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

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

В процессе разработки на платформе 1С:Предприятие 8.3 часто возникает задача реализации печати документов или справочников непосредственно из формы списка. Стандартная подсистема печати БСП (Библиотека стандартных подсистем) по умолчанию ориентирована на работу с выделенными объектами (массив ссылок, передаваемый через параметры формы). Однако пользователи часто запрашивают возможность «напечатать всё, что я сейчас вижу в списке», не прибегая к ручному выделению всех строк через Ctrl+A.

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

Разбор основной проблемы

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

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

Способ 1: Использование исполняемых настроек компоновки данных

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

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

  1. Получение схемы и настроек: Нам нужно извлечь базовую схему запроса динамического списка и объединить её с пользовательскими отборами.
  2. Корректировка состава полей: Поскольку для печати нам нужны только ссылки на объекты, мы заменим выбранные поля в настройках, чтобы запрос работал быстрее и не тянул лишние данные.
  3. Выполнение запроса через процессор компоновки: Результат будет выведен в таблицу значений, из которой мы сформируем массив для подсистемы печати.

Ниже приведен пример кода, реализующий эту логику:


Процедура ПолучитьСсылкиВсехЭлементовСписка(Элементы, ИмяСписка)
    
    // 1. Получаем динамический список из реквизитов формы
    Список = ЭтаФорма[ИмяСписка];
    
    // 2. Получаем исполняемые настройки (с учетом всех отборов и поиска)
    НастройкиДС = Элементы[ИмяСписка].ПолучитьИсполняемыеНастройкиКомпоновкиДанных();
    
    // 3. Получаем схему компоновки данных самого списка
    Схема = Элементы[ИмяСписка].ПолучитьИсполняемуюСхемуКомпоновкиДанных();
    
    // Очищаем выбранные поля, чтобы получить только Ссылку
    НастройкиДС.Выбор.Элементы.Очистить();
    ВыбранноеПоле = НастройкиДС.Выбор.Элементы.Добавить(Тип("ВыбранноеПолеКомпоновкиДанных"));
    ВыбранноеПоле.Поле = Новый ПолеКомпоновкиДанных("Ссылка");
    ВыбранноеПоле.Использование = Истина;

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

Способ 2: Ручной перенос отборов (через вспомогательную схему)

Иногда требуется более тонкая настройка, например, если запрос динамического списка слишком сложен или содержит специфические объединения, которые могут замедлять работу при полной выборке. В этом случае мы можем создать в метаданных отдельную «Схему компоновки данных выбора ссылок», которая содержит только простейший запрос к основной таблице, и программно перенести в неё отборы из списка.

Рассмотрим пример функции для копирования элементов отбора, которая умеет работать с группами (И, ИЛИ, НЕ):


Процедура ПеренестиОтбор(ОтборПриемник, ОтборИсточник) Экспорт
    Для Каждого ЭлементИсточник Из ОтборИсточник.Элементы Цикл
        Если ТипЗнч(ЭлементИсточник) = Тип("ЭлементОтбораКомпоновкиДанных") Тогда
            // Проверяем использование и корректность левого значения
            Если ЭлементИсточник.Использование Тогда
                НовыйЭлемент = ОтборПриемник.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
                ЗаполнитьЗначенияСвойств(НовыйЭлемент, ЭлементИсточник);
            КонецЕсли;
        ИначеЕсли ТипЗнч(ЭлементИсточник) = Тип("ГруппаЭлементовОтбораКомпоновкиДанных") Тогда
            НоваяГруппа = ОтборПриемник.Элементы.Добавить(Тип("ГруппаЭлементовОтбораКомпоновкиДанных"));
            НоваяГруппа.ТипГруппы = ЭлементИсточник.ТипГруппы;
            НоваяГруппа.Использование = ЭлементИсточник.Использование;
            ПеренестиОтбор(НоваяГруппа, ЭлементИсточник);
        КонецЕсли;
    КонецЦикла;
КонецПроцедуры

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

Важные технические нюансы и ограничения

При реализации печати «всех элементов» крайне важно проанализировать возможные риски, связанные с производительностью и стабильностью системы.

  1. Объем данных: Если пользователь не установил фильтры и в списке находятся сотни тысяч документов, попытка выгрузить их ссылки в массив приведет к значительному потреблению оперативной памяти и может вызвать аварийное завершение сеанса. Рекомендуем перед выполнением основной выборки проверять количество записей. Если оно превышает разумный предел (например, 1000 шт.), стоит вывести предупреждение: "В списке слишком много элементов. Пожалуйста, уточните отбор перед печатью".
  2. Длительные операции: Процесс формирования макета компоновки и обхода результата может занять значительное время. Согласно стандартам разработки 1С, такие операции следует выполнять в фоновом задании с использованием модуля ДлительныеОперации. Это позволит интерфейсу оставаться отзывчивым, а пользователю видеть индикатор прогресса.
  3. Полнотекстовый поиск: Как уже упоминалось, метод ПолучитьИсполняемыеНастройкиКомпоновкиДанных() в современных версиях платформы 8.3 (начиная с 8.3.10+) корректно учитывает строку поиска. Если ваша конфигурация работает на более старых релизах, результаты поиска могут быть проигнорированы, и в печать попадут лишние документы.
  4. Интеграция с БСП: При использовании БСП в процедуре ДобавитьКомандыПечати вы можете указать параметр ДополнительныеПараметрыКоманды. Туда можно передать признак "ПечатьВсегоСписка". В серверном менеджере печати, если этот признак установлен, вызовите описанную выше логику получения ссылок вместо использования стандартного параметра ОбъектыПечати.

Рекомендация по оптимизации через Временные Таблицы

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

Выясним причину, почему разработчики часто выбирают Ctrl+A. Это самый простой путь, не требующий написания кода. Но для создания качественного и дружелюбного интерфейса, программное получение отборов является признаком высокого профессионализма разработчика и заботы о конечном пользователе.

← На главную