Как передать все документы из динамического списка с учетом отборов во внешнюю печатную форму

Программист 1С v8.3 (Управляемые формы) 1С:Управление нашей фирмой Управленческий учет
← На главную

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

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

Почему стандартная ВПФ печатает только выделенные строки?

Разберем архитектуру взаимодействия внешней обработки и платформы. Когда мы регистрируем ВПФ через функцию СведенияОВнешнейОбработке, мы указываем тип команды ДополнительныеОтчетыИОбработкиКлиентСервер.ТипКомандыВызовСерверногоМетода(). В этом случае БСП берет на себя задачу сбора ссылок. Она обращается к элементу формы Список, считывает свойство ВыделенныеСтроки и передает этот массив в параметр МассивОбъектовНазначения.

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

Способ №1: Программное получение данных через СКД списка (наиболее надежный)

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

Для реализации этого метода нам потребуется изменить тип команды на ВызовКлиентскогоМетода или ЗаполнениеФормы, чтобы иметь доступ к экранной форме. Рассмотрим пример кода, который можно использовать в модуле обработки для извлечения данных:


// В модуле формы или клиентском методе обработки
&НаКлиенте
Процедура ВыполнитьКоманду(ИдентификаторКоманды, ОбъектыНазначения) Экспорт
    
    // Получаем форму списка, из которой вызвана команда
    ФормаСписка = ВладелецФормы; 
    Если ТипЗнч(ФормаСписка) <> Тип("УправляемаяФорма") Тогда
        Возврат;
    КонецЕсли;

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

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

Способ №2: Использование внешнего отчета вместо печатной формы

Как справедливо заметили участники обсуждения, Реестр документов по своей сути является отчетом, а не печатной формой конкретного объекта. В системе 1С:УНФ 3.0 архитектурно правильнее реализовать такую задачу через "Дополнительный отчет".

Выясним преимущества этого подхода:

  1. Гибкость настроек: Пользователь может сам менять группировки (например, реестр в разрезе контрагентов или дат).
  2. Итоговые показатели: В отчете на СКД гораздо проще реализовать расчет итогов по суммам заказов, чего часто не хватает в обычном "выводе списка".
  3. Сохранение вариантов: Пользователь может сохранить несколько вариантов реестра (например, "Только оплаченные" или "Заказы по складу А").

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

Способ №3: Использование команды "Вывести список"

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

Рассмотрим алгоритм действий пользователя:

  1. Установить необходимые фильтры в списке заказов.
  2. Нажать Еще – Вывести список.
  3. В появившемся окне выбрать колонки, которые должны войти в реестр.
  4. Нажать ОК. Система сформирует табличный документ.

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

Техническая реализация получения данных из списка через расширение

Если бизнес-процесс требует, чтобы кнопка находилась именно в подменю "Печать" и работала "магически" по всем строкам, проанализируем вариант с использованием расширения конфигурации. Мы можем перехватить команду печати и программно подменить МассивОбъектовНазначения.

Для этого в расширении создается обработчик, который считывает данные из Элементы.Список.Отбор. Однако помните о безопасном режиме: внешние обработки часто запускаются с ограничениями. Чтобы код работал корректно, убедитесь, что в параметрах регистрации указано ПараметрыРегистрации.БезопасныйРежим = Ложь; (если политика безопасности компании это позволяет), иначе доступ к некоторым свойствам формы будет ограничен.

Посмотрим на пример формирования структуры настроек для передачи в фоновое задание или на сервер:


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

Рекомендации и выводы

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

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

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

← На главную