Página 1 de 1

como fazer o getlist funcionar?

Enviado: 18 Mai 2016 16:52
por narlem
Olá,

Tenho varios gets em um read, ai no valid de um deles eu chamo uma funcao que abre outro read com varios gets
e quando volto para o primeiro read volta os campos ok, mas o valid dos campos do primeiro read fica como se fosssem
os valid do segundo read aberto.
já tentei usar o getlist como abaixo, mas nao deu certo. Alguem sabe de uma alternativa que funciona ?

function main()
*
@ 10,10 say "primerio read.: " get wcampo valid funcao_teste()
read
return

function funcao_teste()
*
local wgetlist
wgetlist := getlist

@ 10,10 say "segundo read.: " get wtestando valid wtestando > 0
read
getlist := wgetlist
return

ao voltar para o primeiro read depois de passar pelo segundo read o valid do primeiro get do primeiro read fica
"valid wtestando > 0"
quando deveria voltar para "valid funcao_teste()"

Narlem
BH - MG

como fazer o getlist funcionar?

Enviado: 18 Mai 2016 17:08
por Kapiaba

Código: Selecionar todos

Procedure Main()

   LOCAL cVar := "Hello", cVar2 := "World", GetList := {}, Counter
   LOCAL oGet, xProperty
   LOCAL nGet, nGets, nProperty, nProperties
   LOCAL nStart
   LOCAL oEntry

   CLS

   @ 10,10 GET cVar
   @ 12,10 GET cVar2
   ?
   
   nStart := Seconds()

   FOR Counter := 1 TO 10000
      FOR EACH oGet IN GetList
         FOR EACH xProperty IN oGet
         NEXT
      NEXT
   NEXT

   ? Seconds() - nStart
   ?
   
   nStart := Seconds()

   FOR Counter := 1 TO 10000
      nGets := Len( GetList )
      FOR nGet := 1 TO nGets
         oGet := GetList[ nGet ]

         nProperties := Len( oGet )
         FOR nProperty := 1 TO nProperties
            xProperty := oGet[nProperty]
         NEXT
      NEXT
   NEXT

   ? Seconds() - nStart
   ?
   
   FOR EACH oEntry IN { "First Name" => "John", "Last Name" => "Doe" }
      ? oEntry:Key, "=>", oEntry:Value
      oEntry:Value := { "Homer", "Simpson" }[ HB_EnumIndex() ]
      ? oEntry:Key, "=>", oEntry:Value
      ?
   NEXT
   
RETURN

como fazer o getlist funcionar?

Enviado: 18 Mai 2016 17:45
por Toledo
Só para complementar... declarar o GETLIST como variável LOCAL:

Código: Selecionar todos

function main()
LOCAL GetList := {}
*
cls
wcampo:=spac(10)
wcampo2:=spac(10)
@ 10,10 say "primerio read.: " get wcampo valid funcao_teste()
@ 12,10 say "Outro read....: " get wcampo2
read
return

function funcao_teste()
LOCAL GetList := {}, cTela:=SaveScreen( 9, 9, 13, 40 )
*
cls
wtestando:=0
@ 10,10 say "segundo read.: " get wtestando valid wtestando > 0
read
RestScreen( 9, 9, 13, 40, cTela )
return .T.
Abraços,

como fazer o getlist funcionar?

Enviado: 19 Mai 2016 08:03
por narlem
Olá,

Vou testar aqui e coloco se deu ou não certo.

Mas desde já te agradeço pela resposta.

Narlem
BH - MG

como fazer o getlist funcionar?

Enviado: 19 Out 2016 11:11
por asimoes
Voltando ao assunto, trabalhando com o objeto GetList:

cTime1:=Space(8)
cTime2:=Space(8)
cTime3:=Space(8)

@ 05,00 GET cTime1 WHEN {|| Put( Time() ) }
@ 05,00 GET cTime2
@ 05,00 GET cTime3
READ

Para todos os Get´s

Código: Selecionar todos

