При разработке внешних печатных форм для конфигураций на базе Библиотеки стандартных подсистем (БСП), таких как «1С:Зарплата и управление персоналом 3.1», программисты часто сталкиваются с задачей передачи данных, которые не хранятся в реквизитах объекта (справочника или документа), а существуют только «здесь и сейчас» на открытой форме. Классический пример — печать графика работы сотрудника на выбранный пользователем год, который не является частью данных справочника ГрафикиРаботыСотрудников, а выбирается динамически в интерфейсе.
В этой статье мы подробно разберем, как пробросить такие «эфемерные» данные из формы элемента во внешнюю обработку печати, рассмотрим нюансы регистрации БСП и выясним, как управлять отображением кнопок печати.
Рассмотрим ситуацию: в справочнике «Графики работы» есть реквизит формы НомерТекущегоГода. Нам необходимо, чтобы внешняя печатная форма «знала», какой год выбран пользователем в данный момент, чтобы сформировать корректный календарь. Проблема в том, что стандартная процедура печати на сервере получает только ссылку на объект. Реквизиты формы на сервере в контексте печати недоступны. Следовательно, нам нужно перехватить управление на клиенте.
Для начала проанализируем структуру функции СведенияОВнешнейОбработке. Чтобы иметь доступ к форме, из которой вызывается команда, нам нужно зарегистрировать команду с типом Вызов клиентского метода или Заполнение формы. Рассмотрим пример кода для регистрации:
Функция СведенияОВнешнейОбработке() Экспорт
ПараметрыРегистрации = ДополнительныеОтчетыИОбработки.СведенияОВнешнейОбработке();
ПараметрыРегистрации.Вид = ДополнительныеОтчетыИОбработкиКлиентСервер.ВидОбработкиПечатнаяФорма();
ПараметрыРегистрации.Назначение.Добавить("Справочник.ГрафикиРаботыСотрудников");
ПараметрыРегистрации.Наименование = "График работы (внешний)";
ПараметрыРегистрации.Версия = "1.0";
ПараметрыРегистрации.БезопасныйРежим = Ложь; // Для доступа к файловой системе или сложным вызовам
НоваяКоманда = ПараметрыРегистрации.Команды.Добавить();
НоваяКоманда.Представление = "Печать графика на выбранный год";
НоваяКоманда.Идентификатор = "ПечатьСПараметром";
// Используем клиентский метод для доступа к данным формы
НоваяКоманда.Использование = ДополнительныеОтчетыИОбработкиКлиентСервер.ТипКомандыВызовКлиентскогоМетода();
НоваяКоманда.ПоказыватьОповещение = Истина;
Возврат ПараметрыРегистрации;
КонецФункции
Здесь важно обратить внимание на ТипКомандыВызовКлиентскогоМетода(). Это позволит нам выполнить код на стороне клиента в контексте формы справочника.
Теперь проанализируем, как получить доступ к данным формы. В модуле внешней обработки должна быть экспортная процедура ВыполнитьКоманду. Именно в неё БСП передает структуру ПараметрыВыполнения, содержащую свойство ЭтаФорма. В контексте вызова это будет форма справочника, из которой нажата кнопка.
Разберем пример реализации клиентской процедуры:
&НаКлиенте
Процедура ВыполнитьКоманду(ИдентификаторКоманды, ОбъектыНазначения, ПараметрыВыполнения) Экспорт
// Получаем доступ к форме, из которой вызвана печать
ФормаГрафика = ПараметрыВыполнения.ЭтаФорма;
// Извлекаем нужный нам параметр "НомерТекущегоГода"
// Если команда вызвана из формы элемента, этот реквизит там есть
ВыбранныйГод = 0;
Попытка
ВыбранныйГод = ФормаГрафика.НомерТекущегоГода;
Исключение
ВыбранныйГод = Год(ТекущаяДата()); // Фоллбэк, если реквизит не найден
КонецПопытки;
// Теперь мы можем вызвать процедуру печати, передав туда год
// Например, через открытие формы самой обработки или напрямую вызывая серверный метод
ПараметрыОтчета = Новый Структура;
ПараметрыОтчета.Вставить("Год", ВыбранныйГод);
ПараметрыОтчета.Вставить("ОбъектыНазначения", ОбъектыНазначения);
// Формируем печать (упрощенный пример вызова)
СформироватьПечатьНаСервере(ПараметрыОтчета);
КонецПроцедуры
Важный нюанс: Если вы используете свойство ВладелецФормы (как упоминалось в обсуждении форума), помните, что это актуально, когда внешняя обработка сама открывает свою форму. Если же команда зарегистрирована как вызов метода, то ПараметрыВыполнения.ЭтаФорма — это ваш прямой путь к данным исходного графика.
Часто возникает вопрос: как сделать так, чтобы кнопка печати была доступна только в форме элемента, но не в списке? БСП по умолчанию добавляет команду во все связанные формы. Выясним причину: механизм БСП сканирует тип объекта (Справочник.ГрафикиРаботыСотрудников) и выводит кнопку везде.
Рассмотрим два способа решения этой проблемы:
ВыполнитьКоманду проверяйте тип или имя формы. Если это форма списка, выводите предупреждение: "Печать возможна только из карточки графика".ОбъектыНазначения.Количество(). Если выбрано много элементов, возможно, стоит запретить групповую печать, если она требует ввода индивидуальных параметров для каждого.
&НаКлиенте
Процедура ВыполнитьКоманду(ИдентификаторКоманды, ОбъектыНазначения, ПараметрыВыполнения) Экспорт
ИмяФормы = ПараметрыВыполнения.ЭтаФорма.ИмяФормы;
Если Найти(ИмяФормы, "ФормаСписка") > 0 Тогда
ПоказатьПредупреждение(, "Пожалуйста, откройте график работы, чтобы выбрать год для печати.");
Возврат;
КонецЕсли;
// Продолжение логики печати...
КонецПроцедуры
Отладка внешних обработок в БСП — задача нетривиальная, так как код выполняется во временных копиях файлов. Рассмотрим эффективный метод отладки, предложенный участниками сообщества:
В модуле основной внешней обработки создайте «заглушку», которая перенаправляет вызов на файл обработки, лежащий на диске. Это позволит вам ставить точки останова в конфигураторе в файле .epf и видеть изменения без постоянного переподключения обработки в справочнике «Дополнительные отчеты и обработки».
Процедура ВыполнитьКоманду(ИдентификаторКоманды, ОбъектыНазначения, ПараметрыВыполнения) Экспорт
// Путь к файлу для разработки
ПутьКФайлу = "C:\Dev\MyExternalPrintForm.epf";
ОбработкаДебаг = ВнешниеОбработки.Создать(ПутьКФайлу, Ложь);
ОбработкаДебаг.ВыполнитьКоманду(ИдентификаторКоманды, ОбъектыНазначения, ПараметрыВыполнения);
КонецПроцедуры
Мы проанализировали ситуацию и выяснили, что для передачи данных из формы 1С во внешнюю печатную форму наиболее надежным способом является использование типа команды Вызов клиентского метода. Это дает полный доступ к контексту ЭтаФорма, позволяя считывать значения любых реквизитов и элементов управления, включая динамически меняющийся НомерТекущегоГода в ЗУП.
Использование Безопасного режима (БезопасныйРежим = Истина) рекомендуется для финальных версий продукта, однако на этапе разработки его часто отключают для упрощения отладки и доступа к внешним ресурсам. Помните о необходимости проверки типа формы, чтобы обеспечить корректный пользовательский опыт и избежать ошибок выполнения в формах списка.