Как реализовать интерактивный выбор параметров или открытие формы перед печатью внешней печатной формы в 1С?

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

При разработке внешних печатных форм (ВПФ) на базе Библиотеки стандартных подсистем (БСП) часто возникает задача интерактивного взаимодействия с пользователем перед формированием табличного документа. Например, если в документе фигурирует несколько контрагентов, требуется предварительно запросить у пользователя, по какому именно контрагенту формировать печатную форму, а если контрагент один — печатать документ сразу без лишних вопросов.

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

Причины ошибки «Метод объекта не обнаружен (Печать)»

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

  1. У внешней обработки обязательно должна быть назначена основная форма. Если форма не создана или не назначена в свойствах объекта как основная, БСП не сможет инициализировать клиентский контекст.
  2. Процедура с сигнатурой Печать(ИдентификаторКоманды, ОбъектыНазначения) с директивой &НаКлиенте и ключевым словом Экспорт должна располагаться именно в модуле этой основной формы, а не в модуле объекта обработки.

Если процедура Печать объявлена в модуле объекта или забыта директива Экспорт на форме, платформа возвращает исключение об отсутствии метода при нажатии на кнопку печати в документе.

Реализация через «ВызовКлиентскогоМетода» с асинхронным выбором

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

Шаг 1. Регистрация команды в модуле объекта

В процедуре СведенияОВнешнейОбработке() в модуле объекта укажем для команды использование клиентского метода:


Функция СведенияОВнешнейОбработке() Экспорт

    ПараметрыРегистрации = Новый Структура;
    ПараметрыРегистрации.Вставить("Вид", "ПечатнаяФорма");
    ПараметрыРегистрации.Вставить("Версия", "1.0");
    ПараметрыРегистрации.Вставить("Назначение", ПолучитьНазначение());
    ПараметрыРегистрации.Вставить("Наименование", "Печать с выбором контрагента");
    ПараметрыРегистрации.Вставить("БезопасныйРежим", Истина);
    ПараметрыРегистрации.Вставить("Информация", "Внешняя печатная форма с выбором контрагента");

    ТаблицаКоманд = ПолучитьТаблицуКоманд();
    
    СтрокаКоманды = ТаблицаКоманд.Добавить();
    СтрокаКоманды.Идентификатор = "ПечатьСВыбором";
    СтрокаКоманды.Представление = "Печать с выбором контрагента";
    СтрокаКоманды.Использование = "ВызовКлиентскогоМетода";
    СтрокаКоманды.ПоказыватьОповещение = Истина;
    
    ПараметрыРегистрации.Вставить("Команды", ТаблицаКоманд);

    Возврат ПараметрыРегистрации;

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

Шаг 2. Создание формы и обработчика на клиенте

Создадим форму обработки и назначим её основной. В модуле созданной формы разместим клиентскую точку входа и вспомогательные процедуры. Обратите внимание, что в современных конфигурациях действует запрет на использование модальности (свойство конфигурации РежимИспользованияМодальности = НеИспользовать), поэтому интерактивный выбор организуется через асинхронные оповещения, например через метод ПоказатьВыборИзСписка():


&НаКлиенте
Процедура Печать(ИдентификаторКоманды, ОбъектыНазначения) Экспорт

    // Проверяем возможность печати для выбранных объектов
    Если ОбъектыНазначения.Количество() = 0 Тогда
        Возврат;
    КонецЕсли;

    // Для простоты рассмотрим сценарий печати одного выбранного документа
    СсылкаНаДокумент = ОбъектыНазначения[0];
    
    // Получаем список контрагентов документа на сервере
    СписокКонтрагентов = ПолучитьКонтрагентовДокумента(СсылкаНаДокумент);

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

КонецПроцедуры

&НаКлиенте
Процедура ПослеВыбораКонтрагента(ВыбранныйЭлемент, ДополнительныеПараметры) Экспорт

    Если ВыбранныйЭлемент = Неопределено Тогда
        Возврат; // Пользователь отказался от выбора
    КонецЕсли;

    СформироватьИПоказатьПечатнуюФорму(
        ДополнительныеПараметры.ИдентификаторКоманды,
        ДополнительныеПараметры.СсылкаНаДокумент,
        ВыбранныйЭлемент.Значение
    );

КонецПроцедуры

Шаг 3. Формирование и вывод печатной формы

После получения выбранного контрагента формируем табличный документ и выводим его через механизмы БСП подсистемы печати:


&НаКлиенте
Процедура СформироватьИПоказатьПечатнуюФорму(ИдентификаторКоманды, СсылкаНаДокумент, ВыбранныйКонтрагент)

    ПараметрыФормирования = Новый Структура;
    ПараметрыФормирования.Вставить("Документ", СсылкаНаДокумент);
    ПараметрыФормирования.Вставить("Контрагент", ВыбранныйКонтрагент);

    // Сформируем табличный документ на сервере
    ТабличныйДокумент = СформироватьПечатнуюФормуНаСервере(ПараметрыФормирования);

    // Вывод на печать через стандартную коллекцию БСП
    КоллекцияПечатныхФорм = УправлениеПечатьюКлиент.НоваяКоллекцияПечатныхФорм("ПечатнаяФорма");
    КоллекцияПечатныхФорм[0].ТабличныйДокумент = ТабличныйДокумент;
    КоллекцияПечатныхФорм[0].СинонимМакета = "Печатная форма";

    ОбъектыПечати = Новый СписокЗначений;
    ОбъектыПечати.Добавить(СсылкаНаДокумент);

    ПараметрыВывода = УправлениеПечатьюКлиент.НовыеПараметрыВыводаПечатныхФорм();

    УправлениеПечатьюКлиент.ПечатьДокументов(КоллекцияПечатныхФорм, ОбъектыПечати, ЭтотОбъект, ПараметрыВывода);

КонецПроцедуры

Альтернативный вариант: команда «ОткрытиеФормы»

Нередко разработчики избегают использования варианта ОткрытиеФормы, полагая, что форма обработки откроется пустой и потеряет ссылку на исходный документ. Это заблуждение. При выборе типа команды ОткрытиеФормы БСП автоматически помещает в Параметры открываемой формы следующие данные:

  1. Параметры.ОбъектыНазначения — массив ссылок на объекты (документы), из контекста которых была вызвана команда.
  2. Параметры.ИдентификаторКоманды — строка с именем команды.
  3. Параметры.ДополнительнаяОбработкаСсылка — ссылка на справочник дополнительных обработок.

В процедуре ПриСозданииНаСервере модуля открываемой формы эти параметры можно прочитать напрямую:


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)

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

КонецПроцедуры

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

Особенности групповой печати

Важно учитывать, что параметр ОбъектыНазначения всегда передается в виде массива, даже если команда печати запущена из карточки одного открытого документа. Пользователь может выделить несколько документов в динамическом списке и нажать команду печати.

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

  1. Ограничение для группового выделения: перед началом выбора проверить условие Если ОбъектыНазначения.Количество() > 1 и выдать пользователю предупреждение о том, что данная печатная форма поддерживает формирование только по одному документу за раз.
  2. Единый предварительный фильтр: собрать общий список возможных значений и запросить выбор один раз перед циклом формирования всех документов.
← На главную