Página 2 de 4

Eval no Clipper 5.3 roda, no Harbour não

Enviado: 01 Mar 2019 22:47
por microvolution
pessoal boa noite!
meu problema é com a criação de um menu gui através da wvg.
este código:

Código: Selecionar todos

         bCode := [ {|| EXECUTA_PROGRAMA_wvg ( "] + acMenu[ nCont, 3 ] + [" ) } ]
         oMenu:AddItem( acMenu[ nCont, 1 ] , &( bCode ) )
chama a função EXECUTA_PROGRAMA_WVG:

Código: Selecionar todos

function EXECUTA_PROGRAMA_wvg (PROGRAMA)
   msginfo(PROGRAMA) // linha só pra testes
   msginfo(len(PROGRAMA)) // linha só pra testes
   set key TECLA_UTIL to UTIL_PROG
   close all
   // eval (PROGRAMA)
   eval (&(PROGRAMA))
   ABRE_ARQ_ACESSO ()
   set key TECLA_HELP to
   set key TECLA_UTIL to
return nil // EXECUTA_PROGRAMA_wvg
Acontece que gera o erro de EVAL assim:
se usar a linha eval (&(PROGRAMA)) do jeito que o autor do post apresenta no final, o erro fica sendo:
Error BASE/1003 Variável não existe: "xxxxx"
Se mudar a linha para eval (PROGRAMA), o erro é mesmo do autor do post:
Error BASE/1004 Método não exportado: EVAL
?? alguém já passou por isso?

Eval no Clipper 5.3 roda, no Harbour não

Enviado: 02 Mar 2019 00:59
por JoséQuintas
o tópico é sobre algo que funcionou no 5.3, mas não funciona no Harbour.
Acho que não é o seu caso, porque não deve ter testado no 5.3.
Mas vamos lá.

Vamos simplificar sobre qual é o seu problema, que não tem nada a ver com WVG:

Código: Selecionar todos

cMicroInfada := acMenu[ nCont, 3 ]
cCmd := [ {|| Executa_Programa( "] + cMicroInfada + [" ) } ]
Eval( &( cCmd ) )

FUNCTION Executa_Programa( cMicroInfada )
   MsgInfo( cMicroInfada )
   Eval( &( cMicroInfada ) )
   RETURN NIL
Qual o problema disso?
Sei lá... o conteúdo de cMicroInfada é válido pra esse uso estranho?

Eval no Clipper 5.3 roda, no Harbour não

Enviado: 02 Mar 2019 10:56
por microvolution
JoséQuintas escreveu:Sei lá... o conteúdo de cMicroInfada é válido pra esse uso estranho?
se o nobre professor diz "sei lá" kkkk
não entendi nada e continua o mesmo erro.

Eval no Clipper 5.3 roda, no Harbour não

Enviado: 02 Mar 2019 11:50
por Mario Mesquita
Bom dia.

Qual o escopo dessa variável "cMicroInfada"? Pública, local, etc? Ela aparece como variável em cima, mas também como parâmetro na função. Aí ele vira variável local.

Não poderia ser isso?

Saudações,
Mario.

Eval no Clipper 5.3 roda, no Harbour não

Enviado: 02 Mar 2019 12:04
por Jairo Maia
Está errado a forma de uso do EVAL(). EVAL executa Cod Block.

Altere essa linha que está dessa forma:

Código: Selecionar todos

eval (&(PROGRAMA))
Para esta forma:

Código: Selecionar todos

Eval( { || &PROGRAMA } )
Veja se funciona.

Eval no Clipper 5.3 roda, no Harbour não

Enviado: 02 Mar 2019 19:02
por JoséQuintas
microvolution escreveu:se o nobre professor diz "sei lá" kkkk
não entendi nada e continua o mesmo erro.
Qual o problema disso?
Sei lá... o conteúdo de cMicroInfada é válido pra esse uso estranho?
Deixa eu repetir:
Qual o problema disso?
Sei lá... o conteúdo de cMicroInfada é válido pra esse uso estranho?
deu atenção apenas ao "sei lá" ?
vamos retirar o sei lá.
o conteúdo de cMicroInfada é válido pra esse uso estranho?
é mesmo, errei, é "Microevolutionzada", coisa que o Microevolution fez.
Mais direto:

Código: Selecionar todos

Eval( &( cMicroEvolutionzada ) )
Porque não funciona?
O único no mundo inteiro que sabe o conteúdo dessa variável é o Microevolution,
Só pode ser alguma cagad. do Microevolution, mas se não colocar aqui qual é o conteúdo, ninguém vai poder ajudar.
Por isso digo... Sei lá.... só você tem a informação do que tem aí dentro....

Eval no Clipper 5.3 roda, no Harbour não

Enviado: 02 Mar 2019 19:18
por JoséQuintas
Jairo Maia escreveu:Altere essa linha que está dessa forma:
Não jairo, aqui é uma coisa muito legal pra evitar certos tipos de problema.

isto precisa da variável: &variavel

Isto não &( variavel )

Um exemplo mais claro: &( "cod" + "_" + "Cli" )
O macro está sendo aplicado sobre o resultado e com isso, o que foi usado para o cálculo não importa, nem mesmo se for uma variável.
&( "Cod" + cSeparador + "Cli" )

Eliminei muito problema com isso.

Eval no Clipper 5.3 roda, no Harbour não

Enviado: 02 Mar 2019 20:26
por JoséQuintas
Em certos casos, o parêntesis serve pra eliminar macro.

Código: Selecionar todos

USE &cArquivo
RUN &cComando

Código: Selecionar todos

USE ( cArquivo )
RUN ( cComando )
Comentei aqui que numa época usei Joiner, era um compilador alternativo ao Clipper, pra ser usado no Linux.
Um grande diferencial é que nele não funcionava macro.
Foi nessa época que acabei descobrindo esses "macetes", pra não ter que usar macro, e manter um fonte compatível entre Clipper/Joiner.

E no uso do Harbour, aquele uso de &( "texto" ), pra evitar vários erros de compilação por causa do tipo de variável.
E continuar mantendo o fonte compatível entre Clipper/Harbour.

Certas situações acabam ajudando a pensar/testar coisas que não tínhamos pensado antes.

Eval no Clipper 5.3 roda, no Harbour não

Enviado: 02 Mar 2019 20:58
por Jairo Maia
Então vamos ao problema do microvolution. Basta compilar esse exemplo.

Ele não está enviando code block ao Eval, está enviando texto. Vejamos:

Código: Selecionar todos

bCode := [ {|| EXECUTA_PROGRAMA_wvg ( "] + acMenu[ nCont, 3 ] + [" ) } ]
Texto "puro", ou seja, string, não code block.

Então envie apenas a função a ser executada. Na função de menu dele ele tem que alterar apenas indicando a função a ser aberta, e na função de executar o code block mudar para a forma correta se quiser usar Eval().Vamos ao teste:

Código: Selecionar todos

Function Main()
 /*
   Aqui, uma simulação de como ele tem que colocar no Array do menu, ou seja, ao clicar no menu a função literal a ser executada:
 */
 Local PROGRAMA:="ABRE_ARQ_ACESSO()"
 Local PROGRAMA2:="Teste2()"
 Local PROGRAMA3:="Teste3()"

 EXECUTA_PROGRAMA_wvg( PROGRAMA )
 
 EXECUTA_PROGRAMA_wvg( PROGRAMA2 )
 
 EXECUTA_PROGRAMA_wvg( PROGRAMA3 )

rETURN nIL

Function EXECUTA_PROGRAMA_wvg(PROGRAMA)

 Eval( { || &PROGRAMA } )

return nil

Function ABRE_ARQ_ACESSO()

 Hb_Alert( "Olá! Estou em ABRE_ARQ_ACESSO()" )

Return Nil

Function Teste2()

 Hb_Alert( "Olá! Estou em Teste2()" )

Return Nil

Function Teste3()

 Hb_Alert( "Olá! Estou em Teste3()" )

Return Nil

Eval no Clipper 5.3 roda, no Harbour não

Enviado: 02 Mar 2019 21:15
por JoséQuintas
Pelo que dá pra imaginar do fonte do Microevolution, para ser algo válido:

Código: Selecionar todos

