Традиционно начну с того, что искал и не нашёл готового решения, позволяющего в момент печати из документа в «1С:Бухгалтерия предприятия, редакция 3.0» (БП 3.0) выбрать какой именно из макетов печатных форм отправить на печать: стандартный, встроенный в конфигурацию, или макет, изменённый пользователем. По умолчанию БП 3.0 позволяет использовать только один из вариантов макета: стандартный ИЛИ измененный, хотя в конфигурации одновременно хранятся оба макета. Захотелось уйти от «ИЛИ» к «И», не прибегая к внешним печатным формам, оставив пользователю штатную возможность редактирования встроенных макетов печатных форм. Предлагаю своё решение как один из возможных вариантов, не претендующих на уникальность, но позволяющих решить поставленную задачу. В приложенном расширении демонстрируется пример использования двух печатных форм «Акта об оказании услуг» для документа «Реализация (акты, накладные)» («РеализацияТоваровУслуг»).
Алгоритм решения задачи следующий (все модули в моём случае прописываются в расширении к конфигурации БП 3.0). Внесённые изменения в стандартные процедуры обозначены через «скобки»: //дельта стало теперь НАЧАЛО и //дельта стало теперь КОНЕЦ. Это может пригодиться для понимания того, какие были внесены изменения в стандартные процедуры.
1. В модуле менеджера соответствующего документа (в примере это документ «Реализация (акты, накладные)») в процедуру «Печать» добавляем текст, касающийся второй измененной пользователем печатной формы. Ниже приведена часть данной процедуры:
&Вместо("Печать")
Процедура Расш1_Печать(МассивОбъектов, ПараметрыПечати, КоллекцияПечатныхФорм, ОбъектыПечати, ПараметрыВывода)
Если УправлениеПечатью.НужноПечататьМакет(КоллекцияПечатныхФорм, "Накладная") Тогда
УправлениеПечатью.ВывестиТабличныйДокументВКоллекцию(КоллекцияПечатныхФорм, "Накладная", "Расходная накладная",
ПечатьДокумента(МассивОбъектов, ОбъектыПечати, ПараметрыПечати),,"Документ.РеализацияТоваровУслуг.ПФ_MXL_Накладная");
КонецЕсли;
Если УправлениеПечатью.НужноПечататьМакет(КоллекцияПечатныхФорм, "Акт") Тогда
ТаблицаСведенийАктаОбОказанииУслуг = ПолучитьТаблицуСведенийАктаОбОказанииУслуг(МассивОбъектов);
ПараметрыПечати.Вставить("ВидДокументаПечати", "РеализацияТоваровУслуг");
ПараметрыПечати.Вставить("ИмяПараметровПечати", "ПАРАМЕТРЫ_ПЕЧАТИ_РеализацияТоваровУслуг_Акт");
ПараметрыПечати.Вставить("ИмяМакетаПечати", "Документ.РеализацияТоваровУслуг.ПФ_MXL_Акт");
УправлениеПечатью.ВывестиТабличныйДокументВКоллекцию(КоллекцияПечатныхФорм, "Акт", "Акт об оказании услуг",
ПечатьТорговыхДокументов.ПечатьАктаОбОказанииУслуг(ТаблицаСведенийАктаОбОказанииУслуг, ОбъектыПечати, ПараметрыПечати),,
"Документ.РеализацияТоваровУслуг.ПФ_MXL_Акт");
ПараметрыВывода.Вставить("ФормироватьЭД", Истина);
КонецЕсли;
//дельта стало теперь 2019-06-11 НАЧАЛО
Если УправлениеПечатью.НужноПечататьМакет(КоллекцияПечатныхФорм, "АктСПодписями") Тогда
ТаблицаСведенийАктаОбОказанииУслуг = ПолучитьТаблицуСведенийАктаОбОказанииУслуг(МассивОбъектов);
ПараметрыПечати.Вставить("ВидДокументаПечати", "РеализацияТоваровУслуг");
ПараметрыПечати.Вставить("ИмяПараметровПечати", "ПАРАМЕТРЫ_ПЕЧАТИ_РеализацияТоваровУслуг_Акт_Подписи");
ПараметрыПечати.Вставить("ИмяМакетаПечати", "Документ.РеализацияТоваровУслуг.ПФ_MXL_Акт");
КоллекцияПечатныхФорм[0].ИмяВРЕГ = "АКТ";
КоллекцияПечатныхФорм[0].ИмяМакета = "Акт";
УправлениеПечатью.ВывестиТабличныйДокументВКоллекцию(КоллекцияПечатныхФорм, "Акт", "Акт об оказании услуг (с подписями)",
ПечатьТорговыхДокументов.ПечатьАктаОбОказанииУслуг(ТаблицаСведенийАктаОбОказанииУслуг, ОбъектыПечати, ПараметрыПечати),,
"Документ.РеализацияТоваровУслуг.ПФ_MXL_Акт");
ПараметрыВывода.Вставить("ФормироватьЭД", Истина);
КонецЕсли;
//дельта стало теперь 2019-06-11 КОНЕЦ
//…
//здесь оставшийся текст процедуры
//…
ОбщегоНазначенияБП.ЗаполнитьДополнительныеПараметрыПечати(МассивОбъектов,
КоллекцияПечатныхФорм,
ОбъектыПечати,
ПараметрыВывода);
КонецПроцедуры
2. В модуле менеджера соответствующего документа (в примере это «Реализация (акты, накладные)») в процедуру «ДобавитьКомандыПечати» добавляем текст, касающийся второй печатной формы. Ниже приведен весь текст данной процедуры:
&После("ДобавитьКомандыПечати")
Процедура Расш1_ДобавитьКомандыПечати(КомандыПечати)
// Акт об оказании услуг
КомандаПечати = КомандыПечати.Добавить();
КомандаПечати.Идентификатор = "АктСПодписями";
КомандаПечати.Представление = НСтр("ru = 'Акт об оказании услуг (с подписями)'");
КомандаПечати.Обработчик = "УправлениеПечатьюБПКлиент.ВыполнитьКомандуПечати";
КомандаПечати.СписокФорм = "ФормаСписка,ФормаВыбора,ФормаДокументаОбщая,ФормаДокументаУслуги";
КомандаПечати.Порядок = 30;
КонецПроцедуры
3. В общем модуле «ПечатьТорговыхДокументов» изменяем процедуру печати необходимой печатной формы (в случае примера это процедура «ПечатьАктаОбОказанииУслуг»). Ниже приведена часть данной процедуры:
&Вместо("ПечатьАктаОбОказанииУслуг")
Функция Расш1_ПечатьАктаОбОказанииУслуг(СведенияАктаОбОказанииУслуг, ОбъектыПечати, СтруктураПараметровПечати)
УстановитьПривилегированныйРежим(Истина);
ДополнительнаяКолонкаПечатныхФормДокументов = Константы.ДополнительнаяКолонкаПечатныхФормДокументов.Получить();
Если НЕ ЗначениеЗаполнено(ДополнительнаяКолонкаПечатныхФормДокументов) Тогда
ДополнительнаяКолонкаПечатныхФормДокументов = Перечисления.ДополнительнаяКолонкаПечатныхФормДокументов.НеВыводить;
КонецЕсли;
ВыводитьКоды = ДополнительнаяКолонкаПечатныхФормДокументов <> Перечисления.ДополнительнаяКолонкаПечатныхФормДокументов.НеВыводить;
ТабличныйДокумент = Новый ТабличныйДокумент;
ТабличныйДокумент.АвтоМасштаб = Истина;
ТабличныйДокумент.ОриентацияСтраницы = ОриентацияСтраницы.Портрет;
ТабличныйДокумент.КлючПараметровПечати = СтруктураПараметровПечати.ИмяПараметровПечати;
//дельта стало теперь 2019-06-11 НАЧАЛО
Если СтруктураПараметровПечати.ИмяПараметровПечати = "ПАРАМЕТРЫ_ПЕЧАТИ_РеализацияТоваровУслуг_Акт_Подписи" Тогда
//используем исправленный макет
Макет = УправлениеПечатью.МакетПечатнойФормы(СтруктураПараметровПечати.ИмяМакетаПечати);
Иначе
//используем типовой макет
Макет = д_МакетПечатнойФормы(СтруктураПараметровПечати.ИмяМакетаПечати);
КонецЕсли;
//дельта стало теперь 2019-06-11 КОНЕЦ
ПервыйДокумент = Истина;
//…
//здесь оставшийся текст процедуры
//…
Возврат ТабличныйДокумент;
КонецФункции
4. В общем модуле «ПечатьТорговыхДокументов» добавляем свою процедуру печати необходимой печатной формы (в случае примера это процедура «д_МакетПечатнойФормы»). Ниже приведен весь текст данной процедуры:
Функция д_МакетПечатнойФормы(ПутьКМакету) Экспорт
ТекстОшибки = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
НСтр("ru = 'Макет ""%1"" не существует. Операция прервана.'"), ПутьКМакету);
ЧастиПути = СтрРазделить(ПутьКМакету, ".", Истина);
Если ЧастиПути.Количество() <> 2 И ЧастиПути.Количество() <> 3 Тогда
ВызватьИсключение ТекстОшибки;
КонецЕсли;
ИмяМакета = ЧастиПути[ЧастиПути.ВГраница()];
ЧастиПути.Удалить(ЧастиПути.ВГраница());
ИмяОбъекта = СтрСоединить(ЧастиПути, ".");
ТекстЗапроса =
"ВЫБРАТЬ
| ПользовательскиеМакетыПечати.Макет КАК Макет,
| ПользовательскиеМакетыПечати.ИмяМакета КАК ИмяМакета
|ИЗ
| РегистрСведений.ПользовательскиеМакетыПечати КАК ПользовательскиеМакетыПечати
|ГДЕ
| ПользовательскиеМакетыПечати.Объект = &Объект
| И ПользовательскиеМакетыПечати.ИмяМакета ПОДОБНО &ИмяМакета
| И ПользовательскиеМакетыПечати.Использование";
Запрос = Новый Запрос(ТекстЗапроса);
Запрос.Параметры.Вставить("Объект", ИмяОбъекта);
Запрос.Параметры.Вставить("ИмяМакета", "%" + ИмяМакета + "%");
Выборка = Запрос.Выполнить().Выбрать();
СписокМакетов = Новый Соответствие;
//дельта стало теперь 2019-06-11 НАЧАЛО
//Пока Выборка.Следующий() Цикл
// СписокМакетов.Вставить(Выборка.ИмяМакета, Выборка.Макет.Получить());
//КонецЦикла;
//дельта стало теперь 2019-06-11 КОНЕЦ
ИменаПоиска = Новый Массив;
Если СтрНайти(ИмяМакета, "ПФ_DOC_") > 0
Или СтрНайти(ИмяМакета, "ПФ_ODT_") > 0 Тогда // Для обратной совместимости.
ТекущийЯзык = ТекущийЯзык();
Если ТипЗнч(ТекущийЯзык) <> Тип("ОбъектМетаданных") Тогда
ТекущийЯзык = Метаданные.ОсновнойЯзык;
КонецЕсли;
КодЯзыка = ТекущийЯзык.КодЯзыка;
ИменаПоиска.Добавить(ИмяМакета + "_" + КодЯзыка);
Если КодЯзыка <> Метаданные.ОсновнойЯзык.КодЯзыка Тогда
ИменаПоиска.Добавить(ИмяМакета + "_" + Метаданные.ОсновнойЯзык.КодЯзыка);
КонецЕсли;
КонецЕсли;
ИменаПоиска.Добавить(ИмяМакета);
Для Каждого ИмяПоиска Из ИменаПоиска Цикл
НайденныйМакет = СписокМакетов[ИмяПоиска];
Если НайденныйМакет <> Неопределено Тогда
Возврат НайденныйМакет;
КонецЕсли;
КонецЦикла;
ЭтоОбщийМакет = СтрРазделить(ИмяОбъекта, ".").Количество() = 1;
КоллекцияМакетов = Метаданные.ОбщиеМакеты;
Если Не ЭтоОбщийМакет Тогда
ОбъектМетаданных = Метаданные.НайтиПоПолномуИмени(ИмяОбъекта);
Если ОбъектМетаданных = Неопределено Тогда
ВызватьИсключение ТекстОшибки;
КонецЕсли;
КоллекцияМакетов = ОбъектМетаданных.Макеты;
КонецЕсли;
Для Каждого ИмяПоиска Из ИменаПоиска Цикл
Если КоллекцияМакетов.Найти(ИмяПоиска) <> Неопределено Тогда
Если ЭтоОбщийМакет Тогда
Возврат ПолучитьОбщийМакет(ИмяПоиска);
Иначе
УстановитьОтключениеБезопасногоРежима(Истина);
УстановитьПривилегированныйРежим(Истина);
Возврат ОбщегоНазначения.МенеджерОбъектаПоПолномуИмени(ИмяОбъекта).ПолучитьМакет(ИмяПоиска);
КонецЕсли;
КонецЕсли;
КонецЦикла;
ВызватьИсключение ТекстОшибки;
КонецФункции
После выполнения всех этих действий у вас в соответствующем документе станет доступным печать обоих макетов одной печатной формы. Расширение подключается к конфигурации «1С:Бухгалтерия 3.0» и после перезапуска базы в соответствующем документе появляется возможность печати обоих вариантов макета одной печатной формы. Подключается расширение в меню «Администрирование → Печатные формы, отчеты и обработки → Расширения», после этого надо перезапустить базу. Разработка и тестирование осуществлялись на типовом релизе «1С:Бухгалтерия предприятия, редакция 3.0» 3.0.70.50 и платформе 1С 8.3.14.1779.
Примечания:
- предложенный механизм использования того или иного макета работает только в процессе формирования печатной формы через кнопку «Печать» и не отрабатывает событие, если печатные формы формируются как вложения в электронное письмо при нажатии кнопку отправки электронного письма на форме документа.