Сразу оговорюсь, что статья начального уровня и далее последует “изобретение велосипеда”, который не подойдет для типовых конфигураций.
Варианты решения задачи:
- реализовать механизм работы с внешними печатными формами самостоятельно;
- включить в собственную разработку некоторые подсистемы конфигурации «Библиотека стандартных подсистем».
1) Попробуем реализовать работу с внешними печатными формами самостоятельно
Введем ограничения:
- — поддерживаем только печатные формы;
- — автоматическая отправка печати на принтер не поддерживается;
- — объекты печати — справочники и документы;
- — команды вызова печати дополнительно не настраиваются;
- — используется только безопасный режим работы;
- — механизм создания внешних печатных форм будет упрощен относительно методики создания внешних печатных форм для типовых конфигураций.
Для такого варианта реализации нам понадобятся:
- — справочник для хранения внешних печатных форм и установки соответствия объектам;
- — общая команда для вызова списка печатных форм;
- — общая форма, для выбора печатных форм;
- — набор модулей для обеспечения функционирования механизма;
- — описание создания обработки внешней печатной формы.
Создаем справочник ДополнительныеПечатныеФормы
Реквизиты:
— ХранилищеПечатнойФормы, тип ХранилищеЗначения;
— ДатаЗагрузки, тип дата;
— Комментарий, тип строка;
— КомментарийКФайлу, тип строка;
— Табличная часть ОбъектыПечати:
— Представление, тип строка;
— СсылкаОбъекта, составной тип ДокументСсылка, СправочникСсылка.
В справочнике необходимо указать типы объектов метаданных, для которых будет доступна печатная форма, и загрузить обработку внешней печатной формы в справочник.
Выбор типов объектов для печати:
Добавим реквизит формы спОбъектовПечати типа СписокЗначений.
В обработчике формы ПриСозданииНаСервере заполним список:
&НаСервере Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка) СпОбъектыПечати = ПолучитьСписокОбъектов(); АдресВнешнейПечатнойФормы = ""; КонецПроцедуры &НаСервереБезКонтекста Функция ПолучитьСписокОбъектов() СписокОбъектов = Новый СписокЗначений; Для каждого спр из Метаданные.Справочники Цикл СписокОбъектов.Добавить(Справочники[спр.Имя].ПустаяСсылка(), спр.ПолноеИмя()); КонецЦикла; Для каждого спр из Метаданные.Документы Цикл СписокОбъектов.Добавить(Документы[спр.Имя].ПустаяСсылка(), спр.ПолноеИмя()); КонецЦикла; Возврат СписокОбъектов; КонецФункции
Импорт внешней печатной формы в справочник:
Добавим реквизит формы АдресВнешнейПечатнойФормы, тип — строка.
Организуем выбор файла внешней печатной формы и помещаем его во временное хранилище.
&НаКлиенте Процедура ИмпортПечатнойФормы(Команда) ЗначениеВозврата = ВыбратьФайл("открыть"); Если ЗначениеВозврата = Неопределено Тогда Возврат; КонецЕсли; ИмяФайлаВнешнейОбработки = ЗначениеВозврата.ПолноеИмяФайлаОбработки; Если НЕ ЗначениеЗаполнено(Объект.Наименование) Тогда Объект.Наименование = СокрЛП(ЗначениеВозврата.ИмяФайлаОбработки); КонецЕсли; Объект.КомментарийКФайлу = ЗначениеВозврата.КомментарийКФайлу; Объект.ДатаЗагрузки = ЗначениеВозврата.ДатаЗагрузки; Если НЕ ПоместитьФайл(АдресВнешнейПечатнойФормы, ИмяФайлаВнешнейОбработки, , Ложь, УникальныйИдентификатор) Тогда Сообщение = Новый СообщениеПользователю; Сообщение.Текст = "Ошибка импорта внешней печатной формы!"; Сообщение.Поле = "КомментарийКФайлу"; Сообщение.УстановитьДанные(Объект); Сообщение.Сообщить(); Возврат; КонецЕсли; КонецПроцедуры
Запись в справочник:
Получаем из временного хранилища данные обработки и записываем их в справочник в обработчике ПередЗаписьюНаСервере():
&НаСервере Процедура ПередЗаписьюНаСервере(Отказ, ТекущийОбъект, ПараметрыЗаписи) Если АдресВнешнейПечатнойФормы <> "" Тогда ДанныеПечатнойФормы = ПолучитьИзВременногоХранилища(АдресВнешнейПечатнойФормы); ТекущийОбъект.ХранилищеПечатнойФормы = Новый ХранилищеЗначения(ДанныеПечатнойФормы , Новый СжатиеДанных(9)); КонецЕсли; КонецПроцедуры
Создаем общую команду
В конфигураторе создаем новую общую команду ДополнительныеПечатныеФормы. Устанавливаем свойства:
- группа = Командная панель формы.Важное;
- тип параметра команды = составной тип, отмечаем справочники и документы, для которых будет доступна данная команда;
- режим использования параметра = множественный (устанавливаем для возможности печати для списка объектов).
Также создался модуль команды, в котором будем вызывать выбора печатных форм:
&НаКлиенте Процедура ОбработкаКоманды(ПараметрКоманды, ПараметрыВыполненияКоманды) ДополнительныеПечатныеФормыКлиент.ОткрытьФормуКомандДополнительныхПечатныхФорм(ПараметрКоманды, ПараметрыВыполненияКоманды); КонецПроцедуры
В методе ОткрытьФормуКомандДополнительныхПечатныхФорм() подготовим параметры, и откроем форму со списком печатных форм:
Функция ОткрытьФормуКомандДополнительныхПечатныхФорм(ПараметрыКоманды, ПараметрыВыполненияКоманды) Экспорт ПараметрыКомандыСписок = Новый СписокЗначений; Если ТипЗнч(ПараметрыКоманды) = Тип("Массив") Тогда ПараметрыКомандыСписок.ЗагрузитьЗначения(ПараметрыКоманды); СсылкаОбъекта = ДополнительныеПечатныеФормы.ПолучитьПустуюСсылкуОбъекта(ПараметрыКоманды[0]); Иначе ПараметрыКомандыСписок.Добавить(ПараметрыКоманды); СсылкаОбъекта = ДополнительныеПечатныеФормы.ПолучитьПустуюСсылкуОбъекта(ПараметрыКоманды); КонецЕсли; Параметры = Новый Структура("ОбъектыПечати, СсылкаОбъекта", ПараметрыКомандыСписок, СсылкаОбъекта); ОткрытьФормуМодально("ОбщаяФорма.ДополнительныеПечатныеФормы", Параметры, ПараметрыВыполненияКоманды.Источник); КонецФункции
Создаем общую форму
Создаем новую общую форму типа «произвольная форма». Форма будет принимать параметры: СсылкаОбъекта (будет содержать тип объекта, выводимого на печать) и ОбъектыПечати (список объектов для печати).
Добавляем реквизиты формы:
- — СсылкаОбъекта, составной тип СправочникСсылка, ДокументСсылка;
- — ОбъектыПечати, тип СписокЗначений;
- — ПечатныеФормы, тип таблица значений, таблица с перечнем печатных форм
В таблицу ПечатныеФормы будем выводить список встроенных и внешних печатных форм для данного типа объектов. Также предоставим возможность выбирать необходимые формы для печати установкой флагов в строках таблицы.
Таблица будет содержать колонки:
- — Ссылка, тип СправочникСсылка.ДополнительныеПечатныеФормы;
- — Представление, тип строка;
- — Отметка, тип булево;
- — ДопФормы, тип булево, будет показывать, что в строке дополнительная (внешняя) печатная форма;
- — Макет, строка, будет содержать имя встроенного макета.
При создании на сервере заполним таблицу печатных форм:
&НаСервере Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка) СсылкаОбъекта = Параметры.СсылкаОбъекта; ОбъектыПечати.ЗагрузитьЗначения(Параметры.ОбъектыПечати.ВыгрузитьЗначения()); Если СсылкаОбъекта <> Неопределено Тогда ЗначениеВРеквизитФормы(ОбычныеПечатныеФормы.ДополнитьТаблицуЗаполненияМакетамиМетаданныхОбъекта(
ДополнительныеПечатныеФормы.ПолучитьСписок(СсылкаОбъекта), СсылкаОбъекта), "ПечатныеФормы"); КонецЕсли; КонецПроцедуры
Также можно добавить на форму команды «Отметить все» и «Снять отметки» для группового выделения всех печатных форм и снятия всех отметок.
Теперь реализуем обработку печати выбранных печатных форм для переданных объектов.
Получим из таблицы отмеченные флажками печатные формы. Далее, обходя в цикле выбранные печатные формы, будем выполнять на сервере печать списка объектов. В качестве результата получим массив табличных документов, для которого и организуем вывод на экран.
&НаКлиенте Процедура ЗапуститьНаПечать(Команда) МассивПФ = ПечатныеФормы.НайтиСтроки(Новый Структура("Отметка", Истина)); Если МассивПФ.Количество() = 0 Тогда Сообщение = Новый СообщениеПользователю; Сообщение.Текст = "Печатные формы не выбраны!"; Сообщение.Сообщить(); КонецЕсли; ОбъектыПечатиМассив = ОбъектыПечати.ВыгрузитьЗначения(); Для каждого текПФ из МассивПФ Цикл Если текПФ.ДопФорма Тогда МассивТабДок = ДополнительныеПечатныеФормы.ЗапуститьПечать(текПФ.Ссылка, ОбъектыПечатиМассив); Иначе МассивТабДок = ОбычныеПечатныеФормы.ЗапуститьПечать(текПФ.Макет, ОбъектыПечатиМассив); КонецЕсли; ВывестиТабличныеДокументы(МассивТабДок); КонецЦикла; Закрыть(); КонецПроцедуры &НаКлиенте Процедура ВывестиТабличныеДокументы(МассивТД) Для каждого тд из МассивТД Цикл тд.Показать(тд.ИмяПараметровПечати, , Ложь); КонецЦикла; КонецПроцедуры
Общие модули
Создаем общие модули: ОбычныеПечатныеФормы (сервер, вызов сервера), ДополнительныеПечатныеФормы (сервер, вызов сервера) и ДополнительныеПечатныеФормыКлиент (клиент).
Опишем методы ЗапуститьПечать() модулей обычных и дополнительных печатных форм. Более детально с модулями можно ознакомиться в конфигурации.
Модуль ОбычныеПечатныеФормы:
Функция ЗапуститьПечать(ИмяМакета, ОбъектыПечатиМассив) Экспорт УстановитьПривилегированныйРежим(Истина); МассивТабДок = Новый Массив; Для каждого СсылкаОбъектаНазначения из ОбъектыПечатиМассив Цикл Попытка МетаданныеОбъекта = СсылкаОбъектаНазначения.Метаданные(); Если Метаданные.Документы.Содержит(МетаданныеОбъекта) Тогда новыйТабДок = Документы[МетаданныеОбъекта.Имя].Печать(СсылкаОбъектаНазначения, ИмяМакета); ИначеЕсли Метаданные.Справочники.Содержит(МетаданныеОбъекта) Тогда новыйТабДок = Справочники[МетаданныеОбъекта.Имя].Печать(СсылкаОбъектаНазначения, ИмяМакета); Иначе новыйТабДок = Новый ТабличныйДокумент; КонецЕсли; Исключение ТекстОшибки = "Ошибка вывода <" + Строка(СсылкаОбъектаНазначения) + "> в макет <" + ИмяМакета + ">: " + Символы.ПС + ОписаниеОшибки(); новыйТабДок = ВыводОшибкиВМакет(ТекстОшибки); КонецПопытки; МассивТабДок.Добавить(новыйТабДок); КонецЦикла; Возврат МассивТабДок; КонецФункции Функция ВыводОшибкиВМакет(ТекстОшибки) Экспорт ТабДок = Новый ТабличныйДокумент; Макет = ПолучитьОбщийМакет("ВыводОшибкиВыполнения"); Область = Макет.ПолучитьОбласть("ВыводОшибки"); Область.Параметры.ТекстОшибки = ТекстОшибки; ТабДок.Вывести(Область); Возврат ТабДок; КонецФункции
Модуль ДополнительныеПечатныеФормы:
Функция ЗапуститьПечать(ДополнительнаяПечатнаяФорма, ОбъектыПечатиМассив) Экспорт УстановитьПривилегированныйРежим(Истина); ВнешняяОбработка = ПолучитьОбъектВнешнейПечатнойФормы(ДополнительнаяПечатнаяФорма); Попытка МассивТабДок = ВнешняяОбработка.Печать(ОбъектыПечатиМассив); Исключение ТекстОшибки = "Ошибка вывода дополнительной печатной формы <" + Строка(ДополнительнаяПечатнаяФорма) + ">: " + Символы.ПС + ОписаниеОшибки(); новыйТабДок = Новый ТабличныйДокумент; МассивТабДок = Новый Массив; МассивТабДок.Добавить(ОбычныеПечатныеФормы.ВыводОшибкиВМакет(новыйТабДок)); КонецПопытки; Возврат МассивТабДок; КонецФункции Функция ПолучитьОбъектВнешнейПечатнойФормы(ДополнительнаяПечатнаяФормаСсылка) Экспорт ДополнительнаяПечатнаяФорма = ДополнительнаяПечатнаяФормаСсылка.ПолучитьОбъект(); ДвоичныеДанныеПФ = ДополнительнаяПечатнаяФорма.ХранилищеПечатнойФормы.Получить(); ИмяВременногоФайла = ПолучитьИмяВременногоФайла("epf"); ДвоичныеДанныеПФ.Записать(ИмяВременногоФайла); Возврат ВнешниеОбработки.Создать(ИмяВременногоФайла); КонецФункции
Замечание: в случае возникновения ошибок печати, сообщения выводятся в табличный документ.
Описание создания внешней печатной формы
Важно: подготовка внешних печатных форм для типовых конфигураций отличается от приводимого упрощенного примера.
Внешняя печатная форма будет представлять собой внешнюю обработку *.epf, содержащую макет и экспортную функцию Печать(МассивСсылок) в модуле объекта.
Функция Печать() вызывается из метода ЗапуститьПечать() модуля ДополнительныеПечатныеФормы. Она принимает массив ссылок на объекты, для которых необходимо получить печатные формы.
Схема работы: новый табличный документ создается для каждой ссылки, область печати заполняется данными объекта и добавляется в табличный документ. В качестве результата возвращается массив готовых печатных форм (табличных документов).
Функция Печать(МассивСсылокНаОбъекты) Экспорт МассивТабДок = Новый Массив; Для каждого СсылкаОбъекта из МассивСсылокНаОбъекты Цикл табДок = Новый ТабличныйДокумент; МакетДляПечати = ЭтотОбъект.ПолучитьМакет("Макет"); СтруктураДанных = ЗаполнитьСтруктуруДанных(СсылкаОбъекта); ОбластьПечати = МакетДляПечати.ПолучитьОбласть("Строка"); Если СтруктураДанных <> Неопределено Тогда ЗаполнитьЗначенияСвойств(ОбластьПечати.Параметры, СтруктураДанных); КонецЕсли; табДок.Вывести(ОбластьПечати); табДок.Защита = Истина; табДок.ОтображатьСетку = Ложь; табДок.ОтображатьЗаголовки = Ложь; табДок.ИмяПараметровПечати = ЭтотОбъект.Метаданные().Синоним; табДок.ОриентацияСтраницы = ОриентацияСтраницы.Ландшафт; МассивТабДок.Добавить(табДок); КонецЦикла; Возврат МассивТабДок; КонецФункции
Пример:
В тестовой конфигурации создан документ Письмо, для которого подготовлены несколько печатных форм для печати конвертов. Каждая печатная форма соответствует одному стандартному размеру конверта.
Таким образом, воспользовавшись пакетной печатью, можно получить сразу несколько печатных форм для разных типов конвертов как для одного, так и для нескольких писем одновременно.
2) Интеграция БСП
Подробно процесс внедрения БСП можно найти обратившись к документации http://its.1c.ru/db/bspdoc.
Замечу только, что нам понадобится подсистема ДополнительныеОтчетыИОбработки из группы стандартных подсистем.
Также обязательными, для включения в собственную конфигурацию, будут подсистемы:
- — базовая функциональность;
- — контактная информация;
- — настройка порядка элементов;
- — обновление версии ИБ;
- — получение файлов из интернет;
- — пользователи.
Описание создания типовой внешней печатной формы
Как и в приведенном выше примере, нам потребуется создать внешнюю обработку *.epf.
Общая структура модуля обработки:
- * обязательная сервисная экспортная функция СведенияОВнешнейОбработке(). Вызывается в основной программе при регистрации обработки в информационной базе. В этой функции необходимо указать, для каких объектов предназначена данная обработка, указать ее вид (печатная форма, обработка и т.д.), определить команды для вызова печати и указать дополнительную информацию.
Функция возвращает структуру параметров регистрации:
- — Вид – определяет вид регистрируемой обработки, например, «ПечатнаяФорма»;
- — Назначение – массив, определяет набор объектов, для которых предназначена обработка, например:
Назначения = Новый Массив; Назначения.Добавить("Документ.ЗаказПокупателя"); ПараметрыРегистрации.Вставить("Назначение", Назначения);
- — Наименование – наименование обработки;
- — Версия – строка с номером версии обработки, например, “1.0”;
- — БезопасныйРежим – флаг использования обработки в безопасном режиме;
- — Информация – примечание, дополнительная информация по обработке.
- * обязательная экспортная процедура Печать(МассивОбъектов, КоллекцияПечатныхФорм, ОбъектыПечати, ПараметрыВывода).
Используется для формирования печатных форм объектов.
Принимает параметры:
- — МассивОбъектов – список объектов ссылочного типа для формирования печатных форм.
Возвращает параметры:
- — КоллекцияПечатныхФорм – таблица значений, содержащая сформированные табличные документы;
- — ОбъектыПечати – список объектов печати;
- — ПараметрыВывода – параметры сформированных табличных документов.
- * вспомогательные методы заполнения параметров, таблиц и другие.
Замечания:
Предложенная реализация механизма внешних печатных форм далека от идеала, обладает значительным количеством ограничений и некоторыми недостатками по сравнению с реализацией в БСП. Например, для подключения внешней печатной формы новому типа объекта необходимо будет изменить тип параметра общей команды «ДополнительныеПечатныеФормы».
Но, тем не менее, является достаточно простым и работоспособным примером работы с внешними печатными формами в управляемом приложении.
Наверное имеет смысл _сначала_ написать про БСП, а уже потом предлагать ваять нетленки? 🙂
Не совсем понятно. Есле конфа не типовая, значит обновлений от 1С нет.
Тогда не проще ли вставить нужную форму в конфигурацию.
Как альтенатива БСП — почему бы нет
(2) AleksSF, полностью согласен. Но может AlexSvt хочет закрыть доступ юзерам к кофигуратору и дать им возможность самим вставлять свои печатные формы…
Зачем тут создается общий модуль ДополнительныеПечатныеФормыКлиент, если он не заполняется?
(4) Здравствуйте. Почему же не заполняется? В этом модуле есть одна функция ОткрытьФормуКомандДополнительныхПечатныхФорм() и в тексте она описана. Других методов модуль не содержит.