Использование механизма редактирования макетов БСП для внешних обработок

24.11.17

Разработка - БСП (Библиотека стандартных подсистем)

Небольшие изыскания по применению механизма редактирования внешних печатных форм для своих внешних обработок.

Скачать исходный код

Наименование Файл Версия Размер
Использование механизма редактирования макетов БСП в для внешних обработок.:
.epf 9,35Kb
23
.epf 9,35Kb 23 Скачать

На мысль натолкнуло обсуждение на местном форуме, где человек задался вопросом, а можно ли редактировать макет внешней печатной формы в пользовательском режиме. Решил поковыряться поглубже.

Ведь действительно, в современных конфигурациях - очень удобно, раз и подрисовал какую нибудь мелочь, прямо в пользовательском режиме через меню администрирование-печатные формы, отчеты и обработки-макеты печатных форм.

Но этот механизм работает только для объектов из самой конфигурации. А как нам его использовать для своих внешних отчетов и обработок ? И можно ли ? Начинаем смотреть.

Сами пользовательские макеты у нас хранятся в регистре сведений - ПользовательскиеМакетыПечати

Регистр независимый, непериодический. Измерения имеют строковый тип, сам макет - тип "хранилище значений".

Все красиво, все прекрасно. На данном этапе нет никаких причин и ограничений для использования его по своему назначению.

Посмотрим на форму списка регистра, называется он "МакетыПечатныхФорм".

&НаСервере
Процедура ЗаполнитьТаблицуМакетовПечатныхФорм()
	
	КоллекцииОбъектовМетаданных = Новый Массив;
	КоллекцииОбъектовМетаданных.Добавить(Метаданные.Справочники);
	КоллекцииОбъектовМетаданных.Добавить(Метаданные.Документы);
	КоллекцииОбъектовМетаданных.Добавить(Метаданные.Обработки);
	КоллекцииОбъектовМетаданных.Добавить(Метаданные.БизнесПроцессы);
	КоллекцииОбъектовМетаданных.Добавить(Метаданные.Задачи);
	КоллекцииОбъектовМетаданных.Добавить(Метаданные.ЖурналыДокументов);
	КоллекцииОбъектовМетаданных.Добавить(Метаданные.Отчеты);
	
	Для Каждого КоллекцияОбъектовМетаданных Из КоллекцииОбъектовМетаданных Цикл
		Для Каждого ОбъектМетаданныхКоллекции Из КоллекцияОбъектовМетаданных Цикл
			Для Каждого ОбъектМетаданныхМакет Из ОбъектМетаданныхКоллекции.Макеты Цикл
				ТипМакета = ТипМакета(ОбъектМетаданныхМакет.Имя);
				Если ТипМакета = Неопределено Тогда
					Продолжить;
				КонецЕсли;
				Если ОбщегоНазначения.ОбъектМетаданныхДоступенПоФункциональнымОпциям(ОбъектМетаданныхКоллекции) Тогда
					ДобавитьОписаниеМакета(ОбъектМетаданныхКоллекции.ПолноеИмя() + "." + ОбъектМетаданныхМакет.Имя, ОбъектМетаданныхМакет.Синоним, ОбъектМетаданныхКоллекции.Синоним, ТипМакета);
				КонецЕсли;
			КонецЦикла;
		КонецЦикла;
	КонецЦикла;
	
	Для Каждого ОбъектМетаданныхМакет Из Метаданные.ОбщиеМакеты Цикл
		ТипМакета = ТипМакета(ОбъектМетаданныхМакет.Имя);
		Если ТипМакета = Неопределено Тогда
			Продолжить;
		КонецЕсли;
		ДобавитьОписаниеМакета("ОбщийМакет." + ОбъектМетаданныхМакет.Имя, ОбъектМетаданныхМакет.Синоним, НСтр("ru = 'Общий макет'"), ТипМакета);
	КонецЦикла;
	
	МакетыПечатныхФорм.Сортировать("ПредставлениеМакета Возр");
	
	УстановитьФлагиИспользованияИзмененныхМакетов();
