tbrowse: atualização da tela

Projeto [x]Harbour - Compilador de código aberto compatível com o Clipper.

Moderador: Moderadores

cjp
Usuário Nível 6
Usuário Nível 6
Mensagens: 1563
Registrado em: 19 Nov 2010 22:29
Localização: paraná
Contato:

tbrowse: atualização da tela

Mensagem por cjp »

Por favor, como faço para atualizar da tela do tbrowse após teclar alguma coisa na função de usuário?
Explico melhor: queria que, quando o usuário teclasse determinadas teclas, depois de feita a alteração correspondente, o browse voltasse atualizado; sem fechar o browse.
Exemplo: digamos que o usuário tecle Alt-A, para alterar o conteúdo de algum registro. Depois de feita a alteração, queria já exibir no browse essa alteração.
Atualmente, não está exibindo. Mas está alterando corretamente. Se eu fechar e reabrir o browse, volta atualizado. Mas eu queria que ele já voltasse atualizado sem precisar fechar e reabrir, entende?
Segue meu código atual:

Código: Selecionar todos

FUNCTION browseitem(cSql)
   LOCAL oRs, aCamposList
   LOCAL oCN :=ConexaoMySQL( "...", "...", "...", "..." )
*   local tela :=savescreen(0,0,maxrow(),maxcol())

   CLS

   oCn:open()

   DO WHILE .T.
      @ 5,5 SAY Padr( "Obtendo informações...", 22 ) 
      oRs := oCn:Execute( cSql )
      IF oRs == NIL
         Hb_Alert( "Não foi possível obter dados para exibição",, "W+/B" )
		 exit
	  Endif
	  IF oRs:Eof()
	     @ 5,5 clear to 5,25
         Hb_Alert( "Não há dados para exibição",, "W+/B" )
         EXIT
      ENDIF

	  if us="I"
         aCamposList := { ;
         { "DATA_RESPOSTA", { || oRs:ToString( "DATA_RESPOSTA", 11 ) } }, ;
         { "HORA_RESPOSTA", { || oRs:ToString( "HORA_RESPOSTA", 8 ) } }, ;
         { "TEMPO_USADO", { || oRs:ToString( "TEMPO_USADO", 6 )  } }, ;
         { "NR_PONTOS", { || oRs:ToString( "NR_PONTOS", 6 )  } }, ;
         { "TEMPO_PAGO", { || oRs:ToString( "TEMPO_PAGO", 6 )  } }, ;
         { "ATIVIDADE",       { || oRs:ToString( "ATIVIDADE", 60 ) } } }
	  else
         aCamposList := { ;
         { "DATA_RESPOSTA", { || oRs:ToString( "DATA_RESPOSTA", 11 ) } }, ;
         { "HORA_RESPOSTA", { || oRs:ToString( "HORA_RESPOSTA", 8 ) } }, ;
         { "ATIVIDADE",       { || oRs:ToString( "ATIVIDADE", 60 ) } } }
	  endif

        set color to w/r
 		cls
        DispBox( 0, (maxcol()-41)/2, 5, ((maxcol()-41)/2)+44, Nil, "GR+/N" )
     	@ 1,((maxcol()-41)/2)+1 say "Item: "+cArqAtiv+if(us="I","  Cadastrado por: "+alltrim(inc),"")
		@ 2,((maxcol()-41)/2)+1 say "Assunto: "+cAssAtiv
        if us="I"		
		   @ 3,((maxcol()-41)/2)+1 say "Data do cadastro: "+dtoc(dtinclu)+" às "+hrinc
		   @ 4,((maxcol()-41)/2)+1 say "Prioridade: "+alltrim(str(nPrior))
        endif		
		
        @ 6,0 to maxrow(),maxcol() double
		
        @ maxrow()-4,1 say "Tempo máximo para este item: "+alltrim(str(int(te)))+" minutos"
		inkey(.1)
        @ maxrow()-2,1 say "R:responder;B:atualiza;setas:sobe e desce;L:localiza texto"+if(us="I" .or. us="U" .or. us="K" .or. us="M" .or. us="S",";Alt-P:ped.preferência","")+if(us="I",";Ç:na presença;H:hora-exibe;S:adia por 1 semana;X:adia por X dias","")
		if us="I"
		   @ maxrow()-1,1 say "CTRL-P:alt.prioridade;Alt-A:alt.assunto;Alt-G:alt.dtcarga;E:restaurar"
		endif
	  
		 
      tBrowseADO( oRs, aCamposList, { | oBrowse, nKey | RotinaUsuarioItem( oRs, oBrowse, nkey ) } )
	  
      oRs:Close()
      EXIT
   ENDDO
   oCn:close()
   cls

