Página 2 de 3

Browse ADO com problema

Enviado: 07 Jul 2020 00:19
por cjp
Desculpe, meu caro. Não pretendia te incomodar, nem pelo Whats, nem por aqui.

Só questionei porque vejo sempre o teu interesse em ensinar, em ajudar, tanto aqui como pelo whats.

Eu mesmo já tive dezenas de ajudas tuas em várias situações, sempre muito esclarecedoras e que me ajudaram muito.

Não estou só postando meu código para você corrigir. Estou tentando aprender.

Foi vc que me estimulou a mudar de RDD para ADO. É o que estou tentando fazer. Mas, como vc pode ver, não entendo nada.

Nunca havia usado Tbrowse. Não faço ideia de como ele funciona. Comecei a usar o Browse no ADO a partir do outro post. Como não entendo de Tbrowse, apenas copiei o teu código, sem entendê-lo mesmo.

Agora estou tentando fazer outra coisa com Browse em ADO. Esta que estou fazendo agora não funcionou com o código anterior. Como o código anterior está funcionando para outra coisa, não quis mexer nele, e me propus a fazer um novo código.

Copiei o código anterior e estou tentando fazer as alterações para funcionar neste novo código. E, de fato, eu apaguei a parte que vc citou por desconhecimento, achando que ela não seria necessária.

Acresci agora esta parte, mas continua não dando certo. Não consigo nenhum movimento no browse.

Mas, como não entendo nada de Tbrowse, devo estar fazendo algo errado.

Browse ADO com problema

Enviado: 07 Jul 2020 11:48
por JoséQuintas
cjp escreveu:Acresci agora esta parte, mas continua não dando certo. Não consigo nenhum movimento no browse.
Retirou o DO WHILE que falei estar errado no que postei?

Poste o fonte atual.

Browse ADO com problema

Enviado: 07 Jul 2020 20:31
por JoséQuintas
de novo.....

Código: Selecionar todos

#include "inkey.ch"
#include "tbrowse.ch"

FUNCTION novobrowseado( nTop, nLeft, nBottom, nRight, oRs, bFuncao )

   LOCAL I, oColumn, nFieldLen, nLen, nKey, oTBrowse

   CLS

   oTBrowse := TBrowseDB():new( nTop, nLeft, nBottom, nRight )

   oTBrowse:goTopBlock    := { || oRs:moveFirst() }
   oTBrowse:goBottomBlock := { || oRs:moveLast() }
   oTBrowse:skipBlock     := { | n | ADORecordSetSkipper( oRs, n ) }
   oTBrowse:HeadSep       := Chr(196)
   oTBrowse:ColSep        := Chr(179)
   oTBrowse:FootSep       := ""

   nLen := oRs:fields():count() - 1
   FOR i := 0 TO nLen
      oColumn       := TBColumnNew( oRs:fields(i):name(), ADORecordSetFieldBlock( oRs, i ) )
      IF ValType( oRs:Fields(i):Value ) == "D"
         nFieldLen := Len( Dtoc( Date() ) )
      ELSE
         nFieldLen := Min( oRs:Fields(I):DefinedSize, 50 )
      ENDIF
      oColumn:Width := Max( nFieldLen, Len( oRs:fields(i):name ) )
      oTBrowse:addColumn( oColumn )
   NEXT
   DO WHILE .T.
      oTBrowse:forceStable()
      oTBrowse:refreshCurrent()
      nKey := Inkey(0)


      DO CASE
     CASE oTBrowse:ApplyKey( nKey )
    CASE nKey == K_ESC
      EXIT
   OTHERWISE
         IF bFuncao != NIL
            Eval( bFuncao, oTBrowse, nKey, oRs )
           oBrowse:Invalidate()
         ENDIF
      ENDCASE


   ENDDO

   RETURN .t.
Pronto.
TODAS as rotinas de tbrowse que viu, seja DBF, ADO, Array, etc. tem o tratamento de teclas.
ApplyKey - key = tecla (só lembrar de inkey), apply = aplicar

Código: Selecionar todos

      DO CASE
     CASE oTBrowse:ApplyKey( nKey )
    CASE nKey == K_ESC
      EXIT
   OTHERWISE
Como usa isso?

Tem lá seu fonte, chama passando a função

Código: Selecionar todos

