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...
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
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.