cMenu := " { || Teste() }"
cCode := [ { || ExecutePrg( "] + cMenu + [" ) } ]
bCode := &bCode
A string de gerar o codeblock seria esta:

Código: Selecionar todos

{ || ExecutePrg( "{ || Teste() }" ) }
isso vai executar isto:

Código: Selecionar todos

ExecutePrg( "{|| Teste() }" )
isso significa que a rotina vai receber exatamente o que estava em cMenu

Código: Selecionar todos

"{ || Teste() }"
Se a rotina faz isto:

Código: Selecionar todos

Eval( &( cCmd ) )
Então ela vai executar isto:

Código: Selecionar todos

Teste()
Porque a rotina do Microevolution não funciona?
O conteúdo não serve pra rotina, ou a rotina não serve para o conteúdo

E qual é o conteúdo?
Tá lá... no fonte do Microevolution.... na frente do nariz dele... só ele tá vendo

Eval no Clipper 5.3 roda, no Harbour não

Enviado: 03 Mar 2019 10:33
por Jairo Maia
JoséQuintas escreveu:E qual é o conteúdo?
Tá lá... no fonte do Microevolution.... na frente do nariz dele... só ele tá vendo
Pior que é! Veja um outro exemplo usando EXATAMENTE a linha dele que monta o code block. Nesse caso, usei variáveis LOCAL, mas no caso dele, dependendo de como está o programa, as variáveis acMenu e nCont precisam ser declaradas como PRIVADAS, ou vai dar RTE de variável inexistente:

Código: Selecionar todos

Function Main()

 Local bCode, nCont:=1, acMenu:={}, aMenuOpc:={}
 
 AaDd( acMenu, { "Executar Teste1()", Nil, "Teste1()" } )
 AaDd( acMenu, { "Executar Teste2()", Nil, "Teste2()" } )
 AaDd( acMenu, { "Executar Teste3()", Nil, "Teste3()" } )
 
 AEval( acMenu, { |x| AaDd( aMenuOpc, x[1] ) } )
 
 Clear Screen
 
 Do While .t.
  
  nCont := ACHOICE(12,20,15,36, aMenuOpc,.T.,,nCont)
  
  If nCont = 0
   Exit
  EndIf

  bCode := [ {|| EXECUTA_PROGRAMA_wvg ( "] + acMenu[ nCont, 3 ] + [" ) } ]
  Eval( &bCode )
  
 EndDo
 
 Clear Screen
 
Return nIL

Function EXECUTA_PROGRAMA_wvg(PROGRAMA)

 Hb_Alert( "Funcao a ser executada: " + PROGRAMA )
 Eval( { || &PROGRAMA } )

return nil

Function Teste1()

 Hb_Alert( "Olá! Estou em Teste1()" )

Return Nil

Function Teste2()

 Hb_Alert( "Olá! Estou em Teste2()" )

Return Nil

Function Teste3()

 Hb_Alert( "Olá! Estou em Teste3()" )

Return Nil

Eval no Clipper 5.3 roda, no Harbour não

Enviado: 03 Mar 2019 12:09
por microvolution
bom dia nobres Jairo e JQuintas!
me sinto honrado pela participação dos senhores nesse post que não é de minha autoria e sim do próprio professor Quintas.
Bom, o meu menu clipper (console = setas, esc, enter e com um pouco de mouse) pra chamar o próximo módulo é assim:

Código: Selecionar todos

MONTA_VETOR_wvg (LINHA,BLOCO,H_IND,'~Empresas'                    ,{|| EXECUTA_PROGRAMA ({|| PCI10024 ()})},'PCI10024',oMenu)
Observem que EXECUTA_PROGRAMA chama o bloco PCI10024() que é uma função, ou seja, um outro módulo onde realmente executa tudo.
modifquei o MONTA_VETOR acima para a realidade minha de acordo com o que o nobre JQuintas nos passou:

Código: Selecionar todos

         MenuDrop()
            if MONTA_VETOR_wvg2 ('PCI10001')
               MenuOption(HB_AnsiToOem("Orçamentos"),PCI10001())
            endif
         MenuUnDrop()
O problema - na minha ignorância, é exatamente em que a linha MenuOption, transfira o PCI1001() para dentro do:

