БСП: Дополнительные отчеты и обработки - одна обработка, несколько форм

Публикация № 1099952

Разработка - Практика программирования

РЗ Регламентное задание БСП Дополнительные обработки Отладка Обработка отчеты и формы расширения ИзменениеИКонтроль вместо

36
Как в одной дополнительной обработке разместить несколько форм с типом команды "ОткрытиеФормы"?

Вопрос к статье БСП: Дополнительная обработка (Регламенты), примеры от простого к сложному

user_2010: Можно ли сделать так, чтобы у обработки было регл задание и две формы - работающие по-разному?

Для чего это может понадобиться?

1) Допустим, вы решили складировать все регламенты и настройки для них в одной обработке. Соответственно ваша форма для этой обработки становится все больше и страшнее. Вам придётся  что-то скрывать\показывать.

2) Вы собираете форму программно и вдруг заметили, что код по формированию уже стал километровым.

3) У Вас есть универсальные Процедуры\Функции, вы их держите в модуле обработки и вам нужны разные формы для работы с этими процедурами\функциями.

Мысли вслух:

Сам лично я живу с одной формой и мог бы просто ответить не предусмотрено и приложить кусок кода из БСП:

 
Код вывода формы: ДополнительныеОтчетыИОбработкиКлиент.ВыполнитьОткрытиеФормыОбработки 
// Открывает форму обработки.
Процедура ВыполнитьОткрытиеФормыОбработки(ВыполняемаяКоманда, Форма, ОбъектыНазначения) Экспорт
	ПараметрыОбработки = Новый Структура("ИдентификаторКоманды, ДополнительнаяОбработкаСсылка, ИмяФормы, КлючСессии");
	ПараметрыОбработки.ИдентификаторКоманды          = ВыполняемаяКоманда.Идентификатор;
	ПараметрыОбработки.ДополнительнаяОбработкаСсылка = ВыполняемаяКоманда.Ссылка;
	ПараметрыОбработки.ИмяФормы                      = ?(Форма = Неопределено, Неопределено, Форма.ИмяФормы);
	ПараметрыОбработки.КлючСессии = ВыполняемаяКоманда.Ссылка.УникальныйИдентификатор();
	
	Если ТипЗнч(ОбъектыНазначения) = Тип("Массив") Тогда
		ПараметрыОбработки.Вставить("ОбъектыНазначения", ОбъектыНазначения);
	КонецЕсли;
	
	#Если ТолстыйКлиентОбычноеПриложение Тогда
		ВнешняяОбработка = ДополнительныеОтчетыИОбработкиВызовСервера.ПолучитьОбъектВнешнейОбработки(ВыполняемаяКоманда.Ссылка);
		ФормаОбработки = ВнешняяОбработка.ПолучитьФорму(, Форма);
		Если ФормаОбработки = Неопределено Тогда
			ВызватьИсключение СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
				НСтр("ru = 'Для отчета или обработки ""%1"" не назначена основная форма,
				|или основная форма не предназначена для запуска в обычном приложении.
				|Команда ""%2"" не может быть выполнена.'"),
				Строка(ВыполняемаяКоманда.Ссылка),
				ВыполняемаяКоманда.Представление);
		КонецЕсли;
		ФормаОбработки.Открыть();
		ФормаОбработки = Неопределено;
	#Иначе
		ИмяОбработки = ДополнительныеОтчетыИОбработкиВызовСервера.ПодключитьВнешнююОбработку(ВыполняемаяКоманда.Ссылка);
		Если ВыполняемаяКоманда.ЭтоОтчет Тогда
			ОткрытьФорму("ВнешнийОтчет."+ ИмяОбработки +".Форма", ПараметрыОбработки, Форма);
		Иначе
			ОткрытьФорму("ВнешняяОбработка."+ ИмяОбработки +".Форма", ПараметрыОбработки, Форма);
		КонецЕсли;
	#КонецЕсли