КонецПроцедуры

&НаСервере
Функция ТипМакета(ИмяОбъектаМетаданныхМакета)
	
	ТипыМакетов = Новый Массив;
	ТипыМакетов.Добавить("MXL");
	ТипыМакетов.Добавить("DOC");
	ТипыМакетов.Добавить("ODT");
	
	Для Каждого ТипМакета Из ТипыМакетов Цикл
		Позиция = СтрНайти(ИмяОбъектаМетаданныхМакета, "ПФ_" + ТипМакета);
		Если Позиция > 0 Тогда
			Возврат ТипМакета;
		КонецЕсли;
	КонецЦикла;
	
	Возврат Неопределено;
	
КонецФункции

Видим, что в список попадут исключительно печатные формы по объектам метаданных, да еще и с формализованными именами вида "ПФ_MXL" "ПФ_DOC" "ПФ_ODT".

Значит, на стандартной форме мы никак не увидим нашего макета. Но это все равно делу не мешает.

Зайдя в любой менеджер объекта, мы увидим, что печатная форма стандартно вызывается через общий модуль.

Макет = УправлениеПечатью.МакетПечатнойФормы(ИмяОбъектаМетаданных);

Это экспортная процедура

Функция МакетПечатнойФормы(ПолныйПутьКМакету) Экспорт
	
	ЧастиПути = СтрЗаменить(ПолныйПутьКМакету, ".", Символы.ПС);
	
	Если СтрЧислоСтрок(ЧастиПути) = 3 Тогда
		ПутьКМетаданным = СтрПолучитьСтроку(ЧастиПути, 1) + "." + СтрПолучитьСтроку(ЧастиПути, 2);
		ПутьКОбъектуМетаданных = СтрПолучитьСтроку(ЧастиПути, 3);
	ИначеЕсли СтрЧислоСтрок(ЧастиПути) = 2 Тогда
		ПутьКМетаданным = СтрПолучитьСтроку(ЧастиПути, 1);
		ПутьКОбъектуМетаданных = СтрПолучитьСтроку(ЧастиПути, 2);
	Иначе
		ВызватьИсключение СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр("ru = 'Макет ""%1"" не найден. Операция прервана.'"), ПолныйПутьКМакету);
	КонецЕсли;
	
	Запрос = Новый Запрос;
	
	Запрос.Текст = "ВЫБРАТЬ Макет КАК Макет, Использование КАК Использование
					|ИЗ
					|	РегистрСведений.ПользовательскиеМакетыПечати
					|ГДЕ
					|	Объект=&Объект
					|	И	ИмяМакета=&ИмяМакета
					|	И	Использование";
	
	Запрос.Параметры.Вставить("Объект", ПутьКМетаданным);
	Запрос.Параметры.Вставить("ИмяМакета", ПутьКОбъектуМетаданных);
	
	УстановитьОтключениеБезопасногоРежима(Истина);
	УстановитьПривилегированныйРежим(Истина);
	
	Выборка = Запрос.Выполнить().Выбрать();
	
	УстановитьПривилегированныйРежим(Ложь);
	УстановитьОтключениеБезопасногоРежима(Ложь);
	
	Результат = Неопределено;
	
	Если Выборка.Следующий() Тогда
		Результат = Выборка.Макет.Получить();
	Иначе
		Если СтрЧислоСтрок(ЧастиПути) = 3 Тогда
			Результат = ОбщегоНазначения.МенеджерОбъектаПоПолномуИмени(ПутьКМетаданным).ПолучитьМакет(ПутьКОбъектуМетаданных);
		Иначе
			Результат = ПолучитьОбщийМакет(ПутьКОбъектуМетаданных);
		КонецЕсли;
	КонецЕсли;
	
	Если Результат = Неопределено Тогда
		ВызватьИсключение СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр("ru = 'Макет ""%1"" не найден. Операция прервана.'"), ПолныйПутьКМакету);
	КонецЕсли;
		
	Возврат Результат;
	
