Работа алгоритма выглядит следующим образом. При внесении изменений в табличный документ и закрытии формы программа предложит сохранить внесенные изменения. При повторном формировании печатной формы, программа проверит, были ли сохранены изменения и предложит открыть сохраненный табличный документ или сформировать форму заново.
Алгоритм рассмотрим на примере документа "Счет на оплату покупателю".
Документу добавлены две печатные формы "Счет договор" и "Спецификация".
1. Добавим документу два реквизита типа "Хранилище значения" - ПечатнаяФормаСчета и ПечатнаяФормаСпецификации. В них будут храниться измененные табличные документы.
2. Создаем общий модуль или используем существующий. Добавим в него функцию:
Функция ОткрытьСохраненнуюПечатнуюФорму( п_РеквизитХранилище ) Экспорт
ТабДокумент = п_РеквизитХранилище.Получить();
Если ТабДокумент <> Неопределено Тогда
Ответ = Вопрос("Печатная формы была изменена и сохранена. Открыть сохраненный вариант? Да - Открыть; Нет - Сформировать заново.", РежимДиалогаВопрос.ДаНетОтмена );
Если Ответ = КодВозвратаДиалога.Отмена Тогда
Возврат "Отмена";
ИначеЕсли Ответ = КодВозвратаДиалога.Нет Тогда
Возврат Неопределено;
КонецЕсли;
КонецЕсли;
Возврат ТабДокумент;
КонецФункции
Процедура проверяет наличие данных в хранилище, и если хранилище не пустое, предлагает открыть сохраненный табличный документ или сформировать его заново.
3. Вносим изменения в общую форму "ФормаПечати".
А. Изменям тип реквизита формы "Документ" на составной ДокументСсылка, СправочникСсылка (что бы можно было сохранять печатные формы справочников)
Б. Добавляем в модуль процедуру:
Процедура СохранитьПечатнуюФорму( п_Реквизит )
Если Модифицированность Тогда
Ответ = Вопрос( "Печатная форма была изменена. Сохранить изменения?", РежимДиалогаВопрос.ДаНетОтмена );
Если Ответ = КодВозвратаДиалога.Отмена Тогда
Отказ = Истина;
Возврат;
КонецЕсли;
Если Ответ = КодВозвратаДиалога.Да Тогда
Объект = Документ.ПолучитьОбъект();
ПечатныйДокумент.ВставитьОбласть(ЭлементыФормы.ПолеДокумента.Область());
ХЗ = Новый ХранилищеЗначения(ПечатныйДокумент, Новый СжатиеДанных(9));
Объект[п_Реквизит] = ХЗ;
Объект.Записать();
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Процедура проверяет модифицированность формы печати и предлагает сохранить изменения.
В. и обработчик ПередЗакрытием:
Процедура ПередЗакрытием(Отказ, СтандартнаяОбработка)
Если ТипЗнч( Документ ) = Тип( "СправочникСсылка.ДоговорыКонтрагентов" ) Тогда
СохранитьПечатнуюФорму( "ПечатнаяФорма" );
ИначеЕсли ТипЗнч( Документ ) = Тип( "ДокументСсылка.СчетНаОплатуПокупателю" ) Тогда
Если ИмяМакета = "Спецификация" Тогда
СохранитьПечатнуюФорму( "ПечатнаяФормаСпецификации" );
ИначеЕсли ИмяМакета = "СчетСпец" Тогда
СохранитьПечатнуюФорму( "ПечатнаяФормаСчета" );
КонецЕсли;
КонецЕсли;
КонецПроцедуры
В этой процедуре по типу документа и имени макета определяется реквизит документа в которую сохраняется печатная форма.
Здесь помимо документа из примера есть проверка на справочник "Договоры контрагентов", которому была добавлена печатная форма.
4. Корректируем процедуру Печать модуля документа "Счет на оплату покупателю":
Процедура Печать(ИмяМакета, КоличествоЭкземпляров = 1, НаПринтер = Ложь, НепосредственнаяПечать = Ложь) Экспорт
// Получить экземпляр документа на печать
Если ИмяМакета = "Счет" Тогда
ТабДокумент = ПечатьСчетаЗаказа(ИмяМакета);
//ИЗМЕНЕНИЯ
ИначеЕсли ИмяМакета = "СчетСпец" Тогда
ТабДокумент = СпецПечатныеФормы.ОткрытьСохраненнуюПечатнуюФорму( ПечатнаяФормаСчета );
Если ТабДокумент = "Отмена" Тогда
Возврат;
ИначеЕсли ТабДокумент = Неопределено Тогда
ТабДокумент = ПечатьСчета( ИмяМакета );
КонецЕсли;
ИначеЕсли ИмяМакета = "Спецификация" Тогда
ТабДокумент = СпецПечатныеФормы.ОткрытьСохраненнуюПечатнуюФорму( ПечатнаяФормаСпецификации );
Если ТабДокумент = "Отмена" Тогда
Возврат;
ИначеЕсли ТабДокумент = Неопределено Тогда
ТабДокумент = ПечатьСпецификации();
КонецЕсли;
//ИЗМЕНЕНИЯ
КонецЕсли;
//ИЗМЕНЕНИЯ
//УниверсальныеМеханизмы.НапечататьДокумент(ТабДокумент, КоличествоЭкземпляров, НаПринтер, ОбщегоНазначения.СформироватьЗаголовокДокумента(ЭтотОбъект, ""), НепосредственнаяПечать);
УниверсальныеМеханизмы.НапечататьДокумент(ТабДокумент, КоличествоЭкземпляров, НаПринтер, ОбщегоНазначения.СформироватьЗаголовокДокумента(ЭтотОбъект, ""), НепосредственнаяПечать, Ссылка, ИмяМакета);
//ИЗМЕНЕНИЯ
КонецПроцедуры
Здесь видно как используется процедура ОткрытьСохраненнуюПечатнуюФорму которая, в данном примере, описана в общем модуле СпецПечатныеФормы.
Обратите внимание, что в процедуру "НапечататьДокумент" так же передаются Ссылка и ИмяМакета.