#include "inkey.ch"

MEMVAR arq, cSair, prmzero, nSol

PROCEDURE Main

   LOCAL csel := "SELECT ...", Conexao, nProvTar := 1, oRs

   Conexao := Conectado( nProvTar )
   Conexao:Open()
   oRs := conexao:Execute( cSel )

   novobrowseado( 5, 3, MaxRow() - 7, MaxCol() - 2, @oRs, { | tb, k, rs | RotinaDesteBrowse( tb, k, rs ) } )

   RETURN
E na função, se limite a tratar as teclas NÃO existentes no browse.

Código: Selecionar todos

FUNCTION RotinaDesteBrowse( otb, nKey, ors )

   LOCAL opRet

   (otb)
      IF nKey = K_ENTER
         arq=oRs:Fields("nrtarefa"):Value
         chmfunc("entersql",arq,"S")
    ENDIF
Esta parte:
Porque dentro do browse, se isso tem a ver com o usuário ter fechado o browse?

Código: Selecionar todos

         @ maxrow()-1,1 prompt "Finalizar consulta"
         @ maxrow()-1,24 prompt "Reabrir mesmo item"
         @ maxrow()-1,46 prompt "Refazer mesma consulta"
         @ maxrow()-1,70 prompt "Incluir sem prioridade"
         @ maxrow()-1,94 prompt "Incluir solucionados"
         @ maxrow()-1,116 prompt "Incluir sem prioridade e solucionados"
         MENU to opret
         DO CASE
         CASE opret=0 .OR. opret=1
            cSair="S"
         CASE opret=2
            chmfunc("entersql",arq,"S")
         CASE opret=4
            prmzero="N"
         CASE opret=5
            nsol="S"
         CASE opret=6
            prmzero="N"
            nsol="T"
         ENDCASE

Browse ADO com problema

Enviado: 07 Jul 2020 20:41
por JoséQuintas
Aí... lá voltamos a rotina principal.....

Código: Selecionar todos

#include "inkey.ch"

MEMVAR arq, cSair, prmzero, nSol

PROCEDURE Main

   LOCAL csel := "SELECT ...", Conexao, nProvTar := 1, oRs

   Conexao := Conectado( nProvTar )
   Conexao:Open()

   DO WHILE .T.
      oRs := conexao:Execute( cSel )
      novobrowseado( 5, 3, MaxRow() - 7, MaxCol() - 2, @oRs, { | tb, k, rs | RotinaDesteBrowse( tb, k, rs ) } )
      oRs:Close()


         @ maxrow()-1,1 prompt "Finalizar consulta"
         @ maxrow()-1,24 prompt "Reabrir mesmo item"
         @ maxrow()-1,46 prompt "Refazer mesma consulta"
         @ maxrow()-1,70 prompt "Incluir sem prioridade"
         @ maxrow()-1,94 prompt "Incluir solucionados"
         @ maxrow()-1,116 prompt "Incluir sem prioridade e solucionados"
         MENU to opret
         DO CASE
         CASE opret=0 .OR. opret=1
            cSair="S"
         CASE opret=2
            chmfunc("entersql",arq,"S")
         CASE opret=4
            prmzero="N"
         CASE opret=5
            nsol="S"
         CASE opret=6
            prmzero="N"
            nsol="T"
         ENDCASE
   ENDDO

   RETURN
Com cada coisa no seu lugar, isso facilita, mas ISSO NÃO TEM NADA A VER COM ADO

Então... o que seria uma ajuda para duas linhas do browse, que NÃO FORAM COPIADAS, se torna refazer TUDO, porque TUDO ESTÁ FORA DO LUGAR.

É por isso que uma exigência no Harbour-users é transformar a rotina em uma pequena rotina, bem simples, porque ao fazer isso, o usuário geralmente enxerga o erro que cometeu, e resolve sozinho.

Fonte fácil, solução fácil, ajuda fácil.
Fonte complicado.... complica fonte, complica programador, complica ajuda, complica localizar erro, complica tudo.

Browse ADO com problema

Enviado: 07 Jul 2020 21:02
por JoséQuintas
Antes que alguém comente:

Isso não tem a ver com conhecer mais, ou conhecer menos.
Apenas organizei o fonte, e dividi "por assunto".
Com o fonte organizado, e blocos menores, o problema/solução fica mais visível.
Usei os comandos/funções comuns que já estavam no fonte, nada extraordinário.
A exceção talvez seja o codeblock, pra passar a função de usuário.

De um modo geral, qualquer um tem condições de fazer isso, afinal, quem melhor do que o dono do fonte pra organizar o próprio fonte.
Se nunca organizar, nunca vai ficar organizado, e nunca vai se preocupar em organizar.
O resultado de não organizar fica bem visível: passa a ser normal considerar que ser complicado é normal, ou que não consegue fazer porque é complicado.

Sobre os parâmetros recebidos pelo fonte.... vixe... aí teria que olhar o resto do aplicativo pra entender, e talvez ter que organizar todo aplicativo.

Mas isso daí é só começar: começou a organizar/descomplicar, começa a entender o que faz, e com o tempo passa a considerar tudo simples.
Provavelmente vai resolver muito problema que não conseguia resolver ou que não tinha visto antes.

E aproveitando:
Não dá pra resolver o problema? ok... ao invés de quebrar a cabeça.... dá uma organizada no fonte primeiro.
Isso já "refresca" um pouco a cabeça, e pode facilitar encontrar solução.

De certa forma, é o que venho fazendo na minha migração pra SQL: vou deixando os complicados pra depois... ou pra quando a cabeça estiver mais tranquila e enxergando uma solução..

Browse ADO com problema

Enviado: 08 Jul 2020 00:02
por cjp
Sem dúvida assim fica muito mais claro.

Ainda preciso aprender muito, sobretudo a respeito de duas coisas que não entendo nada: recordset e tBrowse.

Testei do jeito que vc postou, mas está dando "erro nos parâmetros: condicional".

É provável que eu não tenha entendido corretamente tua postagem. Pra conferir, veja como fiz:

Código: Selecionar todos

		       conexao := conexADO(nProvTar)
               IF AbreADO( conexao )
                  DO WHILE .T.
                     oRs=conexao:Execute( cSel )
                     novobrowseado( 5, 3, MaxRow() - 7, MaxCol() - 2, @oRs, { | tb, k, rs | RotinaDesteBrowse( tb, k, rs ) } )
                     oRs:Close()
					 conexao:Close()

                     @ maxrow()-1,1 prompt "Finalizar consulta"
                     @ maxrow()-1,24 prompt "Reabrir mesmo item"
                     @ maxrow()-1,46 prompt "Refazer mesma consulta"
                     @ maxrow()-1,70 prompt "Incluir sem prioridade"
                     @ maxrow()-1,94 prompt "Incluir solucionados"
                     @ maxrow()-1,116 prompt "Incluir sem prioridade e solucionados"
                     MENU to opret
                     DO CASE
                        CASE opret=0 .OR. opret=1
                             cSair="S"
						     exit
                        CASE opret=2
                             chmfunc("entersql",cArqAtiv,"S")
                        CASE opret=4
                             prmzero="N"
                        CASE opret=5
                             nsol="S"
                        CASE opret=6
                             prmzero="N"
                             nsol="T"
                     ENDCASE
                  ENDDO
               Endif




FUNCTION RotinaDesteBrowse( otb, nKey, ors )

   LOCAL opRet

   (otb)
      IF nKey = K_ENTER
         arq=oRs:Fields("nrtarefa"):Value
         chmfunc("entersql",arq,"S")
    ENDIF
Return
	
	
#include "inkey.ch"
#include "tbrowse.ch"

FUNCTION novobrowseado( nTop, nLeft, nBottom, nRight, oRs, bFuncao )

   LOCAL I, oColumn, nFieldLen, nLen, nKey, oTBrowse

   CLS

   oTBrowse := TBrowseDB():new( nTop, nLeft, nBottom, nRight )

   oTBrowse:goTopBlock    := { || oRs:moveFirst() }
   oTBrowse:goBottomBlock := { || oRs:moveLast() }
   oTBrowse:skipBlock     := { | n | ADORecordSetSkipper( oRs, n ) }
   oTBrowse:HeadSep       := Chr(196)
   oTBrowse:ColSep        := Chr(179)
   oTBrowse:FootSep       := ""

   nLen := oRs:fields():count() - 1
   FOR i := 0 TO nLen
      oColumn       := TBColumnNew( oRs:fields(i):name(), ADORecordSetFieldBlock( oRs, i ) )
      IF ValType( oRs:Fields(i):Value ) == "D"
         nFieldLen := Len( Dtoc( Date() ) )
      ELSE
         nFieldLen := Min( oRs:Fields(I):DefinedSize, 50 )
      ENDIF
      oColumn:Width := Max( nFieldLen, Len( oRs:fields(i):name ) )
      oTBrowse:addColumn( oColumn )
   NEXT
   DO WHILE .T.
      oTBrowse:forceStable()
      oTBrowse:refreshCurrent()
      nKey := Inkey(0)

      DO CASE
     CASE oTBrowse:ApplyKey( nKey )
    CASE nKey == K_ESC
      EXIT
   OTHERWISE
         IF bFuncao != NIL
            Eval( bFuncao, oTBrowse, nKey, oRs )
           oBrowse:Invalidate()
         ENDIF
      ENDCASE

   ENDDO

   RETURN .t.

Browse ADO com problema

Enviado: 08 Jul 2020 00:59
por alxsts
Olá!
cjp escreveu:Testei do jeito que vc postou, mas está dando "erro nos parâmetros: condicional".
Faltou formular a condição corretamente:

Código: Selecionar todos

IF oTBrowse:applyKey( nKey ) == TBR_EXIT
A linha 37 também não faz sentido: 37 (otb)

Ajuda sobre o método :applyKey() - lembrando que isso veio com o [x]Harbour. Em Clipper, tínhamos que codificar as ações relacionadas a cada tecla padrão.
oTBrowse:applyKey()

Evaluates a code block associated with a navigation key.

Syntax
:applyKey( <nInkey> ) --> nReturnCode

Arguments
<nInkey>
This is a numeric Inkey() code to be processed by a TBrowse object. Description

Description
Method :applyKey() instructs a TBrowse object to process user input obtained from function Inkey(). The return value is a numeric code that indicates whether or not the stabilization loop must be terminated. #define constants are listed in the file TBrowse.ch that can be used to test possible return values of :applyKey().

Return values of :applyKey()

Constant Value Description
TBR_EXIT -1 User request for the browse to lose input focus
TBR_CONTINUE 0 Code block associated with <nInkey> was evaluated
TBR_EXCEPTION 1 <nInkey> is unknown, key was not processed

A TBrowse object maintains a :setKey() dictionary of Inkey() codes and associated code blocks that perform default navigation. The default key processing is as follows:

Default key processing

Inkey code Method or function Return code
K_DOWN :down() TBR_CONTINUE
K_UP :up() TBR_CONTINUE
K_RIGHT :right() TBR_CONTINUE
K_LEFT :left() TBR_CONTINUE
K_CTRL_LEFT :panLeft() TBR_CONTINUE
K_CTRL_RIGHT :panRight() TBR_CONTINUE
K_END :end() TBR_CONTINUE
K_HOME :home() TBR_CONTINUE
K_CTRL_END :panEnd() TBR_CONTINUE
K_CTRL_HOME :panHome() TBR_CONTINUE
K_PGDN :pageDown() TBR_CONTINUE
K_PGUP :pageUp() TBR_CONTINUE
K_CTRL_PGDN :goBottom() TBR_CONTINUE
K_CTRL_PGUP :goTop() TBR_CONTINUE
K_ESC None TBR_EXIT
K_LBUTTONDOWN TBMouse() see below
other codes TBR_EXCEPTION

When the browse display is clicked with the mouse and a data cell is hit, :applyKey() returns TBR_CONTINUE. If no data is hit, the return code is TBR_EXCEPTION.

Fonte: xHarbour Language Reference Guide
Exemplos básicos, retirados da mesma fonte:

Código: Selecionar todos

// The example demonstrates the steps required for creating a
// browse view for a two dimensional array. Note that the data
// source and row pointer of the data source are stored in
// oTBrowse:cargo. The pseudo instance variables :data and :recno
// are translated by the preprocessor.

   #include "TBrowse.ch"

   #xtrans  :data   =>   :cargo\[1]
   #xtrans  :recno  =>   :cargo\[2]

   PROCEDURE Main
      LOCAL i, nKey, bBlock, oTBrowse, oTBColumn
      LOCAL aHeading := { "File Name", ;
                          "File Size", ;
                          "File Date", ;
                          "File Time", ;
                          "File Attr"  }
      LOCAL aWidth := { 20, 10, 9, 9, 9 }

      // Create TBrowse object
      // data source is the Directory() array
      oTBrowse := TBrowse():new( 2, 2, MaxRow()-2, MaxCol()-2 )
      oTBrowse:cargo         := { Directory( "*.*" ), 1 }

      oTBrowse:headSep       := "-"
      oTBrowse:colorSpec     := "N/BG,W+/R"

      // Navigation code blocks for array
      oTBrowse:goTopBlock    := {|| oTBrowse:recno := 1 }
      oTBrowse:goBottomBlock := {|| oTBrowse:recno := Len( oTBrowse:data ) }
      oTBrowse:skipBlock     := {|nSkip| ArraySkipper( nSkip, oTBrowse ) }

      // create TBColumn objects and add them to TBrowse object
      FOR i:=1 TO Len( aHeading )

         // code block for individual columns of the array
         bBlock    := ArrayBlock( oTBrowse, i )

         oTBColumn := TBColumn():new( aHeading[i], bBlock )
         oTBColumn:width := aWidth[i]

         oTBrowse:addColumn( oTBColumn )
      NEXT

      // display browser and process user input
      DO WHILE .T.
         oTBrowse:forceStable()
         nKey := Inkey(0)

         IF oTBrowse:applyKey( nKey ) == TBR_EXIT
            EXIT
         ENDIF
      ENDDO

   RETURN

   // This code block uses detached LOCAL variables to
   // access single elements of a two-dimensional array.
   FUNCTION ArrayBlock( oTBrowse, nSubScript )
   RETURN {|| oTBrowse:data[ oTBrowse:recno, nSubScript ] }

   // This function navigates the row pointer of the
   // the data source (array)
   FUNCTION ArraySkipper( nSkipRequest, oTBrowse )
      LOCAL nSkipped
      LOCAL nLastRec := Len( oTBrowse:data ) // Length of array

      IF oTBrowse:recno + nSkipRequest < 1
         // skip requested that navigates past first array element
         nSkipped := 1 - oTBrowse:recno

      ELSEIF oTBrowse:recno + nSkipRequest > nLastRec
         // skip requested that navigates past last array element
         nSkipped := nLastRec - oTBrowse:recno

      ELSE
         // skip requested that navigates within array
         nSkipped := nSkipRequest
      ENDIF

      // adjust row pointer
      oTBrowse:recno += nSkipped

   // tell TBrowse how many rows are actually skipped.
   RETURN nSkipped
Função relacionada:
TBMouse()
Moves the browse cursor to the mouse pointer.

Syntax
TBMouse( <oTBrowse>, <nMouseRow>, <nMouseCol> ) --> nHandled

Arguments
<oTBrowse>
This parameter must be a TBrowse() object.
<nMouseRow>
A numeric value between 0 and MaxRow() specifying the row position of the mouse cursor. It can be queried using MRow().
<nMouseCol>
A numeric value between 0 and MaxCol() specifying the columnn position of the mouse cursor. It can be queried using MCol(). Return
The function returns 0 when the browse cursor was successfully moved to the screen coordinates passed for the mouse pointer. Otherwise, the return value is 1.

Description
TBMouse() is a utiliy function for implementing "mouse awareness" for TBrowse objects. When the mouse pointer is located within the data area of a TBrowse object, the function calls navigation methods of the object until the browse cursor is located underneath the screen coordinates specified with <nMouseRow> and <nMouseCol>.
A call to TBMouse() is standard behavior for TBrowse():applyKey().

Browse ADO com problema

Enviado: 08 Jul 2020 08:57
por JoséQuintas
alxsts escreveu:A linha 37 também não faz sentido: 37 (otb)
Isso é o mesmo que HB_SYMBOL_UNUSED( otb )

É só "fingindo" que usa a variável, pra não dar erro na compilação por falta de uso. ( compilação -w3 -es2 )
Não serve pra nada, a não ser pra isso.


E não cheguei a executar, porque faltaria tudo do fonte, base de dados, mysql, etc.

Browse ADO com problema