КонецФункции

По процедуре мы видим, что сначала разбивается путь к объекту метаданных, и из регистра пытается получить макет по ключевым параметрам, ИмяМакета и Объект.

Если найдет - то сразу возвращает, содержимое хранилища. А вот если нет, то через менеджер объекта по полному имени получает макет из конфигурации.

Соответственно для внешней обработки, если ничего в хранилище не будет, она неизбежно упадет в исключение.

Ну и ладно, значит так и обработаем.

Осталось понять где же сам редактор.

Сам редактор - это общая форма "РедактированиеТабличногоДокумента". Ее только нужно открыть с нужными нам параметрами, а при закрытии она вызывает оповещение формы родителя с ОпределеннымиСобытиями.

Проанализировав код программы, находим нужные нам методы.

Открыть редактор, делаем кнопку в самой нашей обработке

&НаКлиенте
Процедура РедактироватьМакет(Команда)
	
	ПараметрыОткрытия = Новый Структура;
	ПараметрыОткрытия.Вставить("ИмяОбъектаМетаданныхМакета", ИмяОбъектаМетаданных); //Полный путь
	ПараметрыОткрытия.Вставить("ТипМакета", "MXL");
	ПараметрыОткрытия.Вставить("ТабличныйДокумент", ПолучениеМакета()); //Тут должен быть макет
	
	ПараметрыОткрытия.Вставить("ИмяДокумента", "Внешняя обработка Редактирование печатных форм");
	ПараметрыОткрытия.Вставить("Редактирование", Истина);
	ОткрытьФорму("ОбщаяФорма.РедактированиеТабличногоДокумента", ПараметрыОткрытия, ЭтотОбъект);

КонецПроцедуры

оповещение возвращает нам параметр, отредактированный макет

&НаКлиенте
Процедура ОбработкаОповещения(ИмяСобытия, Параметр, Источник)
	Если ИмяСобытия = "Запись_ТабличныйДокумент" И Источник.ВладелецФормы = ЭтотОбъект Тогда
		Макет = Параметр.ТабличныйДокумент;
		АдресМакетаВоВременномХранилище = ПоместитьВоВременноеХранилище(Макет);
		ЗаписатьМакет(Параметр.ИмяОбъектаМетаданныхМакета, АдресМакетаВоВременномХранилище);
	КонецЕсли;

КонецПроцедуры

Как осуществляется запись макета подсмотрим в форме регистра

&НаСервереБезКонтекста
Процедура ЗаписатьМакет(ИмяОбъектаМетаданныхМакета, АдресМакетаВоВременномХранилище)
	УправлениеПечатью.ЗаписатьМакет(ИмяОбъектаМетаданныхМакета, АдресМакетаВоВременномХранилище);
КонецПроцедуры

Т.к. из администривания нам наш макет не будет виден, то позаботимся и о том, чтобы этот макет можно было удалить из регистра.

Тоже сделаем кнопочку на форме нашей обработки.

&НаКлиенте
Процедура УдалитьМакет(Команда)
	
	УдаляемыеМакеты = Новый Массив;
	УдаляемыеМакеты.Добавить(ИмяОбъектаМетаданных);
	УдалитьИзмененныеМакеты(УдаляемыеМакеты);

КонецПроцедуры

