Доработка полей шапки печатных форм расширениями. УНФ 3.0

Клиент попросил сделать дополнительное поле «Адрес доставки» в шапку печатных форм «Накладная» и «Торг 12». Там уже есть некий адрес доставки, но он общий, а клиент привязал адреса доставки к договорам и хотел, чтобы адрес выводился отдельной строкой, чтобы сразу бросался в глаза.

Я отладил код и обнаружил, что печатные формы формируются в модуле менеджера обработок:

Формирование осуществляется в функции СформироватьПФ. К сожалению, в «лучших» традициях 1С эта функция монолитна, не разбита на участки и единственный способ вмешаться в ее поведение — это расширить с «Вместо с контролем». Но это плохой способ, т.к. при обновлениях расширение придется сопровождать и обновлять под изменения кода печати. А учитывая, что у клиента Фреш, это сложно вдвойне — придется сначала искать точно такую версию конфигурации, потом отправлять на аудит. А в это время печатная форма не будет обрабатываться корректно. В таком случае более уместно использовать «Вместо».

Делать свою печатную форму тоже как-то не очень.

Сначала я хотел заместить вызов ПередНачаломФормированияДокумента, но в него не попадают ДанныеОбъектовПечати:

Тогда я решил, что буду обрабатывать ДанныеОбъектовПечати перед вызовом функции формирования печатной формы — добавлю нужные данные, а функция их подставит:


&Вместо("СформироватьПФ")
Функция мл_СформироватьПФ(ОписаниеПечатнойФормы, ДанныеОбъектовПечати, ОбъектыПечати, ВключаяУслуги)
	ЗаполнитьАдресДоставкиТочный(ОписаниеПечатнойФормы, ДанныеОбъектовПечати);
	Результат = ПродолжитьВызов(ОписаниеПечатнойФормы, ДанныеОбъектовПечати, ОбъектыПечати, ВключаяУслуги);
	Возврат Результат;
КонецФункции


Процедура ЗаполнитьАдресДоставкиТочный(ОписаниеПечатнойФормы, ДанныеОбъектовПечати) Экспорт
	Для Каждого ДанныеОбъекта ИЗ ДанныеОбъектовПечати Цикл
		Ссылка = ДанныеОбъекта.Ссылка;
		Если ТипЗнч(Ссылка) = Тип("ДокументСсылка.РасходнаяНакладная") Тогда
			//Для расходной накладной и Торг-12 заполняем адрес доставки
			СвойствоАдресПоДоговору = мл_Сервер.СвойствоОбъектаПоИдентификатору("АдресДоставкиПоДоговору");
			АдресДоставкиТочный = мл_Сервер.ПолучитьСвойствоСправочника(Ссылка.Договор, "ДоговорыКонтрагентов", СвойствоАдресПоДоговору);
			Если ДанныеОбъектовПечати.Колонки.Найти("АдресДоставкиТочный") = Неопределено Тогда
				ДанныеОбъектовПечати.Колонки.Добавить("АдресДоставкиТочный");
			КонецЕсли;
			ДанныеОбъекта.АдресДоставкиТочный = АдресДоставкиТочный;
		КонецЕсли;
	КонецЦикла;
КонецПроцедуры

Подход красивый, но не сработал. Потому что колонка в ДанныеОбъектовПечати пдобавился, но в коде нигде не было заполнения параметров по текущей строке данных, везде прописаны конкретные имена полей. Т.е. если добавлять свои данные, они просто не вставятся в параметры печатной формы, увы.

Тогда пришлось применять более топорный метод — постобработку:


&Вместо("СформироватьПФ")
Функция мл_СформироватьПФ(ОписаниеПечатнойФормы, ДанныеОбъектовПечати, ОбъектыПечати, ВключаяУслуги)
	Результат = ПродолжитьВызов(ОписаниеПечатнойФормы, ДанныеОбъектовПечати, ОбъектыПечати, ВключаяУслуги);
	ЗаполнитьАдресДоставкиТочный(ОписаниеПечатнойФормы, ДанныеОбъектовПечати);
	Возврат Результат;
КонецФункции


Процедура ЗаполнитьАдресДоставкиТочный(ОписаниеПечатнойФормы, ДанныеОбъектовПечати) Экспорт
	Для Каждого ДанныеОбъекта ИЗ ДанныеОбъектовПечати Цикл
		Ссылка = ДанныеОбъекта.Ссылка;
		Если ТипЗнч(Ссылка) = Тип("ДокументСсылка.РасходнаяНакладная") Тогда
			//Для расходной накладной и Торг-12 заполняем адрес доставки
			СвойствоАдресПоДоговору = мл_Сервер.СвойствоОбъектаПоИдентификатору("АдресДоставкиПоДоговору");
			АдресДоставкиТочный = мл_Сервер.ПолучитьСвойствоСправочника(Ссылка.Договор, "ДоговорыКонтрагентов", СвойствоАдресПоДоговору);
			ТабличныйДокумент = ОписаниеПечатнойФормы.ТабличныйДокумент;
			Маркер = "$АдресДоставки$";
			Область = ТабличныйДокумент.НайтиТекст(Маркер,,,ложь);
			Если Область <> Неопределено Тогда
				Область.Текст = СтрЗаменить(Область.Текст, Маркер, АдресДоставкиТочный);
			КонецЕсли;
		КонецЕсли;
	КонецЦикла;
КонецПроцедуры

В макете печатной формы в режиме 1С-предприятия я добавляю в нужное мне место выделенный знаками доллара идентификатор поля (обратите внимание — добавлено в два места, т.к. шапка может быть со скидкой или без):

А расширение после формирования печатной формы находит этот идентификатор и подменяет его на нужный текст. Дешево и сердито:

К сожалению, пока 1С не начнет разбивать свои монолитные методы на маленькие, перспектив написания элегантных и красивых расширений нет. Как бы расширения есть, но применять их нет смысла по причинам, описанным выше.

Среда: 3.0.1.248 Объем: 1.5 час

Программисты 1С ждут от метрополии ликвидации крупных методов.

fixin

Программирую на 1С с 1999 года. В 1С просто Гений. В 2020 году ушел из офиса на вольные хлеба фриланса. Принимаю заказы.

Читайте также:

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *