miércoles, 8 de abril de 2009

Browse de FiveWin con datos SQL

Si estas usando ADO para recuperar datos de una base de datos SQL y luego quieres mostrarlos en un browse de FiveWin hay que tener varias cosas en cuenta.

Al definir el RecordSet:

  1. El tipo de cursor tiene que ser adOpenKeySet (1) ó adOpenDynamic (2) para que puedas moverte sobre el cursor para arriba y para abajo, de lo contrario solo puedes ir hacia abajo.
  2. El tipo de bloqueo tiene que ser adLockOptimistic (3), para dejar al servidor que se encargue de los bloqueos al momento de actualizar los datos.
  3. La ubicación del cursor tiene que ser adUseClient (3) si quieres que el browse vaya rápido, de lo contrario cada avance de página tiene que ir a buscar los datos al servidor y eso se puede llevar mucho tiempo.
Al definir el Browse:

  1. En la clausula FIELDS del BROWSE tienes que indicar los campos usando el objeto RecordSet: REDEFINE BROWSE FIELDS oRs:Fields(0):Value, oRs:Fields(1):Value.....
  2. Tienes que cambiar los métodos de movimiento del Browse, porque el Browse de FiveWin solo sabe "moverse" sobre campos de DBFs o bien sobre elementos de arrays.
Los métodos de movimiento del browse (TWBrowse) de FiveWin son:

oBrw:bGoTop := {|| oRS:GoTop() }

Se usa para indicarle al browse la operación que debe realizar para ir al primer registro, en este caso usamos el método ::GoTop() del RecordSet, para poder "movernos" libremente por el recordset, el tipo de cursor tiene que ser KeySet o Dynamic.

oBrw:bGoBottom := {|| oRs:GoBottom() }

Se usa para indicarle al browse la operación que debe realizar para ir al final de los datos, en este caso usamos el método ::GoBottom() del RecordSet, para poder "movernos" libremente por el recordset, el tipo de cursor tiene que ser KeySet o Dynamic.

oBrw:bLogicLen := {|| oRs:RecCount()}

Se usa para dibujar la barra de desplazamiento vertical del lado derecho del browse, su valor representa el numero de renglones presentes en el browse y se asigna al método ::RecCount() del RecordSet, el cursor tiene que ser KeySet o Dynamic, de lo contrario devueve -1.

oBrw:bSkip :={|nRegs| AdoSkip(nRegs)}

Esta es la operación de movimiento mas importante, porque define el número de registros que se mueve el browse cuando se utilizan las teclas de flechas arriba y abajo, PgUp y PgDn y Ctrl+PgUp y Ctrl+PgDn, usualmente se asigna a una función que se puede llamar como quieras (usualmente se le llama "skipper") y que devuelve el número de registros que se ha desplazado el browse (ojo: El RecordSet tiene que estar visible para la función):

Function AdoSkip( nSkip )
LOCAL nStart, nEnd, nMoved := 0

nStart := oRecst:Recno()
oRecst:Skip( nSkip )
nEnd := oRecst:Recno()
DO CASE
CASE nEnd > 0
nMoved := nEnd - nStart

CASE nEnd == -3
oRecst:GoBottom()
nMoved := oRecst:RecCount() - nStart

CASE nEnd == -2
oRecst:GoTop()
nMoved := - nStart + 1

ENDCASE
RETURN nMoved


El ejemplo completo quedaria así:

REDEFINE ListBox oBrw FIELDS oRs:Fields(0):Value, oRs:Fields(1):Value, ...oRS:Fields(n)...

WITH OBJECT oBrw
:bSkip := {|nRecs| nAdoSkip( nRecs )}
:bGoTop := {|| oRecst:Gotop() }
:bGoBottom := {|| oRecst:Gobottom() }
:bLogicLen := {|| oRecst:RecCount()}
END WITH
.....
....
....

Function AdoSkip( nSkip )

LOCAL nStart, nEnd, nMoved := 0

nStart := oRecst:Recno()
oRecst:Skip( nSkip )
nEnd := oRecst:Recno()
DO CASE
CASE nEnd > 0
nMoved := nEnd - nStart

CASE nEnd == -3
oRecst:GoBottom()
nMoved := oRecst:RecCount() - nStart

CASE nEnd == -2
oRecst:GoTop()
nMoved := - nStart + 1

ENDCASE
RETURN nMoved


En Xailer no es necesario nada de lo anterior, porque el control DBBrowse de Xailer resuelve directamente el tipo de base de datos que se está utilizando ya sea un Array, una tabla DBF o un Query SQL (versiones Profesional y Enterprise).

Para mas información sobre ADO con FiveWin, recomiendo la lectura de estos 2 estupendos blogs:

BielSys de mi amigo Biel y SQLCmd de mi amigo Armando.

1 comentario:

  1. Sabo sobre las situaciones semejantes y despues la utiliza interesante que sabe decidir la complecacion presente - como reparar mssql.

    ResponderEliminar