&НаСервереБезКонтекста
Процедура УдалитьИзмененныеМакеты(УдаляемыеМакеты)
	
	Для Каждого ИмяОбъектаМетаданныхМакета Из УдаляемыеМакеты Цикл
		ЧастиИмени = СтрРазделить(ИмяОбъектаМетаданныхМакета, ".");
		ИмяМакета = ЧастиИмени[ЧастиИмени.ВГраница()];
		
		ИмяВладельца = "";
		Для НомерЧасти = 0 По ЧастиИмени.ВГраница()-1 Цикл
			Если Не ПустаяСтрока(ИмяВладельца) Тогда
				ИмяВладельца = ИмяВладельца + ".";
			КонецЕсли;
			ИмяВладельца = ИмяВладельца + ЧастиИмени[НомерЧасти];
		КонецЦикла;
		
		МенеджерЗаписи = РегистрыСведений.ПользовательскиеМакетыПечати.СоздатьМенеджерЗаписи();
		МенеджерЗаписи.Объект = ИмяВладельца;
		МенеджерЗаписи.ИмяМакета = ИмяМакета;
		МенеджерЗаписи.Удалить();
	КонецЦикла;
	
КонецПроцедуры

ну и так, как у нас стандартная процедура в случае отсутствия пользовательского макета вываливает исключение, то мы используем ее частично, и будем не напрямую обращатся, а через свою процедурку.

&НаСервере
Функция ПолучениеМакета()
	Попытка
		Макет = УправлениеПечатью.МакетПечатнойФормы(ИмяОбъектаМетаданных);
		Элементы.ФормаУдалитьМакет.Видимость=Истина;
	исключение
		Макет = РеквизитФормыВЗначение("Объект").ПолучитьМакет("ПФ_MXL_МакетВПФ");
		Элементы.ФормаУдалитьМакет.Видимость=Ложь;
	КонецПопытки;
	Возврат Макет;
КонецФункции

Заодно будем устанавливать видимость кнопки "удалить", если макет там уже есть.

Ну и выведем наш тестовый пример печатной формы

&НаСервере
Функция СформироватьПФНаСервере()
	ТабДок = Новый ТабличныйДокумент;
	
	Макет = ПолучениеМакета();
	ОбластьШапка = Макет.ПолучитьОбласть("Шапка");
	ОбластьСтрокаШапка = Макет.ПолучитьОбласть("СтрокаШапка");
	ОбластьСтрДанные = Макет.ПолучитьОбласть("СтрДанные");
	ТабДок.Вывести(ОбластьШапка);
	ТабДок.Вывести(ОбластьСтрокаШапка);
	Для Каждого Стр из Объект.Товары Цикл
		ОбластьСтрДанные.Параметры.Заполнить(стр);
		ТабДок.Вывести(ОбластьСтрДанные);
	КонецЦикла;
	
	Возврат ТабДок;
	
КонецФункции

 

Собственно все работает.

Получаем обработку, с двумя дополнительными кнопочками - редактирование и удаление макета. И макет у нас при этом, вполне себе меняется в пользовательском режиме. Что нам и требовалось.

Если вдруг сильно хочется, посмотреть содержимое регистра, то мы его сможем увидеть только запросом, в консольке.

 

Для наглядности, если не очень понятно, прикладываю эту родившуюся обработку.

Эксприментировал на типовой 1С Бухгалтерии 3.0.52.42.

Обработка печатная форма внешней обработки БСП

См. также

Шаблон многопоточного выполнения фонового задания

Инструментарий разработчика БСП (Библиотека стандартных подсистем) Программист Платформа 1С v8.3 Конфигурации 1cv8 Абонемент ($m)

Пример шаблона для многопоточного выполнения фонового задания на основе БСП. Шаблоны сделаны для процедуры и функции.

2 стартмани

03.05.2024    860    13    Hitcher    2    

8

Создать на основании - своя кнопка (БСП). Проблема двух подменю Создать на основании

БСП (Библиотека стандартных подсистем) Адаптация типовых решений Программист Платформа 1С v8.3 1С:ERP Управление предприятием 2 Бесплатно (free)

Понадобилось в подменю "Создать на основании" добавить свою команду, которая открывает обработку. В процессе доработок появилась проблема двух подменю "Создать на основании". В статье о том, как решились проблемы.

