gifts2017

Пользовательские макеты для внешних печатных форм в УПП 1.3

Опубликовал Михаил Кузнецов (hotey) в раздел Программирование - Практика программирования

Возникла задача - дать пользователям возможность незначительно редактировать оформление макетов для внешних печатных форм в рамках конфигурации УПП 1.3. Вот что получилось.

Как обычно, сначала поискал готовое решение. Максимально близко решение данной задачи описано в этой публикации: http://infostart.ru/public/92500/. С той лишь разницей, что там данная задача решалась для конфигурации УТ 11.

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

РС (регистр сведений) "Пользовательские макеты печати", в котором собственно хранятся макеты, измененные пользователем, является частью подсистемы Печать из БСП (библиотеки стандартных подсистем). И поначалу я думал, что придётся внедрять в УПП версию БСП 2.1. Однако оказалось, что в УПП 1.3 последних версий данный регистр уже включен и даже используется в паре объектов конфигурации. Например, в документе "Выпуск продукции". Это существенно сокращает количество изменений, которые придется внести в конфигурацию, но давайте по порядку.

1. Чтобы дополнить перечень объектов, которые мы видим в форме РС ПользовательскиеМакетыПечати и для которых мы можем редактировать пользовательский макет, надо внести изменения в форму МакетыПечатныхФорм. Также надо не забыть увеличить длину измерения Объект в этом РС, на случай слишком длинного наименования ВПФ (внешней печатной формы). Я указал длину 250.

// ----------------------------------------------------------------------------
&НаСервере
Процедура ЗаполнитьСписокМетаданных(Фильтр = Неопределено)
	
	СписокМакетовДерево = РеквизитФормыВЗначение("СписокМакетов");
	
	ЗаполнитьДеревоПоКоллекцииМетаданных(СписокМакетовДерево, Метаданные.Справочники, Ложь, Фильтр);
	ЗаполнитьДеревоПоКоллекцииМетаданных(СписокМакетовДерево, Метаданные.Документы, Ложь, Фильтр);
	ЗаполнитьДеревоПоКоллекцииМетаданных(СписокМакетовДерево, Метаданные.Обработки, Ложь);
	ЗаполнитьДеревоПоКоллекцииМетаданных(СписокМакетовДерево, Метаданные.ОбщиеМакеты, Истина);
	
	// Miha
	ЗапросВПФ = Новый Запрос;
	ЗапросВПФ.Текст =
	"ВЫБРАТЬ
 | ВнешниеОбработки.Ссылка,
 | ВнешниеОбработки.Наименование,
 | ВнешниеОбработки.ХранилищеВнешнейОбработки
 |ИЗ
 | Справочник.ВнешниеОбработки КАК ВнешниеОбработки
 |ГДЕ
 | ВнешниеОбработки.ВидОбработки = ЗНАЧЕНИЕ(Перечисление.ВидыДополнительныхВнешнихОбработок.ПечатнаяФорма)
 | И НЕ ВнешниеОбработки.ПометкаУдаления
 | И НЕ ВнешниеОбработки.ЭтоГруппа";
	Выборка = ЗапросВПФ.Выполнить().Выбрать();
	Пока Выборка.Следующий() Цикл
		ОбработкаEPF = Выборка.ХранилищеВнешнейОбработки.Получить();
		ИмяВременногоФайла = ПолучитьИмяВременногоФайла("epf");
		ОбработкаEPF.Записать(ИмяВременногоФайла);
		ВнешОбработка = ВнешниеОбработки.Создать(ИмяВременногоФайла);
		ДобавитьКоллекциюМакетов(ВнешОбработка.Метаданные().Макеты,
			СписокМакетовДерево,
			"Справочники.ВнешниеОбработки/"+Выборка.Ссылка.УникальныйИдентификатор()+"#",
			Выборка.Наименование,
			Фильтр);
	КонецЦикла;
	// Miha - End
	
	Если СписокМакетовДерево.Строки.Количество() > 0 Тогда

// ----------------------------------------------------------------------------