Enviado: 08 Jul 2020 09:21
por cjp
Resolveu, obrigado.
Mas tem um problema que ainda não consegui resolver: não consigo sair do Browse com ESC (nem de nenhuma outra forma).
Até tentei acrescer

Código: Selecionar todos

      ELSEIF nKey = K_ESC
	     return
na FUNCTION RotinaDesteBrowse( otb, nKey, ors ), mas mesmo assim não sai.

Outra questão: a ideia inicial é executar o menu

Código: Selecionar todos

                     @ maxrow()-1,1 prompt "Finalizar consulta"
                     @ maxrow()-1,24 prompt "Reabrir mesmo item"
                     @ maxrow()-1,46 prompt "Refazer mesma consulta"
                     @ maxrow()-1,70 prompt "Incluir sem prioridade"
                     @ maxrow()-1,94 prompt "Incluir solucionados"
                     @ maxrow()-1,116 prompt "Incluir sem prioridade e solucionados"
quando volta do

Código: Selecionar todos

      IF nKey = K_ENTER
         cArqAtiv=oRs:Fields("nrtarefa"):Value
         chmfunc("entersql",,"S")
antes de reabrir o browse. Não sei se isso é possível, mas era isso que eu estava desde o início tentando fazer. Isso não está acontecendo. É possível fazer isso?

Browse ADO com problema

Enviado: 08 Jul 2020 10:46
por JoséQuintas
cjp escreveu:Resolveu, obrigado.
Mas tem um problema que ainda não consegui resolver: não consigo sair do Browse com ESC (nem de nenhuma outra forma).
Até tentei acrescer

1       ELSEIF nKey = K_ESC
2         return
3  
Sair do browse.... é na rotina de browse, já tem lá pra ESC sair
cjp escreveu:antes de reabrir o browse. Não sei se isso é possível, mas era isso que eu estava desde o início tentando fazer. Isso não está acontecendo. É possível fazer isso?
A sua pergunta é a sua solução.
À primeira vista, precisa sair do browse não importa se teclar ENTER ou ESC

Mas... não sai do browse, ou não sai da rotina?
Se pensar direito.... o DO WHILE da primeira rotina ficou sem opção de sair.

Browse ADO com problema

Enviado: 08 Jul 2020 10:55
por JoséQuintas
Esqueça a função de usuário, apenas altere pra sair com ENTER ou ESC

Código: Selecionar todos