RETURN Nil

STATIC FUNCTION RotinaUsuarioItem( oRs, oBrowse, nKey )
       local nPt, dDt, cHr, cCom, cQuant
	   local cod :=oRs:Fields("id"):Value

	   If (upper(chr(nkey)) =="R" .or. ((us="U" .or. us="I") .and. nkey==275))
	      if nkey=275
		     nTecla2=275
		  endif
		  chmfunc("respsql",,"S")
		  keyb chr(27)
	  
	  elseif nkey==288 .and. us="I" //Alt-D
		     @ maxrow()-5,1 clear to maxrow()-1,maxcol()-1
			 conf="N"
			 @ maxrow()-3,1 say "Apagar o seguinte registro:"
			 @ maxrow()-2,1 say oRs:Fields("atividade"):Value
			 @ maxrow()-1,20 say "Confirma?"get conf pict "@!"
			 read
			 if conf="S"
			    nrc=oRs:Fields("id"):Value
	            if !exqado("DELETE FROM tarefas WHERE id="+alltrim(str(nrc)),nProvTar) //nrtarefa='"+cArqAtiv+"' AND tarefa='"+tardelreg+"' AND data='"+alltrim(str(year(dt)))+"-"+substr(dtoc(dt),4,2)+"-"+substr(dtoc(dt),1,2)+"' AND hora='"+hr+"'")
			  	   ?"Não apagou"
				   inkey(5)
			    endif
			 endif   
				
	  elseif nkey==281  //Alt-P
		     chmfunc("novacadprefproc",cArqAtiv,"S")

	  elseif nkey==286 //Alt-A
		     chmfunc("novaaltassunto",,"S")

			 
       ENDIF
RETURN 1   

FUNCTION TBrowseADO( oRs, aCamposList, bExecutaRotinaUsuario )
   LOCAL oBrowse, nKey

   SuperADO( oRs )
   
   oBrowse := CriaBrowse( oRs, aCamposList )

   if procname(1)#"BROWSEITEM"
      DispBox( oBrowse:nTop - 1, oBrowse:nLeft - 1, oBrowse:nBottom + 3, oBrowse:nRight + 1, B_SINGLE )
   endif

   DO WHILE .T.
      oBrowse:refreshCurrent()
      DO WHILE ! oBrowse:Stable()
         oBrowse:Stabilize()
      ENDDO
      // Paint TBrowse current line...
      //oBrowse:ColorRect( { oBrowse:RowPos, oBrowse:LeftVisible, oBrowse:RowPos, oBrowse:RightVisible }, { 2, 1 } )

*      @ MaxRow() - 1, 3 SAY Padr( " Registro " + Ltrim( Str( oRs:AbsolutePosition ) ) + " de " + Ltrim( Str( oRs:recordCount ) ) + " ", 20 ) COLOR "N/W"

      nKey := Inkey(0)
      IF oBrowse:applyKey( nKey ) == TBR_EXIT
         EXIT
      ENDIF
      IF bExecutaRotinaUsuario != NIL
         DO WHILE ! oBrowse:Stable
            oBrowse:Stabilize()
         ENDDO
         Eval( bExecutaRotinaUsuario, oBrowse, nKey )
         oBrowse:RefreshAll()
      ENDIF
   ENDDO
RETURN Nil

STATIC FUNCTION CriaBrowse( oRs, aCamposList )
   LOCAL oBrowse, oColumn, aItem, nLen, nCont

   if procname(2)="BROWSEITEM"
      oBrowse := TBrowse():new( 07, 2, MaxRow() - 5, MaxCol() - 2 )
   else
      oBrowse := TBrowse():new( 02, 3, MaxRow() - 3, MaxCol() - 3 )
   endif
   
   oBrowse:headSep       := Chr(196) + Chr(194) + Chr(196)
   oBrowse:colSep        := " " + Chr(179) + " "
   oBrowse:footSep       := Chr(196) + Chr(193) + Chr(196)
   oBrowse:goTopBlock    := { || oRs:moveFirst() }
   oBrowse:goBottomBlock := { || oRs:moveLast() }
   oBrowse:skipBlock     := { |n| ADORecordSetSkipper( oRs,n ) }
   
   if procname(2)#"BROWSEITEM"
      oBrowse:colorSpec     := "W/B,W+/N,N/W*,W+/R,R+/B,R/W*"
   endif

   if us#"I" .and. (procname(1)="ENTERITEM" .or. procname(2)="ENTERITEM" .or. procname(3)="ENTERITEM" .or. procname(4)="ENTERITEM" .or. procname(5)="ENTERITEM" .or. procname(6)="ENTERITEM" .or. procname(7)="ENTERITEM")
	  keysec(-18,115,-1,.t.)
   else
	  keysec(27,1200,-1,.t.)
   endif
		 
   IF aCamposList == Nil
      nLen := oRs:fields():count() - 1
      FOR nCont := 0 TO nLen
         oColumn := TBColumnNew( oRs:fields( nCont ):name(), ADORecordSetFieldBlock( oRs, nCont ) )
         oColumn:width := Max( Min( oRs:Fields( nCont ):definedSize,50), Len( oRs:fields( nCont ):name ) ) + 5
         oBrowse:addColumn( oColumn )
      NEXT
   ELSE
      FOR EACH aItem IN aCamposList
         oColumn := TBColumnNew( aItem[1], aItem[2] )
         IF Len( aItem ) > 2
            oColumn:ColorBlock := aItem[3]
         ENDIF
         oBrowse:AddColumn( oColumn )
      NEXT
   ENDIF
RETURN oBrowse

FUNCTION SuperADO( oRs )
   __ObjAddMethod( oRs, "TOSTRING", @ADOToString() )
   __ObjAddMethod( oRs, "TONUMBER", @ADOToNumber() )
   __ObjAddMethod( oRs, "TODATE",   @ADOToDate() )
   __ObjAddMethod( oRs, "TOSTR",    @ADOToStr() )

RETURN Nil

STATIC FUNCTION ADOToDate( cField )
   LOCAL x, Self := QSelf()

   x := ::Fields( cField ):Value
   IF ValType( x ) != "D"
      x := Ctod("")
   ENDIF
RETURN x

STATIC FUNCTION ADOToString( cField, nLen )
   LOCAL x, Self := QSelf()

   x := ::Fields( cField ):Value
   IF ValType( x ) != "C"
      x := ""
   ENDIF
   IF nLen != Nil
      x := Pad( x, nLen )
   ENDIF
RETURN x

STATIC FUNCTION ADOToNumber( cField )
   LOCAL x, Self := QSelf()

   x := ::Fields( cField ):Value
   IF ValType( x ) != "N"
      x := 0
   ENDIF
RETURN x

STATIC FUNCTION ADOToStr( cField, nLen, nDec )
   LOCAL x, Self := QSelf()

   x := ::Fields( cField ):Value
   IF ValType( x ) != "N"
      x := 0
   ENDIF
   IF nLen == Nil
      x := Str( x )
   ELSEIF nDec == Nil
      x := Str( x, nLen )
   ELSE
      x := Str( x, nLen, nDec )
   ENDIF
RETURN x

FUNCTION ConexaoMySQL( cServer, cDatabase, cUser, cPassword )
       LOCAL oCn := win_OleCreateObject("ADODB.Connection")

       oCn:ConnectionString := "DRIVER={MariaDB ODBC 3.1 Driver};TCPIP=1;SERVER=" + ;
        cServer + ";Database=" + cDatabase + ";UID=" + cUser + ";PWD=" + cPassword + ";PORT=3306"
       oCn:CursorLocation   := 3
RETURN oCn


Inacio de Carvalho Neto
alxsts
Colaborador
Colaborador
Mensagens: 3092
Registrado em: 12 Ago 2008 15:50
Localização: São Paulo-SP-Brasil

tbrowse: atualização da tela

Mensagem por alxsts »

Olá!

Faça a alteração mostrada abaixo e veja se funciona.

Código: Selecionar todos

STATIC FUNCTION RotinaUsuarioItem( oRs, oBrowse, nKey )
   local nPt, dDt, cHr, cCom, cQuant
  local cod :=oRs:Fields("id"):Value

  If (upper(chr(nkey)) =="R" .or. ((us="U" .or. us="I") .and. nkey==275))

   // ...
      // ...
         // ...
            // ...
 elseif nkey==286 //Alt-A
       chmfunc("novaaltassunto",,"S")

       // Adicione esta linha abaixo
       oRs:requery()
      
   ENDIF
RETURN 1
Não sei se vai funcionar porque você criou o recordset através do método Execute da conexão (oRs := oCn:Execute( cSql )) ao invés de criar separadamente (oRs := win_OleCreateObject("ADODB.RecordSet")) e depois fazer o execute. Não sei se o oRs := oCn:Execute( cSql ) alimenta o oRS com a string de conexão que foi passada ao objeto Connection...
[]´s
Alexandre Santos (AlxSts)
cjp
Usuário Nível 6
Usuário Nível 6
Mensagens: 1563
Registrado em: 19 Nov 2010 22:29
Localização: paraná
Contato:

tbrowse: atualização da tela

Mensagem por cjp »

Resolveu, muito obrigado.
Inacio de Carvalho Neto
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

tbrowse: atualização da tela

Mensagem por JoséQuintas »

Vou testar esse também.
Aqui eu fazia o select novamente, aproveitando que a string SQL ficava na classe.

Acabo de acrescentar pra testar

Código: Selecionar todos

   METHOD Requery()                            INLINE ::Rs:Requery()
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

tbrowse: atualização da tela

Mensagem por JoséQuintas »

Adorei isso.
Muito mais rápido do que refazer o comando.
Valeu.

Nota: eu já disse por aqui que uso poucos recursos do ADO. Nem sabia que no modo adUseClient haviam mais possibilidades.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
alxsts
Colaborador
Colaborador
Mensagens: 3092
Registrado em: 12 Ago 2008 15:50
Localização: São Paulo-SP-Brasil

tbrowse: atualização da tela

Mensagem por alxsts »

Olá!
cjp escreveu:Resolveu, muito obrigado.
Se resolveu, tudo bem. Mas, o importante aqui é que você tenha entendido a questão. Poderia dizer porque não funcionava? E porque a solução aplicada resolveu o caso?
alxsts escreveu:Não sei se o oRs := oCn:Execute( cSql ) alimenta o oRS com a string de conexão que foi passada ao objeto Connection...
Se funcionou, é porque ele transfere a connection string para o recordset.
[]´s
Alexandre Santos (AlxSts)
cjp
Usuário Nível 6
Usuário Nível 6
Mensagens: 1563
Registrado em: 19 Nov 2010 22:29
Localização: paraná
Contato:

tbrowse: atualização da tela

Mensagem por cjp »

Se resolveu, tudo bem. Mas, o importante aqui é que você tenha entendido a questão. Poderia dizer porque não funcionava? E porque a solução aplicada resolveu o caso?
Não tenho certeza se entendi bem, mas vamos tentar:

Aparentemente, o os:Requery() vai refazer a query, atualizando-a, estou certo?
Antes não funcionava porque minha função alterava a tabela, mas não alterava a consulta atual.
Se eu estiver certo, a solução resolveu o caso porque agora ele está refazendo a consulta, trazendo para o tbrowse a consulta atualizada.
Está certo?
Inacio de Carvalho Neto
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

tbrowse: atualização da tela

Mensagem por JoséQuintas »

cjp escreveu:Antes não funcionava porque minha função alterava a tabela, mas não alterava a consulta atual.
Se eu estiver certo, a solução resolveu o caso porque agora ele está refazendo a consulta, trazendo para o tbrowse a consulta atualizada.
Está certo?
É isso mesmo.
O recordset não é atualizado automático.
Mas a chamada a :Requery() faz isso.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
cjp
Usuário Nível 6
Usuário Nível 6
Mensagens: 1563
Registrado em: 19 Nov 2010 22:29
Localização: paraná
Contato:

tbrowse: atualização da tela

Mensagem por cjp »

Então que bom que estou começando a entender isso.
Inacio de Carvalho Neto
alxsts
Colaborador
Colaborador
Mensagens: 3092
Registrado em: 12 Ago 2008 15:50
Localização: São Paulo-SP-Brasil

tbrowse: atualização da tela

Mensagem por alxsts »

Olá!
cjp escreveu:Está certo?
Perfeito! Dependendo das configurações do recordset, quando ele é carregado, passa a ser como uma foto (snapshot) da fonte de dados no momento da carga. Se a fonte de dados é alterada, é preciso tirar uma nova foto. Lembrando que o novo conteúdo reflete também as alterações que outros usuários fizeram, caso estejam acessando a fonte de dados.

Na prática,

Código: Selecionar todos

oRs:requery()
é o mesmo que

Código: Selecionar todos

oRs:close()
oRs:open()
[]´s
Alexandre Santos (AlxSts)
Responder