Página 1 de 3

Browse ADO com problema

Enviado: 05 Jul 2020 06:37
por JoséQuintas
a que vc me passou está funcionando bem, o problema não é nela; o problema é na que estou fazendo agora, para outra coisa
minha função está assim:

Código: Selecionar todos

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

               novobrowseado()
			   
			   do while .t.
                  oTBrowse:forceStable()
                  oTBrowse:refreshCurrent()
                  nKey := Inkey(0)
				  
			      if lastkey()=13
		             arq=oRs:Fields("nrtarefa"):Value
	                 chmfunc("entersql",arq,"S")
			      elseif lastkey()=27
			         @ 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
					 exit
			      endif
			   enddo
e a função novobrowseado() está assim:

Código: Selecionar todos

function novobrowseado
         #include "tbrowse.ch"
		 
		 keysec(27,1000,-1,.t.)
   
            cls
			
            oTBrowse := TBrowseDB():new( 05, 3, MaxRow() - 7, MaxCol() - 2 )

            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

	        @ 5,5 say "Abrindo consulta..."
return .t.
eu devo estar fazendo algo errado, pois não estou conseguindo mover dentro do browse com as setas

Browse ADO com problema

Enviado: 05 Jul 2020 06:49
por JoséQuintas
1 - se a que passei é genérica, e funciona pra qualquer coisa, porque criar uma nova?

2 - mesmo assim, se a outra funciona.... é só olhar na outra, pra ver o que esqueceu de copiar

Browse ADO com problema

Enviado: 05 Jul 2020 07:02
por JoséQuintas
Mesmo assim, vamos aproveitar e corrigir o fonte.
O melhor negócio é.... perguntar pro Harbour
hbmk2 -test -w3 -es2
test.prg:5: warning W0001 Ambiguous reference 'NPROVTAR'
test.prg:5: warning W0001 Ambiguous reference 'CONEXAO'
test.prg:6: warning W0001 Ambiguous reference 'CONEXAO'
test.prg:7: warning W0001 Ambiguous reference 'CONEXAO'
test.prg:7: warning W0001 Ambiguous reference 'CSEL'
test.prg:7: warning W0001 Ambiguous reference 'ORS'
test.prg:12: warning W0001 Ambiguous reference 'OTBROWSE'
test.prg:13: warning W0001 Ambiguous reference 'OTBROWSE'
test.prg:14: warning W0001 Ambiguous reference 'NKEY'
test.prg:17: warning W0001 Ambiguous reference 'ORS'
test.prg:17: warning W0001 Ambiguous reference 'ARQ'
test.prg:18: warning W0001 Ambiguous reference 'ARQ'
test.prg:26: warning W0001 Ambiguous reference 'OPRET'
test.prg:26: warning W0001 Ambiguous reference 'OPRET'
test.prg:26: warning W0001 Ambiguous reference 'OPRET'
test.prg:28: warning W0001 Ambiguous reference 'OPRET'
test.prg:28: warning W0001 Ambiguous reference 'OPRET'
test.prg:29: warning W0001 Ambiguous reference 'CSAIR'
test.prg:30: warning W0001 Ambiguous reference 'OPRET'
test.prg:31: warning W0001 Ambiguous reference 'ARQ'
test.prg:32: warning W0001 Ambiguous reference 'OPRET'
test.prg:33: warning W0001 Ambiguous reference 'PRMZERO'
test.prg:34: warning W0001 Ambiguous reference 'OPRET'
test.prg:35: warning W0001 Ambiguous reference 'NSOL'
test.prg:36: warning W0001 Ambiguous reference 'OPRET'
test.prg:37: warning W0001 Ambiguous reference 'PRMZERO'
test.prg:38: warning W0001 Ambiguous reference 'NSOL'
test.prg:52: warning W0001 Ambiguous reference 'OTBROWSE'
test.prg:54: warning W0001 Ambiguous reference 'OTBROWSE'
test.prg:54: warning W0001 Ambiguous reference 'ORS'
test.prg:55: warning W0001 Ambiguous reference 'OTBROWSE'
test.prg:55: warning W0001 Ambiguous reference 'ORS'
test.prg:56: warning W0001 Ambiguous reference 'OTBROWSE'
test.prg:56: warning W0001 Ambiguous reference 'ORS'
test.prg:57: warning W0001 Ambiguous reference 'OTBROWSE'
test.prg:58: warning W0001 Ambiguous reference 'OTBROWSE'
test.prg:59: warning W0001 Ambiguous reference 'OTBROWSE'
test.prg:61: warning W0001 Ambiguous reference 'ORS'
test.prg:61: warning W0001 Ambiguous reference 'NLEN'
test.prg:62: warning W0001 Ambiguous reference 'I'
test.prg:63: warning W0001 Ambiguous reference 'ORS'
test.prg:63: warning W0001 Ambiguous reference 'I'
test.prg:63: warning W0001 Ambiguous reference 'ORS'
test.prg:63: warning W0001 Ambiguous reference 'I'
test.prg:63: warning W0001 Ambiguous reference 'OCOLUMN'
test.prg:64: warning W0001 Ambiguous reference 'ORS'
test.prg:64: warning W0001 Ambiguous reference 'I'
test.prg:65: warning W0001 Ambiguous reference 'NFIELDLEN'
test.prg:67: warning W0001 Ambiguous reference 'ORS'
test.prg:67: warning W0001 Ambiguous reference 'I'
test.prg:67: warning W0001 Ambiguous reference 'NFIELDLEN'
test.prg:69: warning W0001 Ambiguous reference 'OCOLUMN'
test.prg:69: warning W0001 Ambiguous reference 'NFIELDLEN'
test.prg:69: warning W0001 Ambiguous reference 'ORS'
test.prg:69: warning W0001 Ambiguous reference 'I'
test.prg:70: warning W0001 Ambiguous reference 'OTBROWSE'
test.prg:70: warning W0001 Ambiguous reference 'OCOLUMN'
test.prg:71: warning W0001 Ambiguous reference 'I'
test.prg:71: warning W0001 Ambiguous reference 'I'
test.prg:71: warning W0001 Ambiguous reference 'NLEN'
ok, variáveis que não se sabe de onde vém, nem pra onde vão.

