Página 3 de 4

browse ADO

Enviado: 14 Set 2020 20:02
por Itamar M. Lins Jr.
Ola!
Tô na cola...
Veja;

Código: Selecionar todos

#include "hwgui.ch"

Function Main
Local oMainWindow

   INIT WINDOW oMainWindow MAIN TITLE "Example" ;
     AT 200,0 SIZE 400,150

   MENU OF oMainWindow
      MENUITEM "&Exit" ACTION hwg_EndWindow()
      MENUITEM "&Dialog" ACTION DlgGet()
   ENDMENU

   ACTIVATE WINDOW oMainWindow
Return Nil

STATIC FUNCTION DlgGet()

   LOCAL oModDlg, oBrw1, cnSQL

   cnSQL := win_OleCreateObject( "ADODB.Recordset" )
   cnSQL:Open( hb_cwd() + "teste.ado" )

   INIT DIALOG oModDlg TITLE "Licenτas" AT 0,0 SIZE 1024,600

   @ 1,1 BROWSE ARRAY oBrw1 SIZE 1022,500 STYLE WS_BORDER + WS_VSCROLL + WS_HSCROLL
  oBrw1:bOther := {|oBrw, msg, wParam, lParam| fKeyDown(oBrw, msg, wParam, lParam)}   
      
   @ 500,720 OWNERBUTTON ON CLICK {|| cnSQL:Close(), hwg_EndDialog()} ;
       SIZE 180,36 FLAT                                ;
       TEXT "Close" COLOR hwg_ColorC2N("0000FF")
   oBrw1:aarray := cnSQL
   oBrw1:AddColumn( HColumn():New( "Codigo", { |v,o| (v), o:aArray:Fields( "CODIGO" ):Value },"C",6,0,.F.,DT_CENTER ) )
   oBrw1:AddColumn( HColumn():New( "Nome",   { |v,o| (v), o:aArray:Fields( "NOME" ):Value }, "C",30,0,.T.,DT_CENTER,DT_RIGHT ) )
   oBrw1:aColumns[2]:lResizable := .F.
   oBrw1:bSkip     := { | o, nSkip | ADOSkipper( o:aArray, nSkip ) }
   oBrw1:bGotop    := { | o | o:aArray:MoveFirst() }
   oBrw1:bGobot    := { | o | o:aArray:MoveLast() }
   oBrw1:bEof      := { | o | o:nCurrent > o:aArray:RecordCount() }
   //oBrw1:bBof      := { | o | o:nCurrent == 0 }
   oBrw1:bRcou     := { | o | o:aArray:RecordCount() }
   oBrw1:bRecno    := { | o | o:aArray:AbsolutePosition }
   obrw1:bRecnoLog := obrw1:bRecno
   oBrw1:bGOTO     := { | o, n | (o), o:aArray:Move( n - 1, 1 ) }

   ACTIVATE DIALOG oModDlg
Return Nil

FUNCTION ADOSkipper( cnSQL, nSkip )

   LOCAL nRec := cnSQL:AbsolutePosition()
      IF ! cnSQL:Eof()
         cnSQL:Move( nSkip )
         IF cnSQL:Eof()
            cnSQL:MoveLast()
         ENDIF
         IF cnSQL:Bof()
            cnSQL:MoveFirst()
         ENDIF
      ENDIF
      RETURN cnSQL:AbsolutePosition() - nRec

Static FUNCTION fKeyDown(oBrw, msg, wParam, lParam)
LOCAL nKEY := hwg_PtrToUlong( wParam ) //wParam
IF msg == WM_KEYDOWN
   IF nKey = VK_F2
      hwg_Msginfo("Total: " + Str(oBrw:aArray:RecordCount())+hb_eol() + "Recno:" + Str(oBrw:nCurrent) + hb_eol() + "Absoluto:" + Str(oBrw:aArray:AbsolutePosition)  )
   ENDIF
ENDIF
RETURN .T.
nCurrent sempre com 1
Pressione F2 que vai mostrar, até aqui o fonte da Hwgui está ok. Falta o nCurrent retornar o valor correto, mas ai é adaptação do ADO.

Saudações,
Itamar M. Lins Jr.

browse ADO

Enviado: 14 Set 2020 20:11
por JoséQuintas
Não adiantou alterar pra bGoBot

Mas pera aí:
O teste tá errado, de acordo com tbrowse.

Código: Selecionar todos

FUNCTION ADOSkipper( cnSQL, nSkip )

   LOCAL nRec := cnSQL:AbsolutePosition()
      IF ! cnSQL:Eof()
         cnSQL:Move( nSkip )
         IF cnSQL:Eof()
            cnSQL:MoveLast()
         ENDIF
         IF cnSQL:Bof()
            cnSQL:MoveFirst()
         ENDIF
      ENDIF
      RETURN cnSQL:AbsolutePosition() - nRec
O teste não seria Eof(), mas sim se conseguiu pular os registros que foram indicados

Mas pera aí....
hwgui com tantos anos de uso....
Corrigir um browse, equivalente ao tbrowse, porque não está equivalente ao tbrowse...
Nem sei o que dizer....

browse ADO

Enviado: 14 Set 2020 20:17
por JoséQuintas
Olha aí a correção, agora funciona.
E acabei apagando duas linhas do fonte.

Código: Selecionar todos

METHOD LINEDOWN( lMouse ) CLASS HBrowse

   LOCAL minPos, maxPos, nPos, colpos

   IF Eval( ::bSkip, Self, 1 ) == 0
      Eval( ::bGoBot, Self )

Código: Selecionar todos

METHOD LINEUP() CLASS HBrowse

   LOCAL minPos, maxPos, nPos

   IF Eval( ::bSkip, Self, -1 ) == 0
      Eval( ::bGoTop, Self )
Agora confuso....
Só comigo deu problema?
Fui direto começar logo com o que tinha problema?

browse ADO

Enviado: 14 Set 2020 20:29
por Itamar M. Lins Jr.
Ola!
Bom, são muitas coisas.
O browse array usa bSkip que chama a procedure ARSKIP(o,n)
Veja que no seu vc não está atualizando ele.(nCurrent)

Código: Selecionar todos

PROCEDURE ARSKIP( oBrw, nSkip )

   LOCAL nCurrent1

   IF oBrw:nRecords != 0
      nCurrent1   := oBrw:nCurrent
      oBrw:nCurrent += nSkip + iif( nCurrent1 = 0, 1, 0 )
      IF oBrw:nCurrent < 1
         oBrw:nCurrent := 0
      ELSEIF oBrw:nCurrent > oBrw:nRecords
         oBrw:nCurrent := oBrw:nRecords + 1
      ENDIF
   ENDIF

   RETURN

Código: Selecionar todos

FUNCTION ADOSkipper( cnSQL, nSkip )

   LOCAL nRec := cnSQL:AbsolutePosition()
      IF ! cnSQL:Eof()
         cnSQL:Move( nSkip )
         IF cnSQL:Eof()
            cnSQL:MoveLast()
         ENDIF
         IF cnSQL:Bof()
            cnSQL:MoveFirst()
         ENDIF
      ENDIF
      RETURN cnSQL:AbsolutePosition() - nRec
Vc substituiu pelo seu ADOSKIPPER, faltou atualizar nCurrent acho que foi isso por enquanto...

Saudações,
Itamar M. Lins Jr.

browse ADO

Enviado: 14 Set 2020 20:43
por JoséQuintas
Discordo totalmente.
Sabemos que array precisa disso, de um indexador, mas não o resto.
E o array pode ser resolvido da mesma forma.
Ou será que é ficar aprendendo tudo de novo, pra ver se funciona do mesmo jeito ????

Aqui postei um exemplo que serve pra ADO, Array e DBF.
Segue as regras do tbrowse.

https://pctoledo.org/forum/viewto ... se#p142124

browse ADO

Enviado: 14 Set 2020 20:46
por JoséQuintas
Ou pra ficar mais claro, só a parte de array:

Código: Selecionar todos

      oTBrowse:GoTopBlock    := { || nIndex := 1 }
      oTBrowse:GoBottomBlock := { || nIndex := Len( oConsulta ) }
      oTBrowse:SkipBlock     := { | input, temp | temp := nIndex,    ;
         nIndex := Max( 1, Min( Len( oConsulta ), nIndex + input ) ), nIndex - temp }
Array sim, precisa do nCurrent, que nesse caso chamei de nIndex
O retorno é a última parte do codeblock: nIndex - temp

browse ADO

Enviado: 14 Set 2020 20:54
por JoséQuintas
Um possível problema que vejo é:

E array vazio?
Normalmente não existe isso, mas talvez exista em hbMySQL.
Não sei qual seria o comportamento do tbrowse normal nesse caso, porque geralmente não fazemos isso.

browse ADO

Enviado: 14 Set 2020 20:57
por Itamar M. Lins Jr.
Ola!
Pois é!
Para ADO foi agora, array já tinha quem usa ? Eu não uso.
Mas agora já foi corrigido para tudo.

Saudações,
Itamar M. Lins Jr.

browse ADO

Enviado: 14 Set 2020 20:59
por Itamar M. Lins Jr.
Ola!
Posso colocar seu exemplo para testes(ADO) na Hwgui ?

Saudações,
Itamar M. Lins Jr.

browse ADO

Enviado: 14 Set 2020 21:01
por JoséQuintas
Resta testar.
Igual ao tbrowse ficaria assim:

Código: Selecionar todos

PROCEDURE ARSKIP( oBrw, nSkip )

   LOCAL nOld

   nOld          := oBrw:nCurrent
   oBrw:nCurrent := Max( 1, Min( oBrw:nRecords, nOld + nSkip ) )

   RETURN oBrw:nCurrent - nOld
Talvez o sample existente sirva.

browse ADO

Enviado: 14 Set 2020 21:05
por Itamar M. Lins Jr.
Ola!
É isso, vou fazer um bem bonitinho aqui...
E ver se o pessoal faz commit dele na area de testes da Hwgui.

Saudações,
Itamar M. Lins Jr.

browse ADO

Enviado: 14 Set 2020 21:07
por JoséQuintas
Funciona perfeito pra array também, pelo menos no sample.
hwgui.png

browse ADO

Enviado: 14 Set 2020 21:10
por JoséQuintas
Veja isto:

Código: Selecionar todos

      oldRecno := Eval( oBrw:bRecnoLog, oBrw )
      newRecno := Round( ( oBrw:nRecords - 1 ) * nPos/ ( maxPos - minPos ) + 1, 0 )
      IF newRecno <= 0
         newRecno := 1
Testar se RecNo é menor ou igual a zero?

Acho que estão remendando faz tempo.

browse ADO

Enviado: 14 Set 2020 21:30
por JoséQuintas

Código: Selecionar todos

FUNCTION hwg_VScrollPos( oBrw, nType, lEof, nPos )

   LOCAL minPos, maxPos, oldRecno, newRecno

   hwg_Getscrollrange( oBrw:handle, SB_VERT, @minPos, @maxPos )
   IF nPos == Nil
      IF nType > 0 .AND. lEof
         Eval( oBrw:bSkip, oBrw, - 1 )
      ENDIF
      nPos := iif( oBrw:nRecords > 1, Round( ( (maxPos - minPos )/(oBrw:nRecords - 1 ) ) * ;
         ( Eval( oBrw:bRecnoLog,oBrw ) - 1 ), 0 ), minPos )
      hwg_Setscrollpos( oBrw:handle, SB_VERT, nPos )
   ELSE
      oldRecno := Eval( oBrw:bRecnoLog, oBrw )
      newRecno := Round( ( oBrw:nRecords - 1 ) * nPos/ ( maxPos - minPos ) + 1, 0 )
      IF newRecno <= 0
         newRecno := 1
      ELSEIF newRecno > oBrw:nRecords
         newRecno := oBrw:nRecords
      ENDIF
      IF nType == SB_THUMBPOSITION
         hwg_Setscrollpos( oBrw:handle, SB_VERT, nPos )
      ENDIF
      IF newRecno != oldRecno
         Eval( oBrw:bSkip, oBrw, newRecno - oldRecno )
         IF oBrw:rowCount - oBrw:rowPos > oBrw:nRecords - newRecno
            oBrw:rowPos := oBrw:rowCount - ( oBrw:nRecords - newRecno )
         ENDIF
         IF oBrw:rowPos > newRecno
            oBrw:rowPos := newRecno
         ENDIF
         oBrw:Refresh( .F. )
      ENDIF
   ENDIF

   RETURN Nil

Código: Selecionar todos

      ::bRecnoLog := ::bRecno  := { ||( ::alias ) -> ( RecNo() ) }
Tá confuso isso, fazer conta com o RecNo(), e usar RecNo() como referência?
Só se usasse DBF sempre SEM estar indexado.

Então....
Uma vez sugeri que o pessoal falasse sobre ferramentas de uso e modo de trabalho, pra comparações.
De repente a maioria usa array, pra velocidade, e não teve problema com isso.
A minha intenção era justamente tentar preparar pra esse tipo de coisa.
De repente, a ferramenta é ótima pra quem trabalha exatamente daquele jeito.
E quem trabalhar diferente, vai direto justamente testar a parte diferente.
E no meu caso, com certeza é o ADO que é a parte diferente, por isso fui direto nele.

browse ADO

Enviado: 14 Set 2020 22:24
por Itamar M. Lins Jr.
Ola!
Deu defeito no DBF...O mesmo do ADO, não para no final.
Tô vendo onde é :-(

Saudações,
Itamar M. Lins Jr.