Как разместить внешние печатные формы в отдельное подменю кнопки «Печать»?

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

При работе с современными конфигурациями на базе Библиотеки стандартных подсистем (БСП) версии 3.0 и выше, разработчики часто сталкиваются с ограничением: все внешние печатные формы (ВПФ) по умолчанию попадают либо в общий список кнопки «Печать» (есть инструмент управления печатными формами в пользовательском режиме), либо в подменю «Дополнительные печатные формы». Рассмотрим ситуацию, когда бизнес-логика требует более тонкой настройки интерфейса — например, размещение определенных внешних форм в созданное нами подменю «Факсимиле» или «Договоры контрагентов».

Почему стандартный подход через «СведенияОВнешнейОбработке» не работает

Проанализируем типичную ошибку начинающих разработчиков. Попытка добавить в таблицу команд поле МестоРазмещения или ИмяГруппы непосредственно в модуле внешней обработки приводит к ошибке: «Поле объекта не обнаружено». Это происходит потому, что структура таблицы команд жестко регламентирована программным интерфейсом БСП. Выясним причину: подсистема «Дополнительные отчеты и обработки» считывает только определенный набор колонок (Представление, Идентификатор, Использование и т.д.). Любые попытки расширить эту таблицу «изнутри» самой обработки игнорируются ядром системы.

Посмотрим на стандартный код формирования таблицы команд, который удобно редактировать, используя плагин для VS Code (удобнее через инструментарий разработчика и плагин VS Code), и который обычно используется во внешних обработках:


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

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

Шаг 1. Создание группы команд в модуле менеджера объекта

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


&ИзменениеИКонтроль("ПриОпределенииКомандПечати")
Процедура Расш1_ПриОпределенииКомандПечати(КомандыПечати, ГруппыКомандПечати)
    // Добавляем новую группу (подменю)
    НоваяГруппа = ГруппыКомандПечати.Добавить();
    НоваяГруппа.Имя = "ПодменюФаксимиле";
    НоваяГруппа.Представление = НСтр("ru = 'Печать с факсимиле'");
    НоваяГруппа.Порядок = 10; // Определяем место группы в общем списке
КонецПроцедуры

Шаг 2. Программное перемещение команды в расширении

Теперь самое важное: нам нужно заставить БСП перекинуть команду внешней обработки в созданную группу ПодменюФаксимиле. Поскольку внешняя обработка регистрируется динамически, нам нужно применить программное изменение форм и вмешаться в процесс построения команд печати на форме. Для этого идеально подходит общий модуль УправлениеПечатьюПереопределяемый.

Рассмотрим алгоритм действий в расширении. Нам необходимо перехватить процедуру ПередВыводомКомандПечати. Именно здесь система уже собрала все команды (и встроенные, и внешние) в одну коллекцию, и мы можем ими манипулировать.


&После("ПередВыводомКомандПечати")
Процедура Расш1_ПередВыводомКомандПечати(КомандыПечати, ПараметрыВывода)
    
    Для Каждого СтрокаКоманды Из КомандыПечати Цикл
        
        // Внешние печатные формы в БСП имеют специфический идентификатор.
        // Обычно он содержит GUID или имя обработки.
        // Проанализируем идентификатор, чтобы найти нашу форму.
        Если Найти(СтрокаКоманды.Идентификатор, "ДоговорТест") > 0 Тогда
            // Перенаправляем команду в нашу группу
            СтрокаКоманды.ИмяГруппы = "ПодменюФаксимиле";
        КонецЕсли;
        
    КонецЦикла;
    
КонецПроцедуры

Важный момент: при поиске команды по идентификатору учитывайте, что БСП добавляет префиксы к именам команд внешних форм (например, ДополнительнаяПечатнаяФорма_...). Проверьте точное имя идентификатора в отладчике, остановившись в указанной процедуре.

Шаг 3. Настройка внешней печатной формы

Чтобы наша логика в расширении работала стабильно, во внешней обработке в функции СведенияОВнешнейОбработке рекомендуется задавать уникальный и понятный Идентификатор. Это упростит его поиск в коллекции команд. Рассмотрим пример заполнения команды:


Процедура ДобавитьКоманду(ТаблицаКоманд, Представление, Идентификатор, Использование, ПоказыватьОповещение = Ложь, Модификатор = "")
    НоваяКоманда = ТаблицаКоманд.Добавить();
    НоваяКоманда.Представление = Представление;
    НоваяКоманда.Идентификатор = Идентификатор; // Именно этот ID мы ловим в расширении
    НоваяКоманда.Использование = Использование;
    НоваяКоманда.ПоказыватьОповещение = ПоказыватьОповещение;
    НоваяКоманда.Модификатор = Модификатор;
КонецПроцедуры

Альтернативный вариант: использование поля «Модификатор»

Проанализируем еще одну возможность, которую предоставляет БСП. Поле Модификатор часто используется для передачи дополнительных параметров печати. В некоторых кастомизированных конфигурациях (или при доработке общего модуля печати) можно реализовать логику «автораспределения».

Например, в СведенияОВнешнейОбработке мы можем указать: Модификатор = "Группа:ПодменюФаксимиле". Тогда в расширении общего модуля нам не придется зашивать жесткие идентификаторы обработок. Мы сможем написать универсальный код, который считывает значение из Модификатор и подставляет его в ИмяГруппы. Это сделает систему более гибкой: для добавления новой формы в подменю достаточно будет изменить код только в самой внешней обработке.

Пример универсального кода в расширении:


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

Подведем итоги

Мы выяснили, что напрямую через параметры регистрации внешней обработки (БСП 3.1) изменить подменю нельзя. Однако, используя расширение, мы получаем полный контроль над интерфейсом.

Основные правила реализации:

  1. Создаем или используем существующую ГруппуКомандПечати в модуле менеджера объекта.
  2. Регистрируем внешнюю форму со стандартными параметрами.
  3. Через расширение общего модуля УправлениеПечатьюПереопределяемый перехватываем момент формирования списка команд и программно меняем свойство ИмяГруппы для нашей команды.
  4. Для удобства и универсальности используем поле Модификатор для передачи имени целевой группы.

Такой подход позволяет сохранить типовую конфигурацию на поддержке и при этом обеспечить пользователям удобный, структурированный интерфейс для работы с дополнительными печатными формами. Для этой задачи есть комплект внешних печатных форм для УНФ 3.0.

← На главную