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