Página 3 de 5

Cancelar Operação

Enviado: 06 Jan 2016 13:03
por JoséQuintas
Não entendi porque os codeblocks.
Aqui criei uma função só pra deixar esse tipo de coisa mais legível, apesar que dependendo do caso, faria diferente.
E minha GetSys alterada atualiza a tela mesmo em WHEN .F.

Código: Selecionar todos

   ReadExit(.T.)
   cConvenio:=" "
   dData  :=CTOD("06/01/2016")
   @ 10,00 SAY "Convenio:" GET cConvenio PICTURE "!" VALID cConvenio $ "SN" COLOR "GR+/B,B/W*"
   @ 11,00 SAY "Data  :" GET dData  PICTURE "@D" ;
      WHEN ReturnValue( .T., dData := iif(cConvenio = "N", Ctod(""), dData ) .AND. cConvenio == "S"
      VALID LastKey() == K_UP .OR. .NOT. Empty( dData )
   READ

FUNCTION ReturnValue( xValue, ... )
   RETURN xValue
Importante:
No WHEN, cConvenio == "S" precisa estar em segundo lugar, senão a otimização pula o cálculo.
No VALID dispensa a checagem de cConvenio, porque quando não precisa data já é resolvido pelo WHEN

Cancelar Operação

Enviado: 06 Jan 2016 13:14
por JoséQuintas
Ou numa variação:

Código: Selecionar todos

ReadExit(.T.)
 cConvenio:=" "
 dData :=CTOD("06/01/2016")
 @ 10,00 SAY "Convenio:" GET cConvenio PICTURE "!" COLOR "GR+/B,B/W*" ;
   VALID ReturnValue( cConvenio $ "SN" , dData := iif( cConvenio == "N", Ctod( "" ), dData ) )
 @ 11,00 SAY "Data :" GET dData PICTURE "@D" WHEN cConvenio == "S"
   VALID LastKey() == K_UP .OR. .NOT. Empty( dData )
 READ

FUNCTION ReturnValue( xValue, ... )
 RETURN xValue
Já que é o GET do convênio que causa mudança da data, talvez seja mais interessante deixar nele.

Cancelar Operação

Enviado: 06 Jan 2016 13:21
por JoséQuintas
E numa última variação:

Código: Selecionar todos

 @ 10,00 SAY "Convenio:" GET cConvenio PICTURE "!" COLOR "GR+/B,B/W*" VALID ConvenioValid( cConvenio, @dData )
 @ 11,00 SAY "Data :" GET dData PICTURE "@D" WHEN cConvenio == "S"  VALID LastKey() == K_UP .OR. .NOT. Empty( dData )
 READ

STATIC FUNCTION ConvenioValid( cConvenio, @dData )
   IF cConvenio == "N"
      dData := Ctod("")
   ENDIF
   RETURN cConvenio $ "SN"
A linha fica bem legível.
E a declaração STATIC FUNCTION impede que outra função com mesmo nome altere o resultado.

Lembrando:
O fonte não é para o compilador, é pra nós.
Deu problema em validar o convênio... ok... só olhar a rotina ConvenioValid(), tá ali a rotina pequeninha, fácil de entender, e fácil de alterar.
Mais fácil do que complicar mais ainda o codeblock com exceções (pra outros casos).

"Dividir um problema grande em problemas pequenos. Acaba tudo resumido a resolver problemas pequenos".

Lógico... sem criar dependências, pra não criar infinitos probleminhas....
Nesse caso a função ConvenioValid() tem exatamente tudo que precisa pra funcionar, não depende de nada PRIVATE ou PUBLIC.

Cancelar Operação

Enviado: 06 Jan 2016 14:16
por asimoes
Quintas,

Eu até tentei testar o seu exemplo, mas como o seu getsys está customizado, não deu, dá erro.

Cancelar Operação

Enviado: 06 Jan 2016 14:48
por JoséQuintas
A getsys alterada é só pra questão de atualizar tela.

Se deu erro é porque digitei errado.
Digitei direto no post.
Vou testar as três.

Cancelar Operação

Enviado: 06 Jan 2016 15:05
por JoséQuintas
Foi questão de faltar fechar parêntesis e faltar ponto e vírgula pra continuação.
O curioso foi acusar erro em codeblock sem ter codeblock.... rs

As três juntas, passando na compilação, liquedição e execução.
Sem a getsys alterada, é provável que o campo dData não seja atualizado na tela, apesar de ter seu conteúdo atualizado.
(algo como oGet:Display() na getsys).
No teste nem vai dar pra perceber, porque a data é o último campo, e a atualização não faz falta.

Código: Selecionar todos

#include "inkey.ch"

PROCEDURE Main
   ReadExit( .T. )
   DO Teste1
   DO Teste2
   DO Teste3
   RETURN


PROCEDURE Teste1
   LOCAL cConvenio := " ", dData := Date(), GetList := {}
   cConvenio:=" "
   dData :=CTOD("06/01/2016")
   @ 10,00 SAY "Convenio:" GET cConvenio PICTURE "!" VALID cConvenio $ "SN" COLOR "GR+/B,B/W*"
   @ 11,00 SAY "Data :" GET dData PICTURE "@D" ;
      WHEN ReturnValue( .T., dData := iif(cConvenio = "N", Ctod(""), dData ) ) .AND. cConvenio == "S" ;
      VALID LastKey() == K_UP .OR. .NOT. Empty( dData )
   READ
   RETURN

PROCEDURE Teste2
   LOCAL cConvenio := " ", dData := Date(), GetList := {}
   cConvenio:=" "
   dData :=CTOD("06/01/2016")
   @ 10,00 SAY "Convenio:" GET cConvenio PICTURE "!" COLOR "GR+/B,B/W*" ;
      VALID ReturnValue( cConvenio $ "SN" , dData := iif( cConvenio == "N", Ctod( "" ), dData ) )
   @ 11,00 SAY "Data :" GET dData PICTURE "@D" WHEN cConvenio == "S" ;
      VALID LastKey() == K_UP .OR. .NOT. Empty( dData )
   READ
   RETURN

PROCEDURE Teste3
   LOCAL cConvenio := " ", dData := Date(), GetList := {}
   @ 10,00 SAY "Convenio:" GET cConvenio PICTURE "!" COLOR "GR+/B,B/W*" VALID ConvenioValid( cConvenio, @dData )
   @ 11,00 SAY "Data :" GET dData PICTURE "@D" WHEN cConvenio == "S" VALID LastKey() == K_UP .OR. .NOT. Empty( dData )
   READ
   RETURN

STATIC FUNCTION ConvenioValid( cConvenio, dData )
   IF cConvenio == "N"
      dData := Ctod("")
    ENDIF
    RETURN cConvenio $ "SN"

FUNCTION ReturnValue( xValue, ... )
   RETURN xValue

Cancelar Operação

Enviado: 06 Jan 2016 15:11
por JoséQuintas
Só comentário adicional...

Numa das tentativas antigas de atualização, criei GetDisabled()
Algo deste tipo:

Código: Selecionar todos

@ 1, 0 GET campo1
@ 2, 0 GET campo2 WHEN GetDisabled()
@ 3, 0 GET campo3 WHEN GetDisabled()
@ 4, 0 GET campo4 
READ

FUNCTION GetDisabled()
   IF LastKey() == K_UP
      KEYBOARD Chr( K_UP )
   ELSE
     KEYBOARD Chr( K_DOWN )
   ENDIF
   RETURN .T.
O WHEN apenas envia comandos pra pular o campo, assim a atualização de tela acontece.
Mas isso foi antes de mexer na getsys e resolver de vez.
Dependendo da validação do campo, isso não resolvia.

Nota:
Se o usuário está indo em frente - down, se está voltando up. segue a sequência e apenas pula o campo.

Nota2:
Com certeza essa saída aumentava e complicava mais os fontes.
Revisar o que já foi feito ajuda a melhorar o que vém pela frente.
Isso vale pra todo mundo, e sempre.

Cancelar Operação

Enviado: 06 Jan 2016 15:37
por JoséQuintas
Minhas duas versões de alteração na getsys pra isso:

Código: Selecionar todos

   WHILE !( nPos == 0 )
       // novo parte 1 - salva conteúdo antes do get
        aVarGet := Array( Len( GetList ) )
        FOR nCont = 1 TO Len( GetList )
           aVarGet[ nCont ] := GetList[ nCont ]:VarGet()
        NEXT
//      DispBegin()
//      FOR nCont = 1 TO Len( GetList ) // by JPA, atualizar Gets na tela
//         GetList[ nCont ]:Display()     // by JPA, atualizar Gets na tela
//      NEXT
//      DispEnd()

      PostActiveGet( oGet := GetList[ nPos ] )

      IF ( VALTYPE( oGet:reader ) == "B" )
         EVAL( oGet:reader, oGet )    // Use custom reader block
      ELSE
         GetReader( oGet, lIsMouse )            // Use standard reader
      ENDIF
// novo parte 2 - atualiza só o que teve conteúdo alterado
      FOR nCont = 1 TO Len( GetList )
         IF aVarGet[ nCont ] != GetList[ nCont ]:VarGet()
            GetList[ nCont ]:Display()
         ENDIF
      NEXT
      nPos := Settle( GetList, nPos )

   ENDDO
A primeira está comentada: atualizava sempre tudo.
A segunda, já atualiza somente aonde o conteúdo se modificou.
No when não dá certo, senão só atualiza os campos aonde tem when, e somente quando passar no when.
Isso eliminou muitos GetDisabled() que eu usava antes, e já resolveu pra gets ativos, que o GetDisabled() não resolvia.

Cancelar Operação

Enviado: 06 Jan 2016 17:42
por asimoes
Quintas,

Estou habilitando o mouse no teste, só que quando vai para o foco do campo pega o conteúdo de outro?
Tem que fazer alguma coisa para fazer o mouse funcionar corretamente com get..read ?

Cancelar Operação

Enviado: 06 Jan 2016 18:13
por asimoes
O que eu não estou entendendo é o seguinte:

Vou simplificar o que está acontecendo:

Quando pega foco no campo cConvenio o readvar() mostra CCONVENIO quando muda o foco com o mouse para o campo dData e volto o foco para o campo cConvenio com o mouse a função VerGet mostra DDATA, isso não ocorre com o uso do teclado, o readvar() mostra corretamente.

Código: Selecionar todos

Set( _SET_EVENTMASK, INKEY_ALL - INKEY_MOVE )
cConvenio:=Space(1)
dData:=CTOD("")

@ 10,00 SAY "Convenio" GET cConvenio WHEN VerGet()
@ 11,01 SAY "Data"      GET dData
READ

FUNCTION VerGet
   Alert(ReadVar())
RETURN .T.

Cancelar Operação

Enviado: 06 Jan 2016 18:30
por JoséQuintas
Interessante.

Está com o foco em cConvenio, clicou com o mouse, mostra cConvenio.

Está com o foco em dData, clicou com o mouse em cConvenio e.......

Primeiro verifica WHEN, pra ver se deixa ou não entrar em cConvenio.
O retorno está correto, porque ainda não saiu de dData.

Mas na hora da programação, é uma boa pegadinha.

Cancelar Operação

Enviado: 06 Jan 2016 19:02
por Jairo Maia
Olá Pessoal,
JoséQuintas escreveu:O retorno está correto, porque ainda não saiu de dData.
Não, Não! Saiu sim... :?

Concordo com o Alexandre. Com o teclado funciona OK! O problema está com o mouse. Então José, que tal colocar o exemplo do Alexandre no Harbour Developers que inclusive o Viktor sempre lhe dá atenção?

PS: Caso a sugestão for aceita, precisa acrescentar a linha #include "inkey.ch" no inicio do exemplo.

Cancelar Operação

Enviado: 06 Jan 2016 19:19
por JoséQuintas
A primeira coisa é aquela pergunta: é assim no Clipper? se for... vai continuar.

Mas à primeira vista, o WHEN é antes de chegar no get.

Cancelar Operação

Enviado: 06 Jan 2016 19:23
por JoséQuintas
Minha getsys é do tempo do clipper:

Código: Selecionar todos

  IF ( GetPreValidate( oGet ) )

      // Activate the GET for reading
      oGet:setFocus()
Primeiro executa WHEN() e dependendo do resultado, o get entra em foco. oGet:SetFocus()
Então o WHEN é antes de chegar no get.

A não ser que no Clipper 5.3 fosse diferente, mas acho difícil.

Cancelar Operação

Enviado: 06 Jan 2016 19:40
por asimoes
Quintas,

O primeiro foco é em cConvenio (não tem teclado ou mouse ainda) depois é que começa o problema ao usar o mouse, com teclado funciona normal.
Parece que com o mouse o último foco do mouse é que fica com o valor do GetActive() ou ReadVar()