КонецПроцедуры

Сам ответ кроется тут: ОткрытьФорму("ВнешняяОбработка."+ ИмяОбработки +".Форма", ПараметрыОбработки, Форма);

В описании функции ДополнительныеОтчетыИОбработкиКлиентСервер.ТипКомандыОткрытиеФормы написано следующее:

// Возвращает имя типа команд по открытию формы. При выполнении этих команд
//   открывается основная форма внешнего объекта с указанными ниже параметрами.

То есть открывается форма которая определена в обработке.

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

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

Такой ответ был бы прост, но...

С другой стороны:

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

-Есть возможность добавлять формы.

-Есть возможность добавлять несколько команд с открытием формы.

// Возвращает сведения о внешней обработке.
Функция СведенияОВнешнейОбработке() Экспорт
	
	ПараметрыРегистрации = ДополнительныеОтчетыИОбработки.СведенияОВнешнейОбработке("2.4.5.71");
	ПараметрыРегистрации.Вставить("БезопасныйРежим", Ложь);
	
	ПараметрыРегистрации.Вид = ДополнительныеОтчетыИОбработкиКлиентСервер.ВидОбработкиДополнительнаяОбработка();
	ПараметрыРегистрации.Версия = "1.0.08";
	
	//Открываем форму "Форма"
	НоваяКоманда = ПараметрыРегистрации.Команды.Добавить();
	НоваяКоманда.Представление = НСтр("ru = 'Форма задач по регламентам'");
	НоваяКоманда.Идентификатор = "НастроитьИВыполнитьЗадачиВручную";
	НоваяКоманда.Использование = ДополнительныеОтчетыИОбработкиКлиентСервер.ТипКомандыОткрытиеФормы();
	НоваяКоманда.ПоказыватьОповещение = Ложь;
	
	//Открываем форму "Форма1"
	НоваяКоманда = ПараметрыРегистрации.Команды.Добавить();
	НоваяКоманда.Представление = НСтр("ru = 'Форма 1'");
	НоваяКоманда.Идентификатор = "ОткрытьФорму1";
	НоваяКоманда.Использование = ДополнительныеОтчетыИОбработкиКлиентСервер.ТипКомандыОткрытиеФормы();
	НоваяКоманда.ПоказыватьОповещение = Ложь;
	
	//Открываем форму "Форма2"
	НоваяКоманда = ПараметрыРегистрации.Команды.Добавить();
	НоваяКоманда.Представление = НСтр("ru = 'Форма 2'");
	НоваяКоманда.Идентификатор = "ОткрытьФорму2";
	НоваяКоманда.Использование = ДополнительныеОтчетыИОбработкиКлиентСервер.ТипКомандыОткрытиеФормы();
	НоваяКоманда.ПоказыватьОповещение = Ложь;

	
	//...

	Возврат ПараметрыРегистрации;
	
КонецФункции

 

В итоге на работе в пятницу час перед уходом сидел и баловался с кодом. По принципу "придумать минимум два решения".

 

На первый взгляд, задача сводится к тому, что нужно заменить вот этот злополучный кусок кода:

ОткрытьФорму("ВнешняяОбработка."+ ИмяОбработки +".Форма", ПараметрыОбработки, Форма);

На что его менять?

У нас есть Идентификатор команды с помощью этого идентификатора можно было бы передать название формы:

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

 

ОткрытьФорму("ВнешняяОбработка." + ИмяОбработки + ".Форма"
                                              
+ ?(Лев(ПараметрыОбработки.ИдентификаторКоманды,1)=".",
  ПараметрыОбработки.ИдентификаторКоманды,
  "." + ПараметрыОбработки.ИдентификаторКоманды)
                                              
, ПараметрыОбработки, Форма);

Можно использовать ВыполняемаяКоманда.Модификатор и загнать сюда название формы:

 
 Модификатор для справки
