Страница 1 из 1
					
				Как вызвать динамично Routine
				Добавлено: 18 Март 2016, 17:48
				 Tuko_G
				Добрый день!
есть в файле записи где храняеться имени Routine. (напр: 100) есть ли возможность визвать из программи ети Routine и?
Rout_Name
a1
a2
a3
....
сделал Get(file,i) - прочитал 1 ую запись (a1) , и хочу сделать: Do a1; и так далее. Есть ли возможность? с Bind ом не смог(или неправильно сделал)
P.S.
можно и процедуру 
 
Спасибо
с уважением
Гиоргий
 
			 
			
					
				Как вызвать динамично Routine
				Добавлено: 18 Март 2016, 21:03
				 Yufil
				С процедурой никаких особых проблем нет, читай про команду Evaluate()
			 
			
					
				Как вызвать динамично Routine
				Добавлено: 19 Март 2016, 7:11
				 Игорь Столяров
				Согласен, Evaluate() не сможет выполнить команду вроде Evaluate('Do MyRoutine').
Препроцессор просто не знает куда передать управление ....
Нужно преобразовать Routine в процедуры, описать процедуры в Map, считывать имена процедур, биндить имя с описанием процедуры и тогда уже вызывать по имени через Evaluate(). Я так думаю.
			 
			
					
				Как вызвать динамично Routine
				Добавлено: 19 Март 2016, 8:12
				 Larion
				Код: Выделить всё
  Case Clip(Rout_Name)
               OF 'a1'
               DO a1
               OF 'a2'
               DO a2
               ...
               END
               
Может так
 
			 
			
					
				Как вызвать динамично Routine
				Добавлено: 19 Март 2016, 12:13
				 Tuko_G
				Да через case все ясно Larion но 1) медленный 2) не удобно когда 200+ case.
пробовал и через Procedure и Evaluate с Bind ом Игорь, но не хочет. (1010 – Illegal Expression bla bla)
может кто нибуть показать рабочий пример?  clarion 6.3
			 
			
					
				Как вызвать динамично Routine
				Добавлено: 19 Март 2016, 13:01
				 RaFaeL
				Еще есть вариант с magic numbers и execute
			 
			
					
				Как вызвать динамично Routine
				Добавлено: 19 Март 2016, 17:32
				 Yufil
				С Routine вряд ли чего выйдет. А вот процедуры можно вызывать по адресу, составить таблицу "имя процедуры-адрес процедуры", в таблице находить адрес - и вызывать.  Особенно полезно для реализации всяких плагинов, аддонов и прочее 
Кусок из реальной программы 
Я хочу по адресу вызывать процедуру типа 
procedure(string) 
Сначала описал её тип. 
Потом написал вызывалку этой процедуры 
Код: Выделить всё
CallProc               PROCEDURE(StrProc P,String S)   !Вызов процедуры по адресу
                           P(S) 
                           RETURN 
Потом в map  включил "двойника" 
Код: Выделить всё
CallStrProc(Long,String),Name('CALLPROC@F7STRPROCSB')
Волшебное имя справа можно подсмотреть с map-файле, например.  
Или найти в Examples\Src\Pro2exp программу, которая поможет 
Теперь CallProc и CallStrProc - одна и та же программа, но CallStrProc принимает в качестве первого параметра адрес процедуры. 
Ну а дальше всё просто 
Код: Выделить всё
ProcQ   Queue, Pre(ProcQ)
Addr     Long 
id         Cstring(10)
           End 
... 
Регистрим процедуры 
 
Код: Выделить всё
          ProcQ.Id = 'a1'; ProcQ:addr = Address(a1) ; Add(ProcQ)
           ProcQ.Id = 'a2'; ProcQ:addr = Address(a2) ; Add(ProcQ)
           ProcQ.Id = 'a3'; ProcQ:addr = Address(a3) ; Add(ProcQ)
... 
И вызываем 
Код: Выделить всё
 ProcQ.id = 'a1'; get(ProcQ,+ProcQ:Id); CallStrProc(ProcQ.Addr, ....)  
 
Есть и более простой способ реализации - по Over наложить адрес и ссылку на процедуру, но мне так кажется яснее.
 
			 
			
					
				Как вызвать динамично Routine
				Добавлено: 20 Март 2016, 21:13
				 Shur
				Если немного покорпеть над языком шаблонов, то может получиться вот такой шаблончик:
Код: Выделить всё
#!CallSerialRoutines.tpl
#TEMPLATE(CallSerialRoutines,'CallSerialRoutines'),FAMILY('ABC','CW20','Clarion')
#EXTENSION(CallSerialRoutines,'CallSerialRoutines'),PROCEDURE,MULTI
#BOXED('Copyright (c) 2016 ...')
  #DISPLAY ('This template realizes serial routines calls')
#ENDBOXED
#SHEET
  #TAB('&General')
#PROMPT('Enable',CHECK),%CallSerialRoutineEnable, AT(10,30)
    #ENABLE(%CallSerialRoutineEnable=%TRUE)
#PROMPT('Routine List',@s20),%Routines,UNIQUE,MULTI('Input Values...'), AT(10,45)
    #ENDENABLE
  #ENDTAB
#ENDSHEET
#!-------------------------------------------------------------------------------------------------------------------
#AT(%DataSection)
   #IF(%CallSerialRoutineEnable)
LOC:SerialRoutine STRING(80) #<! Use this variable before DOing of CallSerialRoutines routine  
   #ENDIF
#ENDAT
#AT(%ProcedureRoutines)
   #IF(%CallSerialRoutineEnable)
CallSerialRoutines ROUTINE
   CASE LOC:SerialRoutine
      #FOR(%Routines)
   OF '%Routines'; DO %Routines
      #ENDFOR
   END !CASE
   #ENDIF
#ENDAT
#!-------------------------------------------------------------------------------------------------------------------
Остаётся его сохранить в папке Templates, зарегистрировать в Template Registry, добавить в необходимую процедуру в качестве Extension, набить в него 100 имен вызываемых рутинок и - вуаля - всё заработает. 
Может быть вам так проще?
 
			 
			
					
				Как вызвать динамично Routine
				Добавлено: 21 Март 2016, 14:45
				 Tuko_G
				Спасибо Большое всем за Feedback.  
 
P.S.
Особенно Shur!!!
 
			 
			
					
				Как вызвать динамично Routine
				Добавлено: 21 Март 2016, 15:02
				 Shur
				Tuko_G писал(а): Спасибо Большое всем за Feedback.  
 
P.S.
Особенно Shur!!!
 
Аналогично и успехов!