Browse ADO com problema

Enviado: 05 Jul 2020 07:10
por JoséQuintas
Numa formatação e declaração rápida, chega-se nisto:
test.prg:11: warning W0001 Ambiguous reference 'ORS'
test.prg:16: warning W0001 Ambiguous reference 'OTBROWSE'
test.prg:17: warning W0001 Ambiguous reference 'OTBROWSE'
test.prg:21: warning W0001 Ambiguous reference 'ORS'
test.prg:50: warning W0032 Variable 'NKEY' is assigned but not used in function '18:MAIN'
test.prg:58: warning W0001 Ambiguous reference 'OTBROWSE'
test.prg:60: warning W0001 Ambiguous reference 'OTBROWSE'
test.prg:60: warning W0001 Ambiguous reference 'ORS'
test.prg:61: warning W0001 Ambiguous reference 'OTBROWSE'
test.prg:61: warning W0001 Ambiguous reference 'ORS'
test.prg:62: warning W0001 Ambiguous reference 'OTBROWSE'
test.prg:62: warning W0001 Ambiguous reference 'ORS'
test.prg:63: warning W0001 Ambiguous reference 'OTBROWSE'
test.prg:64: warning W0001 Ambiguous reference 'OTBROWSE'
test.prg:65: warning W0001 Ambiguous reference 'OTBROWSE'
test.prg:67: warning W0001 Ambiguous reference 'ORS'
test.prg:69: warning W0001 Ambiguous reference 'ORS'
test.prg:69: warning W0001 Ambiguous reference 'ORS'
test.prg:70: warning W0001 Ambiguous reference 'ORS'
test.prg:73: warning W0001 Ambiguous reference 'ORS'
test.prg:75: warning W0001 Ambiguous reference 'ORS'
test.prg:76: warning W0001 Ambiguous reference 'OTBROWSE'
Ok, restaram as variáveis usadas no módulo e na função, portanto precisam de solução especial pra existir nos dois.

PRIVATE? NÃO, LOCAL e passar por referência pra função.

Browse ADO com problema

Enviado: 05 Jul 2020 07:14
por JoséQuintas
Alteramos aqui:

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

aqui

novobrowseado( @oTBrowse, @oRs )

e aqui

FUNCTION novobrowseado( oTBrowse, oRs )

