При разработке внешних печатных форм, отчетов и обработок для конфигураций на базе БСП (Библиотека Стандартных Подсистем) мы часто сталкиваемся с необходимостью управлять видимостью команд. Чтобы сэкономить время на старте, многие используют классический корректный пример внешней печатной формы на БСП 3.1.10. Например, нам нужно, чтобы кнопка печати появлялась только если документ проведен или если заполнен определенный реквизит. Однако, пытаясь использовать стандартный параметр УсловияВидимости в функции СведенияОВнешнейОбработке, мы обнаруживаем, что он игнорируется или вовсе отсутствует в структуре команд.
В этой статье мы подробно разберем, почему так происходит, рассмотрим архитектурные причины этого ограничения и, самое главное, научимся обходить его, используя современные механизмы платформы 1С.
Давайте проанализируем ситуацию. Когда мы создаем внешнюю обработку, мы описываем её команды в экспортной функции. Обычно это выглядит так:
Функция СведенияОВнешнейОбработке() Экспорт
ПараметрыРегистрации = ДополнительныеОтчетыИОбработки.СведенияОВнешнейОбработке("2.2.2.1");
// ... заполнение свойств
Команда = ПараметрыРегистрации.Команды.Добавить();
Команда.Представление = "Моя печатная форма";
Команда.Идентификатор = "ПечатьЧегоТоТам";
Команда.Использование = ДополнительныеОтчетыИОбработкиКлиентСервер.ТипКомандыВызовСерверногоМетода();
// Мы ожидаем здесь увидеть что-то вроде:
// Команда.УсловияВидимости = ...
Возврат ПараметрыРегистрации;
КонецФункции
Однако, если мы посмотрим в отладчике или в код модуля ДополнительныеОтчетыИОбработки, мы увидим, что колонки для условий видимости в таблице команд просто нет. Это одни из тех нюансов регистрации и типичных ограничений БСП, разобраться в которых поможет подробный справочник по методам БСП с примерами использования.
Дело в способе хранения данных. Все зарегистрированные внешние обработки хранятся в справочнике ДополнительныеОтчетыИОбработки. Команды хранятся в табличной части этого справочника. В БСП параметр УсловияВидимости представляет собой сложный тип данных — обычно это массив структур, описывающий, какие реквизиты с какими значениями сравнивать.
Сохранить массив структур в плоскую табличную часть справочника без дополнительных ухищрений (например, сериализации в строку или ХранилищеЗначения) невозможно. Разработчики БСП приняли решение не усложнять структуру справочника ради этой функции для внешних файлов, оставив приоритет за простотой и универсальностью.
Наиболее правильным и современным подходом, который рекомендует фирма 1С, является использование расширений для изменения логики типовых конфигураций в пользу механизмов, позволяющих более гибко управлять интерфейсом. Для реализации этой задачи можно использовать готовое расширение для ограничения видимости команд печати и отчетов по условиям на реквизиты, которое позволяет скрывать пункты меню без написания лишнего кода — есть универсальное расширение для управления видимостью и режимом просмотра.
В расширениях мы имеем доступ к переопределяемым модулям подсистемы печати. Чтобы понять, как это работает «под капотом», рекомендую изучить материал про программное добавление команд в подсистеме «Печать» БСП 3.0.
Нам необходимо создать расширение и позаимствовать модуль УправлениеПечатьюПереопределяемый. В нем нас интересует процедура ПриДобавленииКомандПечати.
Давайте посмотрим на пример кода, который позволяет добавить команду печати с условием видимости:
&После("ПриДобавленииКомандПечати")
Процедура Расш_ПриДобавленииКомандПечати(КомандыПечати)
// Определяем условия видимости
// Кнопка будет видна, только если документ Проведен (ПометкаУдаления = Ложь и Проведен = Истина)
УсловияВидимости = Новый Массив;
УсловияВидимости.Добавить(УправлениеПечатью.УсловиеВидимостиПоРеквизиту("Проведен", Истина));
// Добавляем команду
УправлениеПечатью.ДобавитьКомандуПечати(
КомандыПечати,
"ВнешняяОбработка.МояОбработкаПечати", // Или идентификатор обработки в расширении
"ПФ_MXL_МояПечатнаяФорма",
"Моя печатная форма (только для проведенных)",
УсловияВидимости // Передаем наши условия
);
КонецПроцедуры
Преимущества этого метода:
Если по каким-то причинам использование расширений невозможно (например, политика компании или особенности базы во фреше) и вы обязаны использовать именно механизм ДополнительныеОтчетыИОбработки, мы можем сымитировать условия видимости.
Кнопка будет доступна всегда, но при нажатии мы будем проверять условия и выдавать пользователю сообщение, если печать невозможна. С точки зрения оптимизации пользовательского интерфейса (UX), в некоторых случаях бывает полезно использовать универсальное расширение для настройки доступности, видимости и режима только просмотр, которое позволяет гибко управлять элементами любой формы — для этого подойдет готовое расширение для настройки доступности и видимости форм.
Давайте реализуем это в модуле вашей внешней обработки в процедуре Печать:
Процедура Печать(МассивОбъектов, КоллекцияПечатныхФорм, ОбъектыПечати, ПараметрыВывода) Экспорт
Для Каждого СсылкаНаДокумент Из МассивОбъектов Цикл
// Проверяем условие
Если Не СсылкаНаДокумент.Проведен Тогда
// Формируем сообщение об ошибке
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = "Печать возможна только для проведенных документов! Документ: " + Строка(СсылкаНаДокумент);
Сообщение.УстановитьДанные(СсылкаНаДокумент);
Сообщение.Сообщить();
// Пропускаем этот документ или прерываем выполнение
Продолжить;
КонецЕсли;
// Если все ок, формируем печатную форму
УправлениеПечатью.ВывестиТабличныйДокументВКоллекцию(
КоллекцияПечатныхФорм,
"МояПФ",
"Моя печатная форма",
СформироватьТабличныйДокумент(СсылкаНаДокумент)
);
КонецЦикла;
КонецПроцедуры
Этот способ хуже с точки зрения пользовательского опыта (UX), так как пользователь видит кнопку, нажимает её и получает отказ. Однако он не требует никаких доработок конфигурации.
Если вы твердо намерены использовать именно справочник ДополнительныеОтчетыИОбработки и хотите полноценную видимость, придется доработать конфигурацию. Этот метод обсуждался участниками сообщества как рабочий вариант обхода ограничения. В ситуациях, когда интерфейс слишком ограничен настройками, разработчики часто используют инструменты, которые открывают видимость и доступность всех элементов на формах для отладки и анализа — для этого есть набор инструментов для отладки видимости и доступности элементов.
План действий:
ДополнительныеОтчетыИОбработки.Команды добавляем новый реквизит, например, УсловияВидимостиJSON (тип Строка неограниченной длины).ДополнительныеОтчетыИОбработки (или соответствующий модуль менеджера), где происходит чтение настроек внешней обработки.В коде СведенияОВнешнейОбработке самой внешней обработки мы должны будем сами сформировать структуру условий, при этом нам очень пригодится знание методов работы с JSON в 1С 8.3 для сериализации структур:
// В коде внешней обработки
Команда = ПараметрыРегистрации.Команды.Добавить();
// ... стандартные настройки ...
// Формируем условия видимости
МассивУсловий = Новый Массив;
СтруктураУсловия = Новый Структура;
СтруктураУсловия.Вставить("ВидСравнения", "Равно"); // Примерная структура, зависит от версии БСП
СтруктураУсловия.Вставить("ЛевоеЗначение", "Проведен");
СтруктураУсловия.Вставить("ПравоеЗначение", Истина);
МассивУсловий.Добавить(СтруктураУсловия);
// Сериализуем в JSON для нашей новой колонки
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();
ЗаписатьJSON(ЗаписьJSON, МассивУсловий);
Команда.УсловияВидимостиJSON = ЗаписьJSON.Закрыть();
Затем, в общем модуле конфигурации, который отвечает за построение команд на форме (обычно это происходит при создании на сервере или при чтении команд), нужно добавить логику: если поле УсловияВидимостиJSON заполнено, десериализовать его и передать в стандартный механизм БСП как параметр видимости.
Хотя отсутствие УсловияВидимости для внешних печатных форм кажется досадным упущением, оно имеет под собой технические основания. Мы выяснили, что наиболее "чистым" и поддерживаемым способом решения этой задачи сегодня является использование Расширений конфигурации.
Если вы стоите перед выбором технологии для внедрения новой печатной формы со сложной логикой отображения — выбирайте расширения. Если вам нужно быстрое решение для внешней обработки — используйте проверку внутри процедуры печати.