Código: Selecionar todos

STATIC FUNCTION MenuOption(mPrompt,mProg)
   LOCAL nCont
   LOCAL mNow
   MEMVAR nMenuLevel, aaMenuOption
   mProg := iif( mProg==NIL, "", mProg)
   
   mNow := aaMenuOption
   FOR nCont = 1 TO nMenuLevel
      mNow := mNow[Len(mNow)]
      IF ValType(mNow[2]) # "A"
         mNow[2] := {}
      ENDIF
      mNow := mNow[2]
   NEXT
   Aadd(mNow,{mPrompt,{},mProg})
RETURN NIL
então, não consegui entender o resultado final desta função MENUOPTION que leva o PCI10001() (apenas exemplo) para a função BUILDMENU:

Código: Selecionar todos

FUNCTION BuildMenu( oMenu, acMenu)
   LOCAL nCont, oSubMenu, bCode
   
   FOR nCont = 1 TO Len( acMenu )
      // msginfo ( acMenu[ nCont, 1 ])

      IF Len( acMenu[ nCont, 2 ] ) == 0
      // msginfo('dentro do IF')
         // bCode := [{|| ExecutePrg( "] + acMenu[ nCont, 3 ] + [" ) }]
         // bCode := EXECUTA_PROGRAMA ({|| acMenu[ nCont, 3 ] ()})
         // EXECUTA_PROGRAMA ({|| PCI10003 ()})
         // bCode := [{|| EXECUTA_PROGRAMA( "] + acMenu[ nCont, 3 ] + [" ) }]
         bCode := [ {|| EXECUTA_PROGRAMA_wvg ( "] + acMenu[ nCont, 3 ] + [" ) } ]
         // bCode := acMenu[ nCont, 3 ]
         // bCode := &(acMenu[ nCont, 3 ])
         // bCode := &(acMenu[ nCont, 3 ])
         // bCode := ({|| EXECUTA_PROGRAMA_wvg ({|| (&(acMenu[ nCont, 3 ])) ()})})
         // bCode := ({|| EXECUTA_PROGRAMA_wvg ({|| acMenu[ nCont, 3 ] ()})})
         // bCode := ({|| EXECUTA_PROGRAMA_wvg ({|| Prg ()})})
         // MsgInfo(bcode)
         // cCmd := [ {|| Executa_Programa_wvg( "] + bCode + [" ) } ]
         // Eval (&(cCmd))
         // msginfo (bcode)
         // msginfo (&(bcode))
         // msginfo (&bcode.)
         // oMenu:AddItem( acMenu[ nCont, 1 ] , &( bCode ) )
         oMenu:AddItem( acMenu[ nCont, 1 ] , bCode )
      ELSE 
         oSubMenu := WvgMenu():new( oMenu, , .T. ):Create()
         BuildMenu( oSubMenu, acMenu[ nCont, 2 ] )
         oMenu:AddItem( oSubMenu, acMenu[ nCont, 1 ] )
      ENDIF
   NEXT
RETURN NIL // BuildMenu( oMenu, acMenu )
Eis o problema: a função (módulo) PCI1001() chegar aqui no bCode.
Obs.: as linhas comentadas foram diversas tentativas que fizemos de entender o funcionamento de toda a tragetória do PCI1001() até chegar aqui e ir para dentro da função EXECUTA_PROGRAMA_WVG() que contém o EVAL.
Vejam essa função abaixo:

Código: Selecionar todos

function EXECUTA_PROGRAMA_wvg (PROGRAMA)
   msginfo(PROGRAMA)
  
   set key TECLA_UTIL to UTIL_PROG
   close all
   eval (PROGRAMA)
   // eval (&(PROGRAMA))
   ABRE_ARQ_ACESSO ()
   set key TECLA_HELP to
   set key TECLA_UTIL to
return nil // EXECUTA_PROGRAMA_wvg
Nada, funciona. Inclusive está com linha comentada pois foi mais uma tentativa de execução.
Como sou apenas um "ignorante" e nada sei, a coisa pra mim é complexa de se entender, principalmente se tratando de coisa gráfica.
Então, o que precisa acontecer - na minha opinião, é que o conteúdo da "PROGRAMA" que chega aqui na função EXECUTA_PROGRAMA_WVG() seja realmente o que era na função MONTA_VETOR().
Resumindo, pra mim o problema é de comunicação entre as funções, que na função:

