Форум » LetoDB, HbNetio. » Странности с letoudf » Ответить

Странности с letoudf

PSP: А может я туплю. Вот имеем два варианта: 1. [pre2] #define WA &( cAlias ) FUNCTION udfDocLoad( nUserStru, cAlias, d1, cOrd, cSeek ) LOCAL aDat := {} LOCAL cOrdSave LOCAL bSeek cAlias := leto_Alias( nUserStru, cAlias ) bSeek := &( "{ || " + cSeek + "}" ) cOrdSave := WA->( OrdSetFocus( cOrd ) ) WA->( dbGoTop() ) WA->( Eval( bSeek ) ) // не срабатывает ... ... ... RETURN aDat [/pre2] 2. [pre2] #define WA &( cAlias ) FUNCTION udfDocLoad( nUserStru, cAlias, d1, cOrd, cSeek ) LOCAL aDat := {} LOCAL cOrdSave LOCAL bSeek cAlias := leto_Alias( nUserStru, cAlias ) //bSeek := &( "{ || " + cSeek + "}" ) cOrdSave := WA->( OrdSetFocus( cOrd ) ) WA->( dbGoTop() ) WA->( dbSeek( DtoS( d1 ), .T. ) ) // срабатывает ... ... ... RETURN aDat [/pre2] Параметры: d1 - дата, cOrd - строка cSeek - строка вида "dbSeek( DtoS( d1 ), .T. )" Так вот: - в первом варианте udf-функция прерывается по ошибке на строке "WA->( Eval( bSeek ) )", а логе появляется запись "Error BASE/1003 Variable does not exist: D1" - во втором варианте всё работает без вопросов. Как это понимать? ps. Проверил на всякий случай leto_UDFExist( "Eval" ). Вернула .T.

Ответов - 21, стр: 1 2 All

SergKis: PSP пишет:cSeek - строка вида "dbSeek( DtoS( d1 ), .T. )" d1 - из параметров - локальная переменная, а Вы ее в макро

PSP: SergKis пишет: d1 - из параметров - локальная переменная, а Вы ее в макро cAlias - тоже из параметров и тоже локальная, но работает. И точно такой же код работает в обычной программе. Вот, не придумываю ))) 2010-07-08 12:35 UTC+0200 Przemyslaw Czerpak (druzus/at/priv.onet.pl) * harbour/include/hbpp.h * harbour/include/hbmacro.h * harbour/include/hbcomp.h * harbour/include/hbcompdf.h * harbour/include/hbexprb.c * harbour/src/pp/ppcore.c * harbour/src/compiler/hbmain.c * harbour/src/vm/macro.c ! fixed code used to decide about early and late macro evaluation in codeblocks to be exactly Clipper compatible. Now if codeblock contains at least one macro variable (i.e.: &var, any&var, any&var.2) then it's always early evaluated. Please remember that codeblocks which contains only simple macro variable ( &var[.] ), i.e.: {|| &var } are modified during compilation by Clipper and Harbour compilers to: &( "{||" + var + "}" ) and then PCODE is generated. It allows to use LOCALs, STATICs and FIELDs as 'var' in such expressions.

SergKis: если сделать PRIV D2 := d1 cSeek := "dbSeek( DtoS( D2 ), .T. )" bSeek := &( "{ || " + cSeek + "}" ) заработает, а с алиасом, наверно, срабатывает результат WA (ppo надо смотреть для точности) (cAlias)->(...) т.е. WA можно совсем выкинуть


PSP: Я проверю, конечно. Только вот не грузит сервер letodb .hrb-шник, если есть PRIVATE переменная. Орёт "Error BASE/6101 Unknown or unregistered symbol: __MVPRIVATE"

SergKis: PSP пишет:Вот, не придумываю верю, но ранее локальные переменные не имели имен, а у Вас в выражении (в строке) по макро - обращение через имя.

SergKis: PSP пишет:Орёт REQUEST в prg сервера добавьте на список функций __MV....

PSP: SergKis пишет: но ранее локальные переменные не имели имен, а у Вас в выражении (в строке) по макро - обращение через имя. Что-то я не понял, о чём вы. Там блок кода генерится. Причем, видимо, успешно. А когда на выполнение отправляется, выясняется, что переменной d1 почему-то нет.

SergKis: PSP пишет:Я проверю, конечно можно попробовать сделать cSeek := StrTran(cSeek, 'd1', "["+DtoS(d1)+"]") bSeek := &( "{ || " + cSeek + "}" )

Pasha: Можно все упростить. cAlias передавать не надо, т.к. leto_udf выполняется по текущему алиасу. d1 передавать не надо, т.к. это аргумент строки cSeek, и его можно заполнять на клиенте. Примерно так: на клиенте: select(cAlias) leto_udf("udfDocLoad", cOrd, "dbSeek("+DTOS(d1)+", .t.)") на сервере: FUNCTION udfDocLoad( nUserStru, cOrd, cSeek ) LOCAL aDat := {} LOCAL cOrdSave LOCAL bSeek OrdSetFocus( cOrd ) bSeek := &( "{ || " + cSeek + "}" ) Eval( bSeek ) ... ... ... RETURN aDat

SergKis: PSP пишет:Там блок кода генерится генерится через macro bSeek := &( "{ || " + cSeek + "}" ) , а не bSeek := {|| dbSeek( DtoS( d1 ), .T. ) } в таком виде сработает eval

PSP: Вот, что выяснилось: при использовании PRIVATE, а также в Пашином варианте на отсутствие переменной не ругается, но и то, что требовалось от Eval(), т.е. поиск, не достигается: Found() == .F. Почему-то я сразу не додумался проверить, а когда проверил, оказалось, что блок кода == NIL!!! О как! ))) Более того, если его сформировать на клиенте и передать в udf в качестве параметра, в теле udf-функции этот параметр тоже будет равен NIL. Вот как-то так... ))) Может кто-то что-то подсказать по этому поводу? Чего letodb.exe не хватает? update: А можно ли вообще блоки кода использовать в .hrb модулях?

SergKis: PSP пишет: А можно ли вообще блоки кода использовать в .hrb модулях? Все работает в hrb, при наличии requst в exe, использую во многих местах, не letodb, как решение разных алгоритмов для клиентов, а exe один. Проверить что в параметрах udf можно WrLog(ProcName()+" "+hb_valtoexp({nUserStru, cAlias, d1, cOrd, cSeek})) Pasha пишет:select(cAlias) leto_udf("udfDocLoad", cOrd, "dbSeek("+DTOS(d1)+", .t.)") не хватает кавычек "dbSeek(["+DTOS(d1)+"], .t.)"

Pasha: Переменные передаются на сервер посредством serialize/deserialize, а там блоки кода не поддерживаются. Да и это в принципе невозможно, т.к. блок кода может содержать ссылки на локальные переменные клиента, а к ним доступа на сервере нет. Ну а создание блока кода на сервере bSeek := &( "{ || " + cSeek + "}" ) должно работать, если конечно cSeek корректно написано, и не содержит ошибок, скажем, синтаксических А кавычки да, я пропустил. Можно так: 'dbSeek("'+DTOS(d1)+'", .t.)'

PSP: Да видел я, что кавычек нет. Ну, "не выходит каменный цветок"!!! ))) Ладно, спасибо за помощь.

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

PSP: Pasha пишет: Может я неточно написал. В hrb конечно можно использовать блоки кода, как и любые другие средства языка. Их нельзя передавать с клиента в качестве параметра для udf-функции. Нет, Паш, всё предельно понятно. Спасибо большое! SergKis, Сергей, и вам спасибо! ))

PSP: Паша, а leto_Alias() меняет ли в процессе своего выполнения текущую рабочую область? Если да, то восстанавливает ли ту, которая была до ее вызова?

SergKis: PSP select(cAlias) leto_udf("udfDocLoad", cOrd, DTOS(d1)) FUNCTION udfDocLoad( nUserStru, cOrd, cDate) LOCAL aDat := {} leto_SetEnv( cDate, cDate, cOrd ) dbGotop() .... leto_ClearEnv( .T., .T. ) RETURN aDat

PSP: SergKis, это типа RTFM? )) Спасибо, не видел этих функций )

Pasha: PSP пишет: Паша, а leto_Alias() меняет ли в процессе своего выполнения текущую рабочую область? Если да, то восстанавливает ли ту, которая была до ее вызова? Нет, не меняет. Р.о. надо устанавливать самому, как и возвращать прежнюю. Чтобы было понятнее, можно посмотреть примеры функций в tests\letoudf.prg



полная версия страницы