FUNCTION Put( cVar )
LOCAL oElemento
FOR EACH oElemento IN GetList
   WITH Object oElemento
      //? :name  
      :Varput( cVar )
      :UpdateBuffer()
      :Display() 
   END
NEXT
RETURN  .T.
Tratando 1 Get

Código: Selecionar todos

FUNCTION Put( cVar )
LOCAL oElemento
FOR EACH oElemento IN GetList
   WITH Object oElemento
      IF :name  = "cTime2"
         :Varput( cVar )
         :UpdateBuffer()
         :Display() 
      ENDIF
   END
NEXT
RETURN  .T.

como fazer o getlist funcionar?

Enviado: 23 Out 2016 11:14
por rubens
Muito bom ASimoes...

Perdi muito tempo fazendo rotina de atualizações depois de uma validação... Pelo que entendi posso atualizar todos os gets ou gets especificos...
Quando fizer uma validação não vou precisar mais usar say/get para atualizar, Não preciso mais saber as coordenadas... basta mandar um "put()"...
Já tinha visto algo da classe mas não sabia como montar...

Valeu...

Rubens

como fazer o getlist funcionar?

Enviado: 23 Out 2016 14:07
por JoséQuintas
NÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃO

Não complique fonte.

Vamos ao problema:
o problema NÃO é atribuir o valor, é atualizar o conteúdo na tela, dependendo da situação.
Podemos dizer que é um inconveniente da GETSYS.
Então é só alterar a getsys, essa parte que coloquei "by JPA".
Ela apenas faz : Display() aonde o conteúdo estiver alterado.
(primeiro salva em array o conteúdo, e depois compara se houve mudança, por isso o FOR/NEXT nas duas situações)

Código: Selecionar todos

   DO WHILE ! nPos == 0
      aVarGet := Array( Len( GetList ) )
      FOR EACH oElement IN GetList // by JPA to otimize screen update
         aVarGet[ oElement:__EnumIndex ] := oElement:VarGet()
      NEXT

      // GET NEXT GET from list and post it as the active GET
      PostActiveGet( oGet := GetList[ nPos ] )

      // Read the GET
      IF ( VALTYPE( oGet:reader ) == "B" )
         EVAL( oGet:reader, oGet )    // Use custom reader block
      ELSE
         GetReader( oGet, lIsMouse )            // Use standard reader
      ENDIF

      FOR EACH oElement IN GetList // by JPA to otimize screen update
         IF aVarGet[ oElement:__EnumIndex ] != oElement:VarGet()
            oElement:Display()
         ENDIF
      NEXT
      // Move to NEXT GET based on EXIT condition
      nPos := Settle( GetList, nPos )

   ENDDO
Atualizar valores de variáveis, isso SEMPRE foi possível.
Vai poder continuar atualizando normalmente.
Apesar de poder ser feito com codeblock, eu prefiro usar uma função.

Exemplo:

Código: Selecionar todos

@ 1, 1 SAY "VALOR:" GET VALOR PICTURE "99999999.99"   VALID ReturnValue( .T., juros := valor * 0.10, desconto :=  ( Valor + juros ) * 0.05 )
@ 2, 1 SAY "JUROS:" GET JUROS PICTURE "999999.99"       
@ 3, 1 SAY "DESCONTO:" GET DESCONTO PICTURE "999999.99"
READ

FUNCTION ReturnValue( xValue, ... )
   RETURN xValue
Atualizar valores é normal, mas por exemplo se tem WHEN .F., não atualiza NA TELA ( o conteúdo é alterado).
Mais prático alterar a GETSYS e acabar com o problema.

Nota:
O :put() que mencionou não resolve o problema de atualizar tela, o que resolve é o : display().
Mas alterando na getsys, elimina TODA necessidade de colocar alguma coisa nos fontes.

A opção por codeblock que mencionei seria deixar o último elemento do codeblock como sendo o retorno:

Código: Selecionar todos

