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

24.11.17

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

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

Скачать файл

ВНИМАНИЕ: Файлы из Базы знаний - это исходный код разработки. Это примеры решения задач, шаблоны, заготовки, "строительные материалы" для учетной системы. Файлы ориентированы на специалистов 1С, которые могут разобраться в коде и оптимизировать программу для запуска в базе данных. Гарантии работоспособности нет. Возврата нет. Технической поддержки нет.

Наименование По подписке [?] Купить один файл
Использование механизма редактирования макетов БСП в для внешних обработок.:
.epf 9,35Kb
28
28 Скачать (1 SM) Купить за 1 850 руб.

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

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

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

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

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

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

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

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

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

См. также

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

Синтакс-помощник БСП - cправочник по библиотеке стандартных подсистем. В состав справочника входит описание экспортных процедур и функций, размещенных в областях кода ПрограммныйИнтерфейс БСП.

1800 руб.

21.11.2024    2364    8    14    

8

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

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

11.12.2024    3061    gorenski    0    

8

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

За последние лет 5 несколько раз сталкиваюсь с проблемой на разных проектах (в конфигурациях 1С:ERP, 1С:ERP УХ и многих других, основанных на БСП), когда много пользователей (около 30 тысяч) в информационной базе, время добавления доступа для пользователей занимает значительное время. Открытие списка занимает от 10 до 15 секунд, и каждое изменение списка еще примерно столько же.

1 стартмани

10.12.2024    625    Iaskeliainen    2    

7

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

Некоторые нюансы, если вы захотите создавать свои расширения. Доработка отчета "Связанные документы" для отражения документов расширения. Печатные формы с шаблоном Word.

20.11.2024    2892    milkers    3    

9

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

В статье описан алгоритм для включения документа или справочника в систему БСП. Будет полезно программистам 1С, начинающим работать с БСП.

24.10.2024    1398    PROSTO-1C    0    

16

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

В материале описан универсальный механизм работы с добавленными элементами на общую форму «ФормаОтчета». Думаю, облегчит работу многим разработчикам.

08.10.2024    1195    PROSTO-1C    4    

14

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

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

04.10.2024    2083    MadRave    11    

24
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. Famza 85 24.11.17 11:12 Сейчас в теме
Для обычных форм также работает?
3. Boneman 302 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 302 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 648 15.10.21 14:16 Сейчас в теме
(7) ИмяОбъектаМетаданных = "Документ.АвансовыйОтчет.ПФ_MXL_АвансовыйОтчетВИностраннойВалюте_ru";
9. AxiomABC 09.03.23 12:56 Сейчас в теме
С 129 (примерно) релиза "ОбщаяФорма.РедактированиеТабличногоДокумента" в параметры не передаёт "ТабличныйДокумент". Можно самостоятельно получить из регистра "ПользовательскиеМакетыПечати"
11. zan0zzza 08.11.24 14:55 Сейчас в теме
Спасибо, очень помогли!
Оставьте свое сообщение