Tree en Xbrowse

Post Reply
User avatar
fgondi
Posts: 636
Joined: Fri Oct 07, 2005 6:58 am
Location: Palencia, España
Contact:

Tree en Xbrowse

Post by fgondi »

Antonio,

Aplicar un tree a un xbrowse es algo muy util, pero tal y como esta pensado actualmente tengo problemas para aplicarlo.

Me explico.

Quiero mostrar en un browse 2 tablas anidadas, o sea el browse se muestra de la primera tabla y al pulsar expandir sobre una fila muestra una serie de artículos de la segunda tabla.

Actualmente tendría que generar una unica tabla con todos los registros (no hay problema via sql), pero para cargar el tree hay que leer uno a uno los registros y en mi caso son entorno a los 90.000, por lo que tarda mucho y es inviable.

Estudiar si es posible no tener que hacer esto para tener un tree en un browse.

Por ejemplo se me ocurre, que se muestre los registros de la primera tabla y al pulsar expandir de una fila llame a la otra tabla para obtener los registros necesarios de la segunda tabla y en el mismo browse se pueda ver los registros de una tabla y de la otra.

Vamos, lo que toda la vida se ha podido hacer en Clipper con dos browse anidados pero intentado que sea con uno sólo.

Espero haberme explicado. Gracias
Un saludo
Fernando González Diez
ALSIS GHE Sistemas Informáticos
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Post by Antonio Linares »

Fernando,

Revisa estos ejemplos:

TstTree.prg

Code: Select all

#include 'fivewin.ch'
#include 'xbrowse.ch'

REQUEST DBFCDX

static nCust, nState

function Main()

   local oWnd, oBrw, oTree

   CheckCdx()

   OpenData()
   oTree := MakeTree()
   oTree:Collapse( 1 )

   DEFINE WINDOW oWnd

   @ 0,0 XBROWSE oBrw OF oWnd CELL LINES

   oBrw:SetTree(  oTree, ;
                  { 'OPEN', 'CLOSE', 'GREEN' }, ; // Three resources
                  { |oItem| OnSkip( oItem ) } ;   // skip block
               )

   oBrw:aCols[ 1 ]:cHeader := 'State/City'

   ADD TO oBrw DATA ;
      If( oBrw:oTreeItem:nLevel == 1, Space( 20 ), (nCust)->First ) ;
      HEADER 'Name'

   ADD TO oBrw DATA ;
      If( oBrw:oTreeItem:nLevel == 1, 0, (nCust)->Salary ) ;
      HEADER 'Salary' ;
      PICTURE '@Z 999,999,999.99'

   oBrw:CreateFromCode()
   oWnd:oClient   := oBrw

   ACTIVATE WINDOW oWnd

return nil

static function OnSkip( oItem )

   ( oItem:Cargo[ 1 ] )->( DbGoTo( oItem:Cargo[ 2 ] ) )

return nil

static function OpenData()

   USE CUSTOMER NEW ALIAS CUST SHARED VIA 'DBFCDX'
   SET ORDER TO TAG STATE
   nCust    := Select( 'CUST' )

   USE STATES NEW SHARED VIA 'DBFCDX'
   SET ORDER TO TAG CODE
   nState    := Select( 'STATES' )
   GO TOP

return nil

static function MakeTree()

   local oTree, oItem

   select states
   go top

   TREE oTree

   do while ! states->( Eof() )

      TREEITEM oItem PROMPT States->Name
      oItem:Cargo := { nState, States->( RecNo() ) }

      if cust->( dbseek( States->Code ) )

         TREE
         do while cust->State == States->Code

            TREEITEM oItem PROMPT Cust->City
            oItem:Cargo := { nCust, Cust->( recno() ) }
            cust->( dbskip( 1 ) )

         enddo

         ENDTREE

      endif

      states->( dbskip( 1 ) )
   enddo

   ENDTREE

return oTree

//--------------------------------------//

static function CheckCdx()

   local n

   if File( "customer.cdx" )
      FErase( "customer.cdx" )
   endif

   USE CUSTOMER EXCLUSIVE VIA "DBFCDX"
   for n := 1 to FCount()
      CreateTag( FieldName( n ) )
   next
   USE

   if File( "states.cdx" )
      FErase( "states.cdx" )
   endif

   USE STATES EXCLUSIVE VIA "DBFCDX"
   for n := 1 to FCount()
      CreateTag( FieldName( n ) )
   next
   USE

return nil

//----------------------------------------------------------------------------//

static function CreateTag( ctag )

   INDEX ON &ctag TAG &ctag

return nil

//----------------------------------------------------------------------------//

TstTree.rc

Code: Select all

OPEN   BITMAP "c:\fwh\bitmaps\16x16\open.bmp"
CLOSE  BITMAP "c:\fwh\bitmaps\16x16\folder.bmp"
GREEN  BITMAP "c:\fwh\bitmaps\16x16\form.bmp"
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Post by Antonio Linares »

Fernando,

Si necesitas que los registros de la base de datos "hija" se refresquen automaticamente, tenemos por aqui otro ejemplo que puede servirte :-)
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
fgondi
Posts: 636
Joined: Fri Oct 07, 2005 6:58 am
Location: Palencia, España
Contact:

Post by fgondi »

Antonio,

Gracias por el ejemplo.

Aunque el problema es el número de registros.

Imagina que la tabla "States" tiene 90.000 registros.

Para mostrar el browse con el tree tiene que hacer una pasada por todos los registros, en consecuencia el tiempo que tarda en mostrar el browse es muy alto.

La idea es que se fuera autocargando el tree a medida que se va pintando el browse. Aprovechar que para pintar el browse tiene que pasar por cada registro e ir haciendo la carga del tree en ese momento.

Lo que estoy probando es a usar ado sobre esos browse.
Estoy echando un vistazo a la clase AdoBase de Adolfo y la forma de pintar browse paginados, aunque uso Ads y no exite la instrucción LIMIT, por lo que tengo que ejecutar las sql de otra forma.

Al no tener ya que manejar los 90.000, sino que sólo los registros de la página mostrada, puedo aplicar el tree como en el ejemplo que me muestras.
Un saludo
Fernando González Diez
ALSIS GHE Sistemas Informáticos
Post Reply