@ 1, 1 SAY "Valor:" GET VALOR PICTURE "999999.99" VALID { || juros := valor * 0.10, desconto := ( valor + juros ) * 0.05, .T. }
Se pensar direito dá quase no mesmo do que usar a função ReturnValue().... rs

como fazer o getlist funcionar?

Enviado: 23 Out 2016 14:41
por JoséQuintas
Ainda na questão de atualizar valores:

Código: Selecionar todos

@ 1, 1 SAY "Valor....:"  GET mValor VALID CalculaValores( mValor, @mJuros, @mDesconto )
@ 2, 1 SAY "Juros...:  GET mJuros VALID CalculaValores( mValor, @mJuros, @mDesconto )
@ 3, 1 SAY "Desconto...:  GET mDesconto VALID CalculaValores( mValor, @mJuros, @mDesconto )
READ

STATIC FUNCTION CalculaValores( mValor, mJuros, mDesconto )
   mJuros := mValor * 0.10
   mDesconto := ( mValor * 0.10 ) * 0.05
   RETURN .T.
1. Sobre o post: a rotina recalcula tudo sempre, a cada valor digitado
2. Passando variáveis por referência, essas são tratadas como locais, evita problemas com nomes de variáveis, ou interferência de outras variáveis com mesmo nome
3. Deixando a função como STATIC, evita problemas em inventar nomes de função, ou ter função repetida em outro fonte
4. Deixa claro o cálculo, não importa que tenha dezenas de campos pra serem atualizados
5. A alteração da getsys dá o toque final de atualizar a tela
6. Nenhum problema pra entender o fonte depois
7. Apenas como consequência de tudo isso: compila normalmente usando -w3 -es2 (como eu disse várias vezes, -w3 -es2 ajuda a lembrar o melhor jeito de fazer)

Nota: Agora imagine igual a isso na digitação de um pedido recalculando todos os impostos, passa a ser moleza.

como fazer o getlist funcionar?

Enviado: 23 Out 2016 15:55
por rubens
Então Quintas... não sei se entendi direito... a menos que eu já venho fazendo errado... mas olha só

Código: Selecionar todos

               @ 21, 05 SAY "CONDICAO PGTO:" GET cCODCOND PICT "@K999" VALID PESQCOND( @cCODCOND ) .AND. !Empty( cCODCOND ) .AND. MUDAPRECO() .AND. VERCOND()
               @ 22, 47 GET nDESC_P_  	PICT "999.99%"  VALID CALCPOR( @nDESCONTO_, @nDESC_P_ )
               @ 22, 67 GET nDESCONTO_ PICT P12   		VALID CALCVEN( @nTOTAL )
               @ 23, 67 GET nTOTAL  	PICT P12   	VALID VERTOTZERO( @nTOTAL ) .AND. VERDESC( @nDESC_P_, @nTOTAL, @nDESCONTO_ )
               READ
Função CalcVen()

Código: Selecionar todos

FUNCTION CALCVEN( nTOTAL )

   IF nDESCONTO_ < 0.00
      BEEP()
      Alert( 'DESCONTO NAO PODE SER MENOR DO QUE ZERO!!!' )
      nDESCONTO_ := 0.00
      RETURN .F.
   ENDIF

   IF nDESCONTO_ = 0.00
      nDESC_P_  := 0.00
      nTOTAL  := nSUBTOTAL
   ELSE
      nDESC_P_  := nDESCONTO_ / ( nSUBTOTAL / 100 )
      nTOTAL  := nSUBTOTAL - nDESCONTO_
   ENDIF
   @ 22, 47 GET nDESC_P_  PICT '999.99%' WHEN 1 > 2
   @ 22, 67 GET nDESCONTO_  PICT P12   WHEN 1 > 2
   @ 23, 67 GET nTOTAL  PICT P12   WHEN 1 > 2
   RETURN( .T. )
Aqui na na CalcVen eu usaria o put para atualizar na tela o conteúdo das variáveis nDesc_p_, nDesconto e nTotal, daí não precisaria das linhas 17,18 e 19.