//           ** Модификатор - Строка - Дополнительная классификация команды.
//               Для внешних печатных форм (когда Вид = "ПечатнаяФорма"):
//                 *** "ПечатьMXL" - для печатных форм на основе табличных макетов.
//               Для загрузки данных из файла (когда Вид = "ПечатнаяФорма" и Использование = "ЗагрузкаДанныхИзФайла"):
//                 Модификатор является обязательным для заполнения
//                 и должен содержать полное имя объекта метаданных (справочника),
//                 для которого выполняется загрузка данных.

 Как мы видим он занят только для команды с типом "ПечатнаяФорма", следовательно можно для команды "ОткрытиеФормы" использовать его как контейнер для названия формы

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

 

ОткрытьФорму("ВнешняяОбработка." + ИмяОбработки + ".Форма"
                                              
+ ?(ПустаяСтрока(ВыполняемаяКоманда.Модификатор),"",
   ?(Лев(ВыполняемаяКоманда.Модификатор,1)=".",
   ВыполняемаяКоманда.Модификатор,
   "." + ВыполняемаяКоманда.Модификатор))

, ПараметрыОбработки, Форма);

 

А давайте сделаем!!!

1 Для примера я взял обработку из статьи БСП: Дополнительная обработка (Регламенты), примеры от простого к сложному

2 Добавил формы с надписью которая говорит какая форма открыта

3 Скачал БСП 3.0.3.48 и развернул демо конфигурацию (Для примера 1.1) использовал платформу 8.3.12.1685

 

Вариант 1.1 Расширение конфигурации (Аннотация - &Вместо). Подходит для платформы от 8.3.9 или режима совместимости 8.3.9

А] Форму передаем через Идентификатор

 
 Функция СведенияОВнешнейОбработке() Экспорт

Создал расширение upBSP:

Добавил в расширение модуль ДополнительныеОтчетыИОбработкиКлиент

 
 Код модуля ДополнительныеОтчетыИОбработкиКлиент расширение

 

Собственно все, пробуем и радуемся!

 

Тут я подумал: - А почему мы должны открывать только формы обработки?

Б] Форму передаем через Модификатор

В Модификатор команды мы будем писать либо название формы, либо путь к форме объекта конфигурации.

Когда мы пишем путь к объекту конфигурации в идентификатор команды добавляем кодовый ключ "upBSP".

 
 Функция СведенияОВнешнейОбработке() Экспорт
 
 Код модуля ДополнительныеОтчетыИОбработкиКлиент расширение

 

Собственно все, пробуем и радуемся!

 

Тут я подумал: - А почему мы вообще должны использовать расширения и ключ "upBSP"?

Вариант 2 Когда я придумал этот вариант... Сам себе сказал: -Да вы, батенька, извращенец! 

После чего решил его сделать и остановится... Мало ли, что еще в голову придет...

!!!Слабонервным просьба не читать!!!

1 В обработке создаем форму "ФормаРаспределения" и прописываем ее как основную форму.

2 В Функции СведенияОВнешнейОбработке просто описываем команды, без извращений. Как обычно.

 
 Функция СведенияОВнешнейОбработке() Экспорт

3 В форме "ФормаРаспределения" добавляем немного кода

 
 Весь код формы

 

&НаСервереБезКонтекста
Функция ПолучитьФормуПоИндентификатору(ИдентификаторКоманды)
	
	//...	Тут прописываем соответствие форм и идентификаторов
	
КонецФункции

 

Собственно все, пробуем и радуемся!

 

Ответ полученный в ходе пятничного часа: Заложено в БСП не было, но сделать можно.

Можно сделать с расширением и можно сделать без расширения.

 

ПС. Еще раз большое спасибо user_2010 за вопрос. Пятница была скрашена!

Все материалы выложены в статье БСП: Дополнительная обработка (Регламенты), примеры от простого к сложному единым архивом.

36

См. также

Специальные предложения