Código: Selecionar todos

MONTA_VETOR_wvg (LINHA,BLOCO,H_IND,'~Grupos'                      ,{|| EXECUTA_PROGRAMA ({|| PCI10007 ()})},'PCI10007',oMenu)
Acima, funcionava, agora abaixo não funciona:

Código: Selecionar todos

bCode := [ {|| EXECUTA_PROGRAMA_wvg ( "] + acMenu[ nCont, 3 ] + [" ) } ]
Simples. Mas, pra mim complexo de se entender.
o conteúdo acMenu[nCont,3] é que o causador do problema, mas, não sei resolver essa fórmula!
rs

Eval no Clipper 5.3 roda, no Harbour não

Enviado: 03 Mar 2019 15:32
por JoséQuintas
Ponte que caiu, realmente gosta de encher fonte de lixo.
Cada vez complica mais.
No meu caso, posso colocar string ou codeblock.
Provavelmente no seu caso está usando apenas codeblock.

vetor do menu:

Código: Selecionar todos

AAdd( mNow, { mPrompt, {}, mProg } )
são 3 itens:
mNow = descrição
{} = subopções, se existirem
mProg = nome da rotina em codeblock (que usou), ou no meu caso também posso usar string.

Código: Selecionar todos

MONTA_VETOR_wvg (LINHA,BLOCO,H_IND,'~Empresas'                    ,{|| EXECUTA_PROGRAMA ({|| PCI10024 ()})},'PCI10024',oMenu)
Nem quero entender isso acima.
O objetivo é executar { || pci10024() } ?
Só precisa disso, porque aí tem Executa_Programa() ?

Código: Selecionar todos

if MONTA_VETOR_wvg2 ('PCI10001')
   MenuOption(HB_AnsiToOem("Orçamentos"),PCI10001())
endif
Também não quero entender isso acima.
Tá adicionando o resultado de uma função ao menu?

Código: Selecionar todos

      // msginfo('dentro do IF')
         // bCode := [{|| ExecutePrg( "] + acMenu[ nCont, 3 ] + [" ) }]
         // bCode := EXECUTA_PROGRAMA ({|| acMenu[ nCont, 3 ] ()})
         // EXECUTA_PROGRAMA ({|| PCI10003 ()})
         // bCode := [{|| EXECUTA_PROGRAMA( "] + acMenu[ nCont, 3 ] + [" ) }]
         bCode := [ {|| EXECUTA_PROGRAMA_wvg ( "] + acMenu[ nCont, 3 ] + [" ) } ]
         // bCode := acMenu[ nCont, 3 ]
         // bCode := &(acMenu[ nCont, 3 ])
         // bCode := &(acMenu[ nCont, 3 ])
         // bCode := ({|| EXECUTA_PROGRAMA_wvg ({|| (&(acMenu[ nCont, 3 ])) ()})})
         // bCode := ({|| EXECUTA_PROGRAMA_wvg ({|| acMenu[ nCont, 3 ] ()})})
         // bCode := ({|| EXECUTA_PROGRAMA_wvg ({|| Prg ()})})
         // MsgInfo(bcode)
         // cCmd := [ {|| Executa_Programa_wvg( "] + bCode + [" ) } ]
         // Eval (&(cCmd))
         // msginfo (bcode)
         // msginfo (&(bcode))
         // msginfo (&bcode.)
         // oMenu:AddItem( acMenu[ nCont, 1 ] , &( bCode ) )
         oMenu:AddItem( acMenu[ nCont, 1 ] , bCode )
...
function EXECUTA_PROGRAMA_wvg (PROGRAMA)
   msginfo(PROGRAMA)
  
   set key TECLA_UTIL to UTIL_PROG
   close all
   eval (PROGRAMA)
   // eval (&(PROGRAMA))
   ABRE_ARQ_ACESSO ()
   set key TECLA_HELP to
   set key TECLA_UTIL to