2. Чтобы появилась возможность получить для редактирования макет из ВПФ и сохранить его в наш регистр, надо доработать общий модуль УправлениеПечатью.

// --------------------------------------------------------------------------
Функция ПолучитьМакет(ПолныйПутьКМакету) Экспорт
	
	ЧастиПути = СтрЗаменить(ПолныйПутьКМакету, ".", Символы.ПС);
	
	Если СтрЧислоСтрок(ЧастиПути) = 3 Тогда
		
	// Miha
        Если Лев(ПолныйПутьКМакету,12) = "Справочники." Тогда
            абПозиция=Найти(ПолныйПутьКМакету,"/");
            абПозиция1=Найти(ПолныйПутьКМакету,"#");;
            Если абПозиция<>0 Тогда
                СтрокаУИД=Сред(ПолныйПутьКМакету,абПозиция+1,абПозиция1-абПозиция-1);
                УИД=Новый УникальныйИдентификатор(СтрокаУИД);
                абОбъект=Справочники.ВнешниеОбработки.ПолучитьСсылку(УИД);

                Запрос = Новый Запрос;
                Запрос.Текст =
                    "ВЫБРАТЬ
 | ПользовательскиеМакетыПечати.ИмяМакета,
 | ПользовательскиеМакетыПечати.Объект,
 | ПользовательскиеМакетыПечати.Макет,
 | ПользовательскиеМакетыПечати.Использование
 |ИЗ
 | РегистрСведений.ПользовательскиеМакетыПечати КАК ПользовательскиеМакетыПечати
 |ГДЕ
 | ПользовательскиеМакетыПечати.Объект ПОДОБНО &Объект";

                Запрос.УстановитьПараметр("Объект", "%"+СтрокаУИД+"%");

                Результат = Запрос.Выполнить();

                ВыборкаДетальныеЗаписи = Результат.Выбрать();

                Если ВыборкаДетальныеЗаписи.Следующий() Тогда
                    абМакет=ВыборкаДетальныеЗаписи.Макет.Получить();
                    Результат = ПолучитьТабличныйДокументПоДвоичнымДанным(абМакет);
                    Возврат Результат;
                Иначе
                    Если абОбъект<>Справочники.ВнешниеОбработки.ПустаяСсылка() Тогда
                        абОбработкаEPF=абОбъект.ХранилищеВнешнейОбработки.Получить();
                        ИмяВременногоФайла = ПолучитьИмяВременногоФайла();
                        абОбработкаEPF.Записать(ИмяВременногоФайла);
                        абОбработка=ВнешниеОбработки.Создать(ИмяВременногоФайла);
                        абМакет=абОбработка.ПолучитьМакет(СтрПолучитьСтроку(ЧастиПути, 3));
                        Возврат  абМакет;
                    КонецЕсли;
                КонецЕсли;
            КонецЕсли;
        Иначе
            ПутьКМетаданным = СтрПолучитьСтроку(ЧастиПути, 1) + "." + СтрПолучитьСтроку(ЧастиПути, 2);
            ПутьКОбъектуМетаданных = СтрПолучитьСтроку(ЧастиПути, 3);
        КонецЕсли;
        //ПутьКМетаданным = СтрПолучитьСтроку(ЧастиПути, 1) + "." + СтрПолучитьСтроку(ЧастиПути, 2);
        //ПутьКОбъектуМетаданных = СтрПолучитьСтроку(ЧастиПути, 3);
        // Miha - End 
		
	ИначеЕсли СтрЧислоСтрок(ЧастиПути) = 2 Тогда
		ПутьКМетаданным = СтрПолучитьСтроку(ЧастиПути, 1);
		ПутьКОбъектуМетаданных = СтрПолучитьСтроку(ЧастиПути, 2);
	Иначе
		ВызватьИсключение СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр("ru = 'Макет ""%1"" не найден. Операция прервана.'"), ПолныйПутьКМакету);
	КонецЕсли;
// --------------------------------------------------------------------------

3. Также понадобится передавать во внешнюю обработку параметр со ссылкой на элемент справочника "Внешние обработки", чтобы ВПФ могла найти свой пользовательский макет в регистре. Для этого правим общий модуль УниверсальныеМеханизмы.

