В процессе написания внешней печатной формы для 1С:ERP Управление предприятием 2 (2.4.6.230), которая, в соответствии с параметрами введенными пользователем в форму, вызываемую при нажатии на соответствующий пункт подменю печати , выводит нужное количество бирок на печать, мною было потрачено много времени на то, чтобы табличный документ, созданный в модуле внешней печатной формы, затем открывался при помощи общей формы печати документов.
Проблема, как мы понимаем, заключается в том, что сначала: нам нужно вызвать на клиенте внешнюю печатную форму, после того как пользователь введет параметры передать их в общую форму печати документов, которая, в свою очередь, должна вызвать процедуру модуля внешней печатной формы - передав в неё нужные параметры, которые пользователь ввел при вызове формы внешней печатной форме на клиенте. Последовательность действий определена и понятна, но тут нужно учитывать креатив создателей общей формы печати документов, единственная переменная, которая может быть передана по всем интересующим звеньям – это массив объектов печати. Сначала я решил не возиться с передачей при помощи массива, а передать параметры через хранилище настроек, но доступ к хранилищам оказался очень ограничен по ролям пользователей, поэтому пришлось вернуться к массиву.
Итак, описание процедур и функций внешней печатной формы:
- В модуле обработки создаем обязательные процедуры необходимые для регистрации обработки в базе:
# Область ОбщиеСведения
Функция СведенияОВнешнейОбработке() Экспорт
ПараметрыРегистрации = Новый Структура;
МассивНазначений = Новый Массив;
МассивНазначений.Добавить("Документ.РеализацияТоваровУслуг"); //Указываем документ к которому делаем внешнюю печ. форму
Попытка
//Вид = ДополнительныеОтчетыИОбработкиКлиентСервер.ВидОбработкиДополнительныйОтчет();
Вид = ДополнительныеОтчетыИОбработкиКлиентСервер.ВидОбработкиПечатнаяФорма();
//Вид = ДополнительныеОтчетыИОбработкиКлиентСервер.ВидОбработкиДополнительнаяОбработка();
//Вид = ДополнительныеОтчетыИОбработкиКлиентСервер.ВидОбработкиЗаполнениеОбъекта();
Исключение
//Вид = "ДополнительныйОтчет";
Вид = "ПечатнаяФорма";
//Вид = "ДополнительнаяОбработка";
//Вид = "ЗаполнениеОбъекта";
КонецПопытки;
ПараметрыРегистрации.Вставить("Вид", Вид); //может быть - ПечатнаяФорма, ЗаполнениеОбъекта, ДополнительныйОтчет, СозданиеСвязанныхОбъектов...
ПараметрыРегистрации.Вставить("Назначение", МассивНазначений);
ПараметрыРегистрации.Вставить("Наименование", "Шаблон - открытие формы"); //имя под которым обработка будет зарегестрирована в справочнике внешних обработок
ПараметрыРегистрации.Вставить("БезопасныйРежим", ЛОЖЬ);
ПараметрыРегистрации.Вставить("Версия", "1.0");
ПараметрыРегистрации.Вставить("Информация", "Внешняя печатная форма");
ТаблицаКоманд = ПолучитьТаблицуКоманд();
//ОткрытиеФормы – Открывает форму обработки.
//ВызовКлиентскогоМетода – будет вызвана клиентская процедура из модуля формы обработки.
//ВызовСерверногоМетода - будет вызвана серверная процедура из модуля обработки.
//СценарийВБезопасномРежиме – тоже будет вызвана серверная процедура из модуля обработки в безопасном режиме.
Попытка
//Тип = ДополнительныеОтчетыИОбработкиКлиентСервер.ТипКомандыВызовСерверногоМетода();
//Тип = ДополнительныеОтчетыИОбработкиКлиентСервер.ТипКомандыВызовКлиентскогоМетода();
Тип = ДополнительныеОтчетыИОбработкиКлиентСервер.ТипКомандыОткрытиеФормы();
Исключение
//Тип = "ВызовСерверногоМетода";
//Тип = "ВызовКлиентскогоМетода";
Тип = "ОткрытиеФормы";
КонецПопытки;
ДобавитьКоманду(ТаблицаКоманд, "Шаблон - открытие формы", "ШаблонОткрытиеФормы", Тип, Истина);
ПараметрыРегистрации.Вставить("Команды", ТаблицаКоманд);
Возврат ПараметрыРегистрации;
КонецФункции // СведенияОВнешнейОбработке()
Функция ПолучитьТаблицуКоманд()
Команды = Новый ТаблицаЗначений;
Команды.Колонки.Добавить("Представление", Новый ОписаниеТипов("Строка"));//как будет выглядеть описание печ.формы для пользователя
Команды.Колонки.Добавить("Идентификатор", Новый ОписаниеТипов("Строка")); //имя макета печ.формы
Команды.Колонки.Добавить("Использование", Новый ОписаниеТипов("Строка")); //ВызовСерверногоМетода
Команды.Колонки.Добавить("ПоказыватьОповещение", Новый ОписаниеТипов("Булево"));
Команды.Колонки.Добавить("Модификатор", Новый ОписаниеТипов("Строка"));
Возврат Команды;
КонецФункции
Процедура ДобавитьКоманду(ТаблицаКоманд, Представление, Идентификатор, Использование, ПоказыватьОповещение = Ложь, Модификатор = "")
НоваяКоманда = ТаблицаКоманд.Добавить();
НоваяКоманда.Представление = Представление;
НоваяКоманда.Идентификатор = Идентификатор;
НоваяКоманда.Использование = Использование;
НоваяКоманда.ПоказыватьОповещение = ПоказыватьОповещение;
НоваяКоманда.Модификатор = Модификатор;
КонецПроцедуры
# КонецОбласти
- Создаем реквизит внешней печатной формы «СтруктураПараметровПечати» с типом «Произвольный». Я использовал его в процессе отладки печати для передачи параметров формы на клиенте в серверные процедуры модуля обработки. Реквизит не обязательный. Создаем форму для отображения пользователю, данная форма позволит пользователю ввести нужные параметры. В модуле формы создаем обязательные процедуры необходимые для получения объектов печати при вызове обработки, когда она будет подключена к базе.
&НаКлиенте
Процедура Печать(ИдентификаторКоманды, ОбъектыНазначения) Экспорт
СтруктураПараметровПечати = Объект.СтруктураПараметровПечати;
Если СтруктураПараметровПечати = Неопределено ИЛИ НЕ ТипЗнч(СтруктураПараметровПечати) = Тип("Структура") Тогда
СтруктураПараметровПечати = Новый Структура;
КонецЕсли;
СтруктураПараметровПечати.Вставить("МассивОбъектов", ОбъектыНазначения);
КонецПроцедуры
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
Если Элементы.Найти("Документ") = Неопределено Тогда
Если НЕ Параметры.Свойство("ОбъектыНазначения") Тогда
Сообщить("Ошибка получения докумнта!");
Отказ = Истина;
Возврат;
КонецЕсли;
КонецЕсли;
СтруктураПараметровПечати = Объект.СтруктураПараметровПечати;
Если СтруктураПараметровПечати = Неопределено ИЛИ НЕ ТипЗнч(СтруктураПараметровПечати) = Тип("Структура") Тогда
СтруктураПараметровПечати = Новый Структура;
КонецЕсли;
Если Параметры.Свойство("ОбъектыНазначения") Тогда
МассивОбъектов = Новый Массив;
Для Каждого мЭл Из Параметры.ОбъектыНазначения Цикл
МассивОбъектов.Добавить(мЭл);
КонецЦикла;
Если НЕ Элементы.Найти("Документ") = Неопределено И НЕ МассивОбъектов.Количество() = 0 Тогда
Документ = МассивОбъектов[0];
КонецЕсли;
СтруктураПараметровПечати.Вставить("МассивОбъектов", МассивОбъектов);
КонецЕсли;
Объект.СтруктураПараметровПечати = СтруктураПараметровПечати;
ПечатьБирок = Истина;
КонецПроцедуры
ОбъектыНазначения – это массив, в который платформа помещает объекты печати.
- В модуле формы: создаем процедуры которые будут отображать табличный документ. При отладке при помощи метода «Показать» табличного документа. Для отображения табличного документа при помощи общей формы вызываем форму печати документов и передаем в неё параметры поместив их в массив «ОбъектыНазначения» элемента структуры «ПараметрыИсточника». Кроме того, необходимо в параметры открытия общей формы поместить элемент с ключом «ИсточникДанных» и в качестве значения поместить ссылку на элемент справочника - «ДополнительныеОтчетыИОбработки», который будет создан при подключении печатной формы к базе. Это необходимо для того чтобы общая форма при создании на сервере вызвала модуль внешней печатной формы и создала табличный документ.
&НаКлиенте
Процедура ПечатьНаКлиенте()
Если Отладка Тогда
мКоллекцияПечатныхФорм = УправлениеПечатьюКлиент.НоваяКоллекцияПечатныхФорм("ШаблонОткрытиеФормы");
ТабличныйДокумент = Новый ТабличныйДокумент;
КнПечатьНаСервере(мКоллекцияПечатныхФорм);
Попытка
ТабличныйДокумент = Объект.СтруктураПараметровПечати.КоллекцияПечатныхФормСтруктура.ТабличныйДокумент;
ТабличныйДокумент.Показать("Шаблон - открытие формы");
Исключение
КонецПопытки;
Иначе
ПараметрыОткрытия = Новый Структура;
ПолучитьПараметрыОткрытия(ПараметрыОткрытия);
Если ПараметрыОткрытия = Неопределено Тогда
Сообщить("Ошибка обработки документа");
Иначе
ОткрытьФорму("ОбщаяФорма.ПечатьДокументов", ПараметрыОткрытия);
КонецЕсли;
Закрыть();
КонецЕсли;
КонецПроцедуры
&НаСервере
Процедура ПолучитьПараметрыОткрытия(ПараметрыОткрытия)
ИсточникДанных = Справочники.ДополнительныеОтчетыИОбработки.НайтиПоНаименованию("Шаблон - открытие формы");
Если ИсточникДанных = Неопределено ИЛИ НЕ ТипЗнч(ИсточникДанных) = Тип("СправочникСсылка.ДополнительныеОтчетыИОбработки") Тогда
ИсточникДанных = Справочники.ДополнительныеОтчетыИОбработки.ПустаяСсылка();
КонецЕсли;
Если Не ЗначениеЗаполнено(ИсточникДанных) Тогда
ПараметрыОткрытия = Неопределено;
Возврат;
КонецЕсли;
ПараметрыОткрытия.Вставить("ИсточникДанных", ИсточникДанных);
ПараметрыИсточника = Новый Структура;
ИдентификаторКоманды = "ШаблонОткрытиеФормы";
ПараметрыПечати = Новый Структура;
ПараметрыПечати.Вставить("ПечатьБирок", ПечатьБирок);
ПараметрыПечати.Вставить("КоличествоБирок", КоличествоБирок);
СтруктураПараметровПечати = Объект.СтруктураПараметровПечати;
Если СтруктураПараметровПечати = Неопределено ИЛИ НЕ ТипЗнч(СтруктураПараметровПечати) = Тип("Структура") Тогда
Если Элементы.Найти("Документ") = Неопределено Тогда
ПараметрыОткрытия = Неопределено;
Возврат;
Иначе
Если ЗначениеЗаполнено(Документ) Тогда
ТекОбъектыНазначения = Новый Массив;
ТекОбъектыНазначения.Добавить(Документ);
ТекОбъектыНазначения.Добавить(ПараметрыПечати);
ПараметрыИсточника.Вставить("ОбъектыНазначения", ТекОбъектыНазначения);
Иначе
ПараметрыОткрытия = Неопределено;
Возврат;
КонецЕсли;
КонецЕсли;
Иначе
Если СтруктураПараметровПечати.Свойство("МассивОбъектов") Тогда
СтруктураПараметровПечати.МассивОбъектов.Добавить(ПараметрыПечати);
ПараметрыИсточника.Вставить("ОбъектыНазначения", СтруктураПараметровПечати.МассивОбъектов);
Иначе
Если ЗначениеЗаполнено(Документ) Тогда
ТекОбъектыНазначения = Новый Массив;
ТекОбъектыНазначения.Добавить(Документ);
ТекОбъектыНазначения.Добавить(ПараметрыПечати);
ПараметрыИсточника.Вставить("ОбъектыНазначения", ТекОбъектыНазначения);
Иначе
ПараметрыОткрытия = Неопределено;
Возврат;
КонецЕсли;
КонецЕсли;
КонецЕсли;
ПараметрыИсточника.Вставить("ИдентификаторКоманды", ИдентификаторКоманды);
ПараметрыОткрытия.Вставить("ПараметрыИсточника", ПараметрыИсточника);
ПараметрыОткрытия.Вставить("ПараметрКоманды", ПараметрыИсточника.ОбъектыНазначения);
КонецПроцедуры
- В модуле внешней печатной формы создаем обязательную процедуру: «Печать», которая будет вызвана из процедуры общей формы печать документов – «ПриСозданииНаСервере».
В процедуре печати получаем массив, в котором передавали параметры печати, параметры - помещаем в нужную переменную. Элемент массива, который хранил нужные нам параметры, удаляем. Я прописал удаление перед каждым вызовом общих процедур, для того чтобы убедиться в том, что внутри общих процедур переменная хранящая массив и переданная в процедуру печати модуля внешней печатной формы не перезаполняется из переменной общей формы печати документов.
Процедура Печать(МассивОбъектов = Неопределено, КоллекцияПечатныхФорм = Неопределено,
ОбъектыПечати = Неопределено, ПараметрыВывода = Неопределено) Экспорт
ПараметрыПечати = Неопределено;
н = 0;
Если НЕ МассивОбъектов = Неопределено И ТипЗнч(МассивОбъектов) = Тип("Массив") Тогда
Для Каждого мЭл Из МассивОбъектов Цикл
Если ТипЗнч(мЭл) = Тип("Структура") Тогда
ПараметрыПечати = Новый Структура;
ПараметрыПечати.Вставить("ПечатьБирок", мЭл.ПечатьБирок);
ПараметрыПечати.Вставить("КоличествоБирок", мЭл.КоличествоБирок);
МассивОбъектов.Удалить(н);
КонецЕсли;
н = н + 1;
КонецЦикла;
КонецЕсли;
Если ПараметрыПечати = Неопределено Тогда
СтруктураПараметровПечати = ЭтотОбъект.СтруктураПараметровПечати;
ПараметрыПечати = Новый Структура;
Если НЕ СтруктураПараметровПечати = Неопределено И ТипЗнч(СтруктураПараметровПечати) = Тип("Структура") Тогда
ПараметрыПечати.Вставить("ПечатьБирок", СтруктураПараметровПечати.ПараметрыПечати.ПечатьБирок);
ПараметрыПечати.Вставить("КоличествоБирок", СтруктураПараметровПечати.ПараметрыПечати.КоличествоБирок);
МассивОбъектов = Новый Массив;
Для Каждого мЭл Из СтруктураПараметровПечати.МассивОбъектов Цикл
МассивОбъектов.Добавить(мЭл);
КонецЦикла;
КоллекцияПечатныхФорм = Новый ТаблицаЗначений;
Для Каждого ЭлСтруктуры Из СтруктураПараметровПечати.мКоллекцияПечатныхФорм[0] Цикл
КоллекцияПечатныхФорм.Колонки.Добавить(ЭлСтруктуры.Ключ);
КонецЦикла;
СтрКоллекцияПечатныхФорм = КоллекцияПечатныхФорм.Добавить();
ЗаполнитьЗначенияСвойств(СтрКоллекцияПечатныхФорм, СтруктураПараметровПечати.мКоллекцияПечатныхФорм[0]);
ОбъектыПечати = Новый СписокЗначений;
ОбъектыПечати.ЗагрузитьЗначения(СтруктураПараметровПечати.ОбъектыПечати.ВыгрузитьЗначения());
ПараметрыВывода = Новый Структура;
Для Каждого ЭлСтруктуры Из СтруктураПараметровПечати.ПараметрыВывода Цикл
ПараметрыВывода.Вставить(ЭлСтруктуры.Ключ, ЭлСтруктуры.Значение);
КонецЦикла;
КонецЕсли;
КонецЕсли;
Если ПараметрыПечати = Неопределено Тогда
Сообщить("Не удалось определить параметры печати!");
Возврат;
КонецЕсли;
Если УправлениеПечатью.НужноПечататьМакет(КоллекцияПечатныхФорм, "ШаблонОткрытиеФормы") Тогда
УправлениеПечатью.ВывестиТабличныйДокументВКоллекцию(
КоллекцияПечатныхФорм,
"ШаблонОткрытиеФормы",
НСтр("ru = 'Шаблон - открытие формы'"),
СформироватьПечатнуюФормуНакладная(МассивОбъектов, ОбъектыПечати, ПараметрыПечати));
КонецЕсли;
Если НЕ МассивОбъектов = Неопределено И ТипЗнч(МассивОбъектов) = Тип("Массив") Тогда
н = 0;
Для Каждого мЭл Из МассивОбъектов Цикл
Если ТипЗнч(мЭл) = Тип("Структура") Тогда
МассивОбъектов.Удалить(н);
КонецЕсли;
н = н + 1;
КонецЦикла;
КонецЕсли;
Если ПараметрыВывода.Свойство("ПараметрыОтправки") Тогда
ФормированиеПечатныхФорм.ЗаполнитьПараметрыОтправки(
ПараметрыВывода.ПараметрыОтправки,
МассивОбъектов,
КоллекцияПечатныхФорм);
Иначе
ОбщегоНазначенияБП.ЗаполнитьДополнительныеПараметрыПечати(МассивОбъектов,
КоллекцияПечатныхФорм,
ОбъектыПечати,
ПараметрыВывода);
КоллекцияПечатныхФормСтруктура = Новый Структура;
Для Каждого Колонка Из КоллекцияПечатныхФорм.Колонки Цикл
КоллекцияПечатныхФормСтруктура.Вставить(Колонка.Имя, КоллекцияПечатныхФорм[0][Колонка.Имя]);
КонецЦикла;
ЭтотОбъект.СтруктураПараметровПечати = Новый Структура("КоллекцияПечатныхФормСтруктура,ОбъектыПечати,ПараметрыВывода",
КоллекцияПечатныхФормСтруктура, ОбъектыПечати, ПараметрыВывода);
КонецЕсли;
КонецПроцедуры