/*
   LOCAL csel := "SELECT ...", Conexao, nProvTar := 1, oRs

   Conexao := Conectado( nProvTar )
   Conexao:Open()
   oRs := conexao:Execute( cSel )

   DO WHILE .T.
      novobrowseado( 5, 3, MaxRow() - 7, MaxCol() - 2, @oRs )
   IF nKey == K_ENTER
      arq := oRs:Fields( "nrtarefa" ):Value
   ENDIF
   oRs:Close()
   IF nKey = K_ENTER
         chmfunc("entersql",arq,"S")
      ELSEIF nKey == K_ESC
         @ maxrow()-1,1 prompt "Finalizar consulta"
         @ maxrow()-1,24 prompt "Reabrir mesmo item"
         @ maxrow()-1,46 prompt "Refazer mesma consulta"
         @ maxrow()-1,70 prompt "Incluir sem prioridade"
         @ maxrow()-1,94 prompt "Incluir solucionados"
         @ maxrow()-1,116 prompt "Incluir sem prioridade e solucionados"
         MENU to opret
         DO CASE
         CASE opret=0 .OR. opret=1
            EXIT
         CASE opret=2
            chmfunc("entersql",arq,"S")
         CASE opret=4
            prmzero="N"
         CASE opret=5
            nsol="S"
         CASE opret=6
            prmzero="N"
            nsol="T"
         ENDCASE
         EXIT
      ENDIF
   ENDDO

   RETURN NIL
E no browse genérico, seja ENTER ou ESC encerra.

Browse ADO com problema

Enviado: 08 Jul 2020 22:09
por MSDN
Quintas, vc vai pro céu e não faz nem curva...arebaba !

Browse ADO com problema

Enviado: 08 Jul 2020 22:59
por cjp
Ainda não funcionou assim. O browse está travado.
Me parece que ele está preso no do while da função principal, que só trata as teclas Enter e ESC. Daí não dá pra movimentar no browse.
Veja se fiz alguma besteira, por favor:

Código: Selecionar todos

		       conexao := conexADO(nProvTar)
               IF AbreADO( conexao )
                  oRs=conexao:execute(cSel)

   DO WHILE .T.
      novobrowseado( 5, 3, MaxRow() - 7, MaxCol() - 2, @oRs )
   IF nKey == K_ENTER
      cArqAtiv := oRs:Fields( "nrtarefa" ):Value
   ENDIF
   IF nKey = K_ENTER
         chmfunc("entersql",,"S")
      ELSEIF nKey == K_ESC
         @ maxrow()-1,1 prompt "Finalizar consulta"
         @ maxrow()-1,24 prompt "Reabrir mesmo item"
         @ maxrow()-1,46 prompt "Refazer mesma consulta"
         @ maxrow()-1,70 prompt "Incluir sem prioridade"
         @ maxrow()-1,94 prompt "Incluir solucionados"
         @ maxrow()-1,116 prompt "Incluir sem prioridade e solucionados"
         MENU to opret
         DO CASE
         CASE opret=0 .OR. opret=1
            EXIT
         CASE opret=2
            chmfunc("entersql",arq,"S")
         CASE opret=4
            prmzero="N"
         CASE opret=5
            nsol="S"
         CASE opret=6
            prmzero="N"
            nsol="T"
         ENDCASE
         EXIT
      ENDIF
   ENDDO
   oRs:Close()


FUNCTION novobrowseado( nTop, nLeft, nBottom, nRight, oRs, bFuncao )

   LOCAL I, oColumn, nFieldLen, nLen, nKey, oTBrowse

   CLS

   oTBrowse := TBrowseDB():new( nTop, nLeft, nBottom, nRight )

   oTBrowse:goTopBlock    := { || oRs:moveFirst() }
   oTBrowse:goBottomBlock := { || oRs:moveLast() }
   oTBrowse:skipBlock     := { | n | ADORecordSetSkipper( oRs, n ) }
   oTBrowse:HeadSep       := Chr(196)
   oTBrowse:ColSep        := Chr(179)
   oTBrowse:FootSep       := ""

   nLen := oRs:fields():count() - 1
   FOR i := 0 TO nLen
      oColumn       := TBColumnNew( oRs:fields(i):name(), ADORecordSetFieldBlock( oRs, i ) )
      IF ValType( oRs:Fields(i):Value ) == "D"
         nFieldLen := Len( Dtoc( Date() ) )
      ELSE
         nFieldLen := Min( oRs:Fields(I):DefinedSize, 50 )
      ENDIF
      oColumn:Width := Max( nFieldLen, Len( oRs:fields(i):name ) )
      oTBrowse:addColumn( oColumn )
   NEXT
*   DO WHILE .T.
      oTBrowse:forceStable()
      oTBrowse:refreshCurrent()
      nKey := Inkey(0)

      DO CASE
     CASE oTBrowse:ApplyKey( nKey ) == TBR_EXIT
*    CASE nKey == K_ESC
*      EXIT
   OTHERWISE
         IF bFuncao != NIL
            Eval( bFuncao, oTBrowse, nKey, oRs )
           oTBrowse:Invalidate()
         ENDIF
      ENDCASE

*   ENDDO

RETURN .t.

Browse ADO com problema

Enviado: 09 Jul 2020 01:28
por alxsts
Olá!

Que tópico confuso... segue mais uma tentativa de jogar luz. Na primeira, acho que a lâmpada queimou...

Código: Selecionar todos

FUNCTION MenosConfusa( nTop, nLeft, nBottom, nRight, oRs, bFuncao )

   // FAÇA TUDO NESTA FUNÇÃO. NÃO PRECISA DE FUNÇÃO SEPARADA COMO novobrowseado

   LOCAL I, oColumn, nFieldLen, nLen, nKey, oTBrowse

   CLS

   oTBrowse := TBrowseDB():new( nTop, nLeft, nBottom, nRight )

   oTBrowse:goTopBlock    := { || oRs:moveFirst() }
   oTBrowse:goBottomBlock := { || oRs:moveLast() }
   oTBrowse:skipBlock     := { | n | ADORecordSetSkipper( oRs, n ) }
   oTBrowse:HeadSep       := Chr(196)
   oTBrowse:ColSep        := Chr(179)
   oTBrowse:FootSep       := ""

//---------------------------------------------------------
   Concte no banco aqui
   selecione os dados, gerando assim o record set
//---------------------------------------------------------   

   nLen := oRs:fields():count() - 1

   FOR i := 0 TO nLen
      oColumn       := TBColumnNew( oRs:fields(i):name(), ADORecordSetFieldBlock( oRs, i ) )
      IF ValType( oRs:Fields(i):Value ) == "D"
         nFieldLen := Len( Dtoc( Date() ) )
      ELSE
         nFieldLen := Min( oRs:Fields(I):DefinedSize, 50 )
      ENDIF
      oColumn:Width := Max( nFieldLen, Len( oRs:fields(i):name ) )
      oTBrowse:addColumn( oColumn )
   NEXT

   DO WHILE .T.
      oTBrowse:forceStable()
      nKey := Inkey(0)

      DO CASE
         CASE oTBrowse:ApplyKey( nKey ) == TBR_EXIT           // ------------------------  PROCESSA TECLAS PADRÃO

            // É aqui que tem que exibir o tal menu?
            // Se sim, exiba aqui...

            Savescreen()

            @ maxrow()-1,1 prompt "Finalizar consulta"
            @ maxrow()-1,24 prompt "Reabrir mesmo item"
            @ maxrow()-1,46 prompt "Refazer mesma consulta"
            @ maxrow()-1,70 prompt "Incluir sem prioridade"
            @ maxrow()-1,94 prompt "Incluir solucionados"
            @ maxrow()-1,116 prompt "Incluir sem prioridade e solucionados"            

            MENU to opret

            DO CASE
               CASE opret=0 .OR. opret=1
                    cSair="S"

                    EXIT

               CASE opret=2
                    chmfunc("entersql",cArqAtiv,"S")
               CASE opret=4
                    prmzero="N"
               CASE opret=5
                    nsol="S"
               CASE opret=6
                    prmzero="N"
                    nsol="T"
            ENDCASE
            
            RestScreen()
            
            // Se não é aqui que exibe o menu, cai fora...

            EXIT  // oTBrowse:ApplyKey( nKey ) == TBR_EXIT

         CASE oTBrowse:ApplyKey( nKey ) == TBR_EXCEPTION     // ------------------------  PROCESSA TECLAS DE EXCEÇÃO
            // teclou alguma coisa diferente de ESC e das teclas tratadas por padrão...
            // Então trate as teclas que precisa...
            DO CASE
               CASE nKey == K_ENTER
                  // faça o que precisa no ENTER
               CASE nKey == K_ALGUMA COISA
                  FAÇA ALGUMA COISA...
            ENDCASE

         OTHERWISE
            IF bFuncao != NIL
               Eval( bFuncao, oTBrowse, nKey, oRs )
               oTBrowse:Invalidate()   // Sei lá pra que isso...
            ENDIF
      ENDCASE
   ENDDO

RETURN .t.

Browse ADO com problema

Enviado: 09 Jul 2020 09:24
por JoséQuintas
Sim, fez uma enorme besteira.
Bloqueou toda navegação

Código: Selecionar todos

*   DO WHILE .T.
      oTBrowse:forceStable()
      oTBrowse:refreshCurrent()
      nKey := Inkey(0)

      DO CASE
     CASE oTBrowse:ApplyKey( nKey ) == TBR_EXIT
*    CASE nKey == K_ESC
*      EXIT
   OTHERWISE
         IF bFuncao != NIL
            Eval( bFuncao, oTBrowse, nKey, oRs )
           oTBrowse:Invalidate()
         ENDIF
      ENDCASE

*   ENDDO

e eu também, faltou pegar a tecla, que acusaria erro na compilação -w3 -es2
Mas isto não afeta navegação.

Código: Selecionar todos

      novobrowseado( 5, 3, MaxRow() - 7, MaxCol() - 2, @oRs )
nKey := LastKey()
   IF nKey == K_ENTER

Talvez aqui: como não uso isso, talvez não esteja certo
Na dúvida, tire fora do DO CASE

Código: Selecionar todos

oTBrowse:ApplyKey( nKey )
IF nKey == K_ENTER .OR. nKey == K_ESC
   EXIT
ENDIF