agora só resta esta:
test.prg:50: warning W0032 Variable 'NKEY' is assigned but not used in function '18:MAIN'
É lógico, se atribui nKey a uma variável, pra não usar pra nada.... pra que a variável?

Browse ADO com problema

Enviado: 05 Jul 2020 07:16
por JoséQuintas
Então, já que a variável existe, alteramos aqui:

Código: Selecionar todos

      nKey := Inkey(0)
      IF nKey = K_ENTER
         arq=oRs:Fields("nrtarefa"):Value
         chmfunc("entersql",arq,"S")
      ELSEIF nKey == K_ESC
c:/temp/test.o:test.c:(.data+0x38): undefined reference to `HB_FUN_CONECTADO'
c:/temp/test.o:test.c:(.data+0xd8): undefined reference to `HB_FUN_CHMFUNC'
c:/temp/test.o:test.c:(.data+0x158): undefined reference to `HB_FUN_KEYSEC'
c:/temp/test.o:test.c:(.data+0x208): undefined reference to `HB_FUN_ADORECORDSETSKIPPER'
c:/temp/test.o:test.c:(.data+0x278): undefined reference to `HB_FUN_ADORECORDSETFIELDBLOCK'
Pronto, isso tem a ver com o aplicativo e/ou rotinas que não estão nesse fonte.

Browse ADO com problema

Enviado: 05 Jul 2020 07:20
por JoséQuintas
Agora vamos alterar pra genérica.
Primeira coisa que pode mudar: posições

Alteramos aqui:

Código: Selecionar todos

   novobrowseado( 5, 3, MaxRow() - 7, MaxCol() - 2, @oTBrowse, @oRs )
e aqui:

Código: Selecionar todos

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

Browse ADO com problema

Enviado: 05 Jul 2020 07:32
por gilbertosilverio
Olá Quintas,
do while .t.
oTBrowse:forceStable()
oTBrowse:refreshCurrent()
Nos meus dbedit(), a tempos, tinha um problema parecido, inclui estas linhas e funcionou...

Código: Selecionar todos

      oBrw:REFRESHALL()
      oBrw:Stabilize()
Tenta pra ver no que da...

Do help do harbour...
:ForceStable() Performs a full stabilization
:GetColumn( nColumn ) Gets a specific TBColumn() object
:Hilite() Highlights the current cell
:InsColumn( nPos, oCol ) Insert a column object in a browse
:Invalidate() Forces entire redraw during next stabilization
:RefreshAll() Causes all data to be recalculated during the next stabilize
:RefreshCurrent() Causes the current row to be refilled and repainted on next stabilize
:SetColumn( nColumn, oCol ) Replaces one TBColumn() object with another
:Stabilize() Performs incremental stabilization
Faz tanto tempo, que não lembro mais onde vi esta sugestão...

Browse ADO com problema

Enviado: 05 Jul 2020 07:33
por JoséQuintas
é um usuário perguntando pelo whatsapp

A próxima:
O Browse fazer tudo e passar função de usuário:

Código: Selecionar todos

   novobrowseado( 5, 3, MaxRow() - 7, MaxCol() - 2, @oTBrowse, @oRs, { || RotinaDesteBrowse( tb, k, rs ) )
Pronto.
Agora é ajustar as variáveis para o novo fonte.

Browse ADO com problema

Enviado: 05 Jul 2020 07:36
por JoséQuintas
O novo fonte ajustado para um browse genérico.

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

FUNCTION RotinaDesteBrowse( otb, nKey, ors )

   LOCAL opRet

   (otb)
   DO WHILE .t.

      IF nKey = K_ENTER
         arq=oRs:Fields("nrtarefa"):Value
         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
            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
         EXIT
      ENDIF
   ENDDO

   RETURN NIL

#include "tbrowse.ch"

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

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

   keysec(27,1000,-1,.t.)

   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
      OTHERWISE
         IF bFuncao != NIL
            Eval( bFuncao, oTBrowse, nKey, oRs )
         ENDIF
      ENDCASE
   ENDDO


   RETURN .t.
E... como eu já disse... só copiar o que falta PARA O BROWSE, da rotina que funciona
Sem tratamento de teclas, não tem funcionamento de teclas... é simples assim.

Browse ADO com problema

Enviado: 05 Jul 2020 07:39
por JoséQuintas
Considerações adicionais:

chamar de CSEL, o que é comando SQL.... esquisito....

chamar de Conectado() o que seria uma conexao... esquisito também.

Apenas esquisito, cada um escolhe o nome que quiser.

Ah sim... uma vez que as variáveis são LOCAIS, nada impede de usar o nome que quiser, MESMO QUE EXISTA EM OUTRO FONTE.
Por exemplo, nOpcao ou nOpc pra escolha de opção.

Browse ADO com problema

Enviado: 05 Jul 2020 07:56
por JoséQuintas
Uma consideração importante sobre o codeblock:

No Clipper, havia opção de função de usuário, passando como string. "funcao".
O problema de usar assim é que OBRIGA que seja uma função pública e única, para cada browse.
Já usando codeblock, dá pra usar uma função STATIC, que só fica visível no fonte aonde a função foi declarada.
Ou seja, retira a limitação que deixa tudo preso.

Com codeblock, poderia até ter todas as rotinas de browse com mesmo nome, que não seria problema.
Essa é a grande diferença, dá até pra padronizar um nome pra tudo.

Browse ADO com problema

Enviado: 05 Jul 2020 13:37
por JoséQuintas
Ficou um erro nisso tudo.
O DO WHILE da função de usuário vai acabar travando tudo.
É decidir como vai tratar essa função de usuário.

Outra opção interessante seria fazer parecido com a tbrowse, mas aí teria que alterar pra classe pra poder acrescentar as opções.

Achei interessante o recurso, que é oBrowse:SetKey( nKey, bCode )

É que desse jeito, ao invés de uma função de usuário tratando tudo que é tecla, teria uma função pra cada tecla.

oBrowse:SetKey( K_ENTER, { || RotinaEnter() } )
oBrowse:SetKey( K_ESC, { || RotinaEsc() } )

O lado ruim seria ter que repetir isso pra maiúscula/minúscula.
O lado bom seria deixar tudo por conta do browse genérico, e dividir o que seria um fonte monstruoso em pequenos fontes.

No browse genérico, talvez algo do tipo:

AEval( aSetKeyList, { | e | iif( nKey == e[ 1 ], Eval( e[ 2 ] ), NIL ) } )

Esse conceito poderia ser usado nas LIBs GUI também, pra configurar teclas para as rotinas de grid/browse/etc.

Browse ADO com problema

Enviado: 06 Jul 2020 00:29
por cjp
Em primeiro lugar, obrigado por ter postado aqui o problema e a solução.
Testei exatamente da forma como vc postou, e não funcionou. Nenhuma tecla funciona no browse.

Só para ficar claro, fiz assim:

Código: Selecionar todos


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

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



FUNCTION RotinaDesteBrowse( otb, nKey, ors )

   LOCAL opRet

   (otb)
   DO WHILE .t.

      IF nKey = K_ENTER
         arq=oRs:Fields("nrtarefa"):Value
         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
            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
         EXIT
      ENDIF
   ENDDO

   RETURN NIL

#include "tbrowse.ch"

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

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

   keysec(27,1000,-1,.t.)

   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
      OTHERWISE
         IF bFuncao != NIL
            Eval( bFuncao, oTBrowse, nKey, oRs )
         ENDIF
      ENDCASE
   ENDDO

   RETURN .t.
   

Browse ADO com problema

Enviado: 06 Jul 2020 10:52
por JoséQuintas
https://pctoledo.org/forum/viewto ... do#p137242
browse.png
Mas é confuso isso.
Você JÁ TEM browse ADO no aplicativo funcionando.
Agora tá fazendo outro browse.....

É que essa situação se tornou comum: pergunta e copia fonte, sendo que JÁ TEM FONTE FUNCIONANDO E EM USO.

Tá viciado em baixar fonte da internet, baixou de novo, e nem olhou o que já tinha?
Copiou do que JÁ TEM NO APLICATIVO, e nem conferiu se faltava alguma coisa?

A impressão que dá, é que apenas coloca fontes pra que alguém devolva o fonte corrigido.
Não sei o que pensar.

Nota aos demais: além do fórum tem perguntas via whatsapp, é que considerando apenas pelo fórum pode parecer exagero.