При разработке конфигураций на базе Библиотеки стандартных подсистем (БСП) мы часто сталкиваемся с необходимостью выводить разные печатные формы для одного и того же документа. Разберем типичную ситуацию: команды печати добавляются штатно через процедуру модуля менеджера ДобавитьКомандыПечати. При этом нам нужно реализовать отображение разных печатных форм в зависимости от реквизита документа. Например, если реквизит ВидДокумента равен значению «Основной» — отображаем одни формы, а если «Дополнительный» — другие. Для проверки и отладки вызова всех зарегистрированных команд документа можно использовать обработку для печати любых зарегистрированных в БСП печатных форм.
Рассмотрим, как правильно решить эту задачу, проанализируем различные подходы, применимые как для старых версий БСП (например, 2.2), так и для современных (2.4 и выше).
Первый и, зачастую, самый лаконичный с точки зрения интерфейса способ — скрыть эту логику от пользователя. Пользователь всегда видит только одну команду, например, «Распечатать бланк». Однако алгоритм внутри модуля менеджера, анализируя реквизит объекта, сам принимает решение о том, какой макет нужно сформировать и вывести на экран.
Рассмотрим этот подход. В процедуре добавления команд мы создаем стандартную кнопку:
Процедура ДобавитьКомандыПечати(КомандыПечати) Экспорт
КомандаПечати = КомандыПечати.Добавить();
КомандаПечати.МенеджерПечати = "Документ._ДемоСчетНаОплатуПокупателю";
КомандаПечати.Идентификатор = "СчетЗаказУниверсальный";
КомандаПечати.Представление = НСтр("ru = 'Счет на оплату'");
КомандаПечати.ПроверкаПроведенияПередПечатью = Истина;
КонецПроцедуры
А уже непосредственно в процедуре Печать мы разделяем алгоритмы формирования табличного документа:
Процедура Печать(МассивОбъектов, ПараметрыПечати, КоллекцияПечатныхФорм, ОбъектыПечати, ПараметрыВывода) Экспорт
Если УправлениеПечатью.НужноПечататьМакет(КоллекцияПечатныхФорм, "СчетЗаказУниверсальный") Тогда
// Перебираем объекты и формируем разные макеты в зависимости от реквизита
Для Каждого ТекущийДокумент Из МассивОбъектов Цикл
Если ТекущийДокумент.ВидДокумента = Перечисления.ВидыДокументов.Основной Тогда
// Выводим один макет
Иначе
// Выводим другой макет
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецПроцедуры
Проанализируем ситуацию, если мы хотим оставить в меню «Печать» несколько разных кнопок (отдельная кнопка на каждый макет), но в версии БСП 2.2 еще нет механизмов скрытия кнопок по условию. В типовых конфигурациях для таких случаев применяется простая проверка правдивости реквизита при самом нажатии на кнопку печати.
Если реквизит не подходит для выбранной формы, мы просто прерываем выполнение и выводим пользователю понятное сообщение: «Данная печатная форма не предназначена для этого типа документа». Команды в меню при этом не фильтруются.
Посмотрим на пример реализации внутри обработчика печати:
Если МассивОбъектов[0].ВидДокумента <> Перечисления.ВидыДокументов.Основной Тогда
ОбщегоНазначенияКлиентСервер.СообщитьПользователю("Выбранный документ не может быть распечатан по данной форме. Проверьте вид документа.");
Возврат; // Прерываем формирование макета
КонецЕсли;
Этот способ автор обсуждения признал наиболее подходящим, если возможные значения реквизита ограничены (всего два-три варианта), и нет технической возможности динамически перестраивать интерфейс.
В более свежих редакциях БСП разработчики добавили штатный и элегантный механизм управления видимостью. Теперь у добавляемой команды появилась колонка УсловияВидимости. Мы можем задать простые условия на равенство с помощью функции УправлениеПечатью.ДобавитьУсловиеВидимостиКоманды. Для быстрого поиска синтаксиса и параметров процедур библиотеки пригодится конфигурация-справочник по методам БСП.
Разберем по шагам, как это работает. При добавлении команды мы явно указываем системе, при каких значениях конкретных полей документа кнопка должна быть видна:
Процедура ДобавитьКомандыПечати(КомандыПечати) Экспорт
КомандаПечати = КомандыПечати.Добавить();
КомандаПечати.МенеджерПечати = "Документ._ДемоСчетНаОплатуПокупателю";
КомандаПечати.Идентификатор = "СчетЗаказОсновной";
КомандаПечати.Представление = НСтр("ru = 'Счет на оплату (Основной)'");
// Добавляем условие: реквизит "ВидДокумента" должен быть равен значению "Основной"
УправлениеПечатью.ДобавитьУсловиеВидимостиКоманды(КомандаПечати, "ВидДокумента", ВидСравненияКомпоновкиДанных.Равно, Перечисления.ВидыДокументов.Основной);
КонецПроцедуры
Важное ограничение: реквизит, по которому настраивается условие видимости, обязательно должен быть в составе данных формы и списка с установленным флагом «Использовать всегда». Иначе платформа не сможет проверить условие на клиенте без лишних обращений к серверу при отрисовке меню.
Выясним причину частой ошибки: что произойдет, если пользователь открыл новый документ, где реквизит ВидДокумента еще не заполнен, а затем заполнил его в процессе работы с формой? Изначально подменю печати строится при открытии формы. Если мы хотим, чтобы состав кнопок изменился мгновенно после выбора реквизита, нам нужно принудительно обновить список команд.
В БСП предусмотрен механизм принудительного обновления. Вызовем метод УправлениеПечатьюКлиент.ОбновитьКомандыПечати в обработчике события изменения реквизита на клиенте:
&НаКлиенте
Процедура ВидДокументаПриИзменении(Элемент)
// Инициируем повторную проверку условий и перестроение подменю печати
УправлениеПечатьюКлиент.ОбновитьКомандыПечати(ЭтаФорма);
КонецПроцедуры
Без этого вызова пользователь увидит новую (или исчезнувшую старую) команду только после записи и переоткрытия формы.
Если ваша версия БСП не поддерживает УсловияВидимости, но вы все же хотите скрыть недопустимые формы, можно добавить команды печати для всех возможных вариантов, а затем программно находить их в дереве элементов формы и скрывать.
Проанализируем этот подход. Команды печати при создании формы обычно помещаются подсистемой в группу (подменю) с именем ПодменюПечать. Программный перебор элементов этой группы, например, в процедуре ПриЧтенииНаСервере или ПриСозданииНаСервере, позволяет найти нужную кнопку по имени. Имя кнопки обычно формируется динамически (зачастую как ИмяФормы + ИдентификаторКоманды). Найдя нужный элемент, мы просто устанавливаем ему свойство Видимость = Ложь.
Однако этот способ требует аккуратности, так как алгоритмы формирования имен элементов в разных версиях БСП могут немного отличаться, и такой код может оказаться хрупким при обновлении библиотеки.
Рассмотрим дополнительные инструменты, которые предоставляет платформа и БСП для регулирования доступа к печатным формам:
ФункциональныеОпции. Если логика отображения связана с глобальными настройками базы, укажите массив имен функциональных опций. Платформа сама скроет команду, если опция отключена.КомандаПечати.СписокФорм = "ИмяВашейФормы";. Однако помните, что это жесткий фильтр. Он не позволяет менять видимость динамически внутри одной и той же формы в зависимости от данных. Этот параметр полезен, только если для разных видов документа у вас в конфигурации физически созданы разные формы (например, ФормаДокументаОсновная и ФормаДокументаДополнительная).ПроверкаПравДоступа. Это позволит скрыть команду (например, печать документов с конфиденциальными финансовыми показателями) для пользователей, у которых нет соответствующих прав, даже если по условиям реквизитов форма должна быть доступна.Подводя итог, можно сделать вывод: для старых конфигураций надежнее всего реализовать проверку реквизита прямо в момент печати с выдачей предупреждающего сообщения. А при разработке на современных версиях БСП всегда используйте встроенный метод добавления условий видимости с обязательным клиентским обновлением формы при изменении ключевых полей.