01.03.2024    2561    dimanich70    8    

15

Заполнение поля адреса в своей обработке [БСП]

Механизмы платформы 1С БСП (Библиотека стандартных подсистем) Программист Стажер Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Небольшая шпаргалка по функциям БСП касательно адреса. Так скажем, еще один способ помимо https://infostart.ru/1c/articles/1060970/

12.02.2024    947    FilippovRI    0    

17

Расширяем возможности дополнительных обработок и настраиваем их отладку

БСП (Библиотека стандартных подсистем) Механизмы типовых конфигураций Программист Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Уже не одна веб-страница исписана знаниями о дополнительных обработках, как создать, как подключить. Есть масса вариантов, как их можно отладить. Я разобрался в кишках работы библиотеки и покажу, как можно расширить возможности дополнительных отчетов, а также покажу удобный способ отладки.

07.02.2024    2965    YA_418728146    11    

49

1С:БСП Дополнительные реквизиты и сведения

БСП (Библиотека стандартных подсистем) Программист Платформа 1С v8.3 Бесплатно (free)

В этой статье расскажем об архитектуре, использовании и особенностях реализации подсистемы «Свойства» из инструментария разработчика «1С:Библиотека стандартных подсистем» (1С: БСП).

19.01.2024    8438    PROSTO-1C    5    

47
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. Famza 85 24.11.17 11:12 Сейчас в теме
Для обычных форм также работает?
3. Boneman 298 24.11.17 11:16 Сейчас в теме
(1) в конфигурациях на обычных формах, никогда не было возможности редактировать макет в пользовательском режиме. Этот механизм появился в типовых конфигурациях на управляемых формах.
6. binex 279 20.03.18 20:23 Сейчас в теме
(3) редактирование макета в пользовательском режиме на обычных формах https://infostart.ru/public/337901/
2. necropunk 9 24.11.17 11:15 Сейчас в теме
Хех, любопытно, сам этим вопросом задавался, просматривал эти процедуры, но до реализаци руки не дошли.
4. hotey 42 04.12.17 10:39 Сейчас в теме
Уже же вроде было на управляемых формах:
https://infostart.ru/public/92500/
Для УПП сам доделывал под впиленный туда аналогичный механизм: https://infostart.ru/public/419417/
5. Boneman 298 04.12.17 10:57 Сейчас в теме
(4) ну может и было, я весь интернет не отслеживаю. Да, не отрицаю, посмотрел, там старенькая публикация, предполагается доработка конфигурации. Мой вариант, будет работать на любой типовой.
Хотя в принципе, те же яйца...
10. nano1c 172 05.04.23 11:05 Сейчас в теме
(4) попытался допилить под редактирование внеш.форм последнюю ут11 и вдргу обнаружил что там переделывать вообще кучу всего нужно, видимо БСП теперь совсем другая. Проще не пилить вообще, учитывая что обновлять придется, а если нужно править макеты, то либо делать встроенную форму, либо как здесь советуют делать обработку с кнопкой (вся сложность в том чтобы заставить работать стандартную кнопку редактирования макета - там кучу кишок БСП допиливать нужно, но если сделать свою форму с кнопкой, как описано тут, то все проще).
7. RBA1972 07.04.21 12:34 Сейчас в теме
Подскажите, пожалуйста, новичку - откуда взять "ИмяОбъектаМетаданных"?
8. pridecom 806 15.10.21 14:16 Сейчас в теме
(7) ИмяОбъектаМетаданных = "Документ.АвансовыйОтчет.ПФ_MXL_АвансовыйОтчетВИностраннойВалюте_ru";
9. AxiomABC 09.03.23 12:56 Сейчас в теме
С 129 (примерно) релиза "ОбщаяФорма.РедактированиеТабличногоДокумента" в параметры не передаёт "ТабличныйДокумент". Можно самостоятельно получить из регистра "ПользовательскиеМакетыПечати"
Оставьте свое сообщение