Código: Selecionar todos

FUNCTION Put( )
LOCAL oElemento
FOR EACH oElemento IN GetList
 WITH Object oElemento
   :Varput( cVar )
   :UpdateBuffer()
   :Display() 
 END
NEXT
RETURN .T.
Isso não funcionaria?
Daí em todas as validações que eu precisasse atualizar uma variável eu chamaria a função put() que atualizaria todos os gets da getlist atual.
Não perderia tempo posicionando o cursos com @ say get.
Porque a mudança do valor da variável dentro da função calcven() por si só não atualizaria o get até que ele receba o foco novamente.
Agora se tiver um procedimento na getsys que atualizasse o get da variável automaticamente sempre que ela mudasse de valor também resolveria...

P.S. Depois que postei e que fui olhar de novo seu post e vi a mudança na getsys... vou fazer os testes... obrigado

Rubens

como fazer o getlist funcionar?

Enviado: 23 Out 2016 17:31
por JoséQuintas
Já deve ter visto no outro post:

Se passar as variáveis por referência pra rotina, retira a dependência de nome de variável.
Não se preocupe com vai mais fonte, porque vai ser mais seguro e mais prático pra futuras alterações.

Uma coisa importante:

Código: Selecionar todos

@ 21, 05 SAY "CONDICAO PGTO:" GET cCODCOND PICT "@K999" VALID PESQCOND( @cCODCOND ) .AND. !Empty( cCODCOND ) .AND. MUDAPRECO() .AND. VERCOND()
Lembre-se que se for obrigatório executar tudo desse valid, não vai acontecer.
Devido à otimização, na primeira condição que retornar .F., as outras não serão executadas.
Confirme se é isso mesmo que deve acontecer.

Isso faz parte da otimização default.
Numa explicação prática: se uma condição é falsa não vai aceitar, então pra que perder tempo verificando as outras.
É isso que a otimização faz, mas de repente, você está contando que a última será sempre executada, por exemplo, fazer cálculo.

como fazer o getlist funcionar?

Enviado: 24 Out 2016 15:23
por rubens
Então Quintas...

Se fosse para começar um projeto do zero talvez eu faria diferente mas com o passar dos anos e solicitações do cliente tive que ir fazendo estes "ajustes" !!!
No início era só PesqCond() dbedit com a tabela de condições só que começou a passar sem escolher a condição daí tive que validar com !empty(cCodCond) é lógico que ficava mais elegante or na função e validar para não sair sem escolher a condição. De repente um cliente pediu para recalcular o valor dos itens conforme a condição escolhida daí veio a validação MudaPreco() e por ultimo foi necessário uma outra validação que foi mais fácil criar a função vercond() então na realidade é um sequencia de validações. O algorítimo é ruim???!!! éh, mas funcionou e talvez na época o tempo tava escasso para corrigir o algorítimo original. MAs se precisar de mais validações? Espero que não... é uma rotina estática com poucas mudanças...
Mas sempre agradeço os seus comentários e observações, porque sempre empurram para frente para o melhor... gosto do seu jeito de nivelar as coisas pelo melhor e mais prático...

Quanto a questão do getsys... Na mosca... funcionou belezinha para o que foi proposto. Mas tenho um getsys adaptado pelo pessoal do antigo clipper´s club e tem um opção que transforma o get em password. Com essa mudança no getsys para atualizar automaticamente quando termino de digitar a senha ele troca os caracteres do password pelo que foi digitado. Daí criei uma condição, estática mesmo, que se for o get da senha ele não faz a atualização.

Obrigado
Rubenss

como fazer o getlist funcionar?

Enviado: 24 Out 2016 15:38
por JoséQuintas
Muito bom.

E agora pode até retirar dos fontes antigos o que fazia pra atualizar tela.

Avisar só por precaução:
Não sei se fez, é importante aonde alterou na getsys declarar as variáveis como locais.
Assim nada interfere com elas, e nem elas com nada.
Ainda mais a getsys, que é usada em tudo.