// --------------------------------------------------------------------------
Функция НапечататьВнешнююФорму(Ссылка, ИсточникМакета) Экспорт
	
	Перем ДополнительныеПараметры;
	
	ДвоичныеДанные = ИсточникМакета.СсылкаНаВнешнююОбработку.Принадлежность[ИсточникМакета.НомерСтроки - 1].ХранилищеВнешнейОбработки.Получить();
	
	// Получить дополнительные параметры внешней обработки
	ИсточникМакета.Свойство("ДополнительныеПараметрыОбработки", ДополнительныеПараметры);
	
	// Miha
	Если ДополнительныеПараметры = Неопределено Тогда
		ДополнительныеПараметры = Новый Структура;
	КонецЕсли;
	ДополнительныеПараметры.Вставить("СсылкаНаВнешнююОбработку", ИсточникМакета.СсылкаНаВнешнююОбработку);
	// Miha - End

// --------------------------------------------------------------------------

На этом изменения в конфигураторе завершены. Остальные изменения можно делать непосредственно в файлах ВПФ.

4. Во-первых, понадобится добавить реквизит ДополнительныеПараметры с типом Произвольный.

5. В названии макетов должно быть одно из сочетаний: ПФ_MXL, ПФ_DOC или ПФ_ODT. Это проверяется встроенной подсистемой.

6. Когда получаем макет, вместо стандартного ПолучитьМакет вызываем функцию МСК_ПолучитьМакет. Нужный код приведен ниже.

// --------------------------------------------------------------------------
Функция МСК_ПолучитьМакет(ИмяМакета)
	СтрокаУИД=Строка(ДополнительныеПараметры.СсылкаНаВнешнююОбработку.УникальныйИдентификатор());

	Запрос = Новый Запрос;
	Запрос.Текст =
	"ВЫБРАТЬ
 | ПользовательскиеМакетыПечати.ИмяМакета,
 | ПользовательскиеМакетыПечати.Объект,
 | ПользовательскиеМакетыПечати.Макет
 |ИЗ
 | РегистрСведений.ПользовательскиеМакетыПечати КАК ПользовательскиеМакетыПечати
 |ГДЕ
 | ПользовательскиеМакетыПечати.Объект ПОДОБНО &amp;Объект
 | И ПользовательскиеМакетыПечати.Использование";

	Запрос.УстановитьПараметр("Объект", "%"+СтрокаУИД+"%");

	Результат = Запрос.Выполнить();

	ВыборкаДетальныеЗаписи = Результат.Выбрать();

	Если ВыборкаДетальныеЗаписи.Следующий() Тогда
	    ДвМакет=ВыборкаДетальныеЗаписи.Макет.Получить();
	    ИспользуемыйМакет = ПолучитьТабличныйДокументПоДвоичнымДанным(ДвМакет);
	Иначе
		ИспользуемыйМакет = ПолучитьМакет(ИмяМакета);
	КонецЕсли;

	Возврат ИспользуемыйМакет;
	
КонецФункции
// --------------------------------------------------------------------------
Функция ПолучитьТабличныйДокументПоДвоичнымДанным(ДвоичныеДанные) Экспорт

    ИмяВременногоФайла = ПолучитьИмяВременногоФайла();
    ДвоичныеДанные.Записать(ИмяВременногоФайла);
    ТабличныйДокумент = Новый ТабличныйДокумент;
    ТабличныйДокумент.Прочитать(ИмяВременногоФайла);

    Возврат ТабличныйДокумент;

КонецФункции
// --------------------------------------------------------------------------

 

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

Скачать файлы

Наименование Файл Версия Размер Кол. Скачив.
Внешняя печатная форма
.epf 6,12Kb
18.11.15
1
.epf 6,12Kb 1 Скачать

См. также

Подписаться Добавить вознаграждение
В этой теме еще нет сообщений.
Для написания сообщения необходимо авторизоваться
Прикрепить файл
Дополнительные параметры ответа