Комментарии
Избранное Подписка Сортировка: Древо
1. A_Max 17 29.07.19 13:53 Сейчас в теме
Первым в голову пришёл именно второй вариант с формой маршрутизатором, ничего крамольного в нём не вижу.
fvadim; eden_gmail; ltfriend; +3 Ответить
2. dsdred 1184 29.07.19 13:57 Сейчас в теме
(1)Ну не знаю, мне как то не по душе ))
3. A_Max 17 29.07.19 15:12 Сейчас в теме
(2) До того как появилась возможность переопределения форм (ОбработкаПолученияФормы) в типовых конфигурациях повсеместно использовалось для документов.
4. KazanKokos 8 30.07.19 09:38 Сейчас в теме
помню форму sbis - отчетности для УТ11.2 построенную на формах вроде по такому же алгоритму. Помню был гимор. Сам считаю что стиль это как нотация - привыкаешь к стилю типовых 1Сок и не паришься не выдумываешь всякую фигню :)
5. ltfriend 377 30.07.19 10:31 Сейчас в теме
Именно второй вариант первый и приходит на ум, вместо того, чтобы лезть и менять код БСП. Что в нём извращённого? Только я использовал бы тип команды "Вызов клиентского метода". Тогда в модуле основной формы достаточно одной процедуры вместо двух ("ПриСозданииНаСервере" и "ПриОткрытии").
Создаётся пустая форма без всяких реквизитов и параметров и в модуле этой формы прописывается код:
&НаКлиенте
Процедура ВыполнитьКоманду(ИдентификаторКоманды) Экспорт
    НазваниеФормы = ПолучитьФормуПоИндентификатору(ИдентификаторКоманды);
    ОткрытьФорму(НазваниеФормы);
КонецПроцедуры
6. dsdred 1184 30.07.19 13:03 Сейчас в теме
(5)мне честно говорю не очень нравится ))

Я сделал
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
		
	НазваниеФормы = ПолучитьФормуПоИндентификатору(Параметры.ИдентификаторКоманды);	

	//Если нужны еще параметры дописываем тут
	ПараметрыОбработки = Новый Структура("ИдентификаторКоманды, ДополнительнаяОбработкаСсылка, ИмяФормы, КлючСессии");
	ПараметрыОбработки.ИдентификаторКоманды          = Параметры.ИдентификаторКоманды;
	ПараметрыОбработки.ДополнительнаяОбработкаСсылка = Параметры.ДополнительнаяОбработкаСсылка;
	ПараметрыОбработки.ИмяФормы   = Параметры.ИмяФормы;
	ПараметрыОбработки.КлючСессии = Параметры.КлючСессии;
		
КонецПроцедуры
Показать
и
ОткрытьФорму(НазваниеФормы, ПараметрыОбработки,ВладелецФормы);


Чтобы полностью имитировать Процедура ВыполнитьОткрытиеФормыОбработки

Процедура ВыполнитьОткрытиеФормыОбработки(ВыполняемаяКоманда, Форма, ОбъектыНазначения) Экспорт
	ПараметрыОбработки = Новый Структура("ИдентификаторКоманды, ДополнительнаяОбработкаСсылка, ИмяФормы, КлючСессии");
	ПараметрыОбработки.ИдентификаторКоманды          = ВыполняемаяКоманда.Идентификатор;
	ПараметрыОбработки.ДополнительнаяОбработкаСсылка = ВыполняемаяКоманда.Ссылка;
	ПараметрыОбработки.ИмяФормы                      = ?(Форма = Неопределено, Неопределено, Форма.ИмяФормы);
	ПараметрыОбработки.КлючСессии = ВыполняемаяКоманда.Ссылка.УникальныйИдентификатор();

//...

	ОткрытьФорму("ВнешняяОбработка."+ ИмяОбработки +".Форма", ПараметрыОбработки, Форма);

//...
Показать


Но еще раз повторюсь, решение мне не нравится. Но это сугубо мое ощущение.
Оставьте свое сообщение