Страница 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!!!
Аналогично и успехов!