return nil // EXECUTA_PROGRAMA_wvg
Também não quero entender isso acima.

Código: Selecionar todos

cDescricao := acMenu[ nCont, 1 ]
bCode       := acMenu[ nCont, 3 ]
Bom... o menu tem uma descrição e um codeblock.
o menu da API Windows/gtwvg precisa de uma descrição e um codeblock.
Então tá tudo pronto.
É só trocar aquele monte de lixo acima por:

Código: Selecionar todos

cDescricao := acMenu[ nCont, 1 ]
bCode       := acMenu[ nCont, 3 ]
oMenu:AddItem( cDescricao, bCode )
uma string, um codeblock.
Não seria isso?


Agora.... como é teimoso, não leu o que eu disse antes, e já partiu pra sair usando antes de qualquer teste.....

A próxima etapa vai ser fazer funcionar o seu fonte, que provavelmente não vai funcionar.
Imagino que vai dar falta de muitas variáveis, mas isso já avisei antes que deveria acontecer.
Como partiu pra sair usando ao invés de testar...

Eval no Clipper 5.3 roda, no Harbour não

Enviado: 03 Mar 2019 16:59
por microvolution
JoséQuintas escreveu:Tá adicionando o resultado de uma função ao menu?
lembra q falei q preciso limitar as opções ao perfil do usuário?
algumas opções não podem aparecer pra todos os usuários. Então, o resultado da função é a q libera o a criação ou não da opção do menu/submenu.
JoséQuintas escreveu:Agora.... como é teimoso, não leu o que eu disse antes, e já partiu pra sair usando antes de qualquer teste.....
quem me dera se fosse teimosia. É ignorância de minha parte mesmo. Não consigo entender, simples assim. Pra mim isso tudo q o nobre escreve é muito complexo. O meu código antigo em clipper, consigo com sua ajuda, inclusive colocar clique do mouse, mas, gostaria da opção do menu.
Pelo pouco q entendi ao ler/reler/rever o seu código, vejo que o problema está nesta linha:

Código: Selecionar todos

bCode := [ {|| EXECUTA_PROGRAMA_wvg ( "] + acMenu[ nCont, 3 ] + [" ) } ]
que é um resultado produzido da linha abaixo:

Código: Selecionar todos

MenuOption(HB_AnsiToOem("Orçamentos"),"PCI10001()")
Já testei assim também, mas, não funciona:

Código: Selecionar todos

MenuOption(HB_AnsiToOem("Orçamento ~Simplificado"),"PCI10047")
Assim como não consigo entender o seu código, é a mesma coisa do nobre professor não entender o meu que eu já entendo e sei onde está cada coisa.
JoséQuintas escreveu:O objetivo é executar { || pci10024() } ?
Claro, ou pci10001, pci10002, etc...
Mas, não está funcionando.

Eval no Clipper 5.3 roda, no Harbour não

Enviado: 03 Mar 2019 17:44
por microvolution
só pra concluir essa parte.
essas 2 linhas abaixo:

Código: Selecionar todos

bCode := [ {|| EXECUTA_PROGRAMA_wvg ( "] + acMenu[ nCont, 3 ] + [" ) } ]
oMenu:AddItem( acMenu[ nCont, 1 ] , &( bCode ) )
estão dentro do :

Código: Selecionar todos

IF Len( acMenu[ nCont, 2 ] ) == 0
que pertencem à função do JQuintas:

Código: Selecionar todos

FUNCTION BuildMenu( oMenu, acMenu)
e dentro da função:

Código: Selecionar todos

FUNCTION MenuClipper()
está a função que cria a opção e manda pro codeblock da função BUILDMENU:

Código: Selecionar todos

MenuOption(HB_AnsiToOem("Orçamentos"),"PCI10001()")
É isso que está no sistema.
Da forma q está aí o erro é o mesmo desde o início de meus comentários aqui neste tópico:
19-0303 - erro EVAL.png
As linhas do erro são:
4045:

Código: Selecionar todos

oMenu:AddItem( acMenu[ nCont, 1 ] , &( bCode ) )
4306:

Código: Selecionar todos

eval (PROGRAMA)
E agora Mario e JQ o q está errado?
voltamos à estaca zero