FiveTech Support Forums

FiveWin / Harbour / xBase community
Board index FiveWin para Harbour/xHarbour Como refrescar Intems de un de Tree en un Xbrose
Posts: 83
Joined: Wed Apr 20, 2011 03:08 PM
Como refrescar Intems de un de Tree en un Xbrose
Posted: Tue Mar 02, 2021 01:24 AM
Estimados amigos, espero se encuentren todos bien de salud. Necesito de su ayuda ya que me he quebrado la cabeza para actualizar los 脥tems que han sido modificados en un Tree de un Xbrowse que uso para Indexar bases de datos. S贸lo me funciona el refresco cuando cambio solo un 脥tem del Tree, no as铆 cuando uso la funci贸n de marcado para todos los 脥tem del Tree, ya que solo me refresca el 脥tem que seleccion茅, pero no as铆 sus 脥tems debajo, siendo que la informaci贸n de la columna a mostrar cambio, ya sea a .T. o .F., mostrando el Bitmaps, respectivo del 脥tem.

A continuaci贸n les dejo algunas im谩genes, para que puedan entender la soluci贸n que estoy buscando

Ac谩 la ventana con el arbol inicial, antes de abrirse:



Luego el Tree abierto:



Cuando hago doble click sobre alguno de los Items del Tree, se marcan y refrescan sin problemas



Luego aca tengo mi problema, al marcar la columna de la cabecera del 脕rbol, de modo de seleccionar en forma simult谩nea todos los 脥tem de esa rama del Tree, solo puedo refrescar el 脥tem de la cabecera de la rama, no as铆 los items, ya que no los puedo refrescar, aunque la funci贸n si trabaja bien y cambia a .f. o .t., seg煤n sea el caso a toda la familia en la base de Datos. Intent茅 usar el M茅todo obrw:Refresh() y me da error, pero si uso [b]]obrw:Refresh()[/b, solo se refresca el 脥tem que seleccion茅 del 谩rbol. como pasa al seleccionar los items individual de la rama, como se mostr贸 arriba.



Ac谩 les muestro parte de la l铆nea de c贸digo que uso para hacer lo anterior:


Code (fw): Select all Collapse
function Indexa(oWndMain)

聽 聽local oWnd, oCol
聽 聽local oRs, oRsTot
聽 聽local oTree, oItem
聽 聽local oBold, bFont
聽 聽local nMethod := 1
聽 聽local oBrw, oChild
聽 聽local oDlg, oBIndex, FntArial
聽 聽local cAlias := cGetNewAlias( "FBD" )
聽 聽local cDbName 聽:= ""
聽 聽local cNtxName := ""
聽 聽local oDbName, oNtxName
聽 聽local cItem 聽:= "Bases de Datos"
聽 聽local aGradBarMet:= { { 1/2, nRGB( 224, 255, 255), nRGB( 135, 206, 250 ) 聽} , ;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽{ 1/2, nRGB( 030, 144, 255), nRGB( 000, 255, 255 ) } }
聽 聽local aGradRowSel:= {{ 1, RGB(000,191, 255), RGB(224,255,255)}}
聽 聽local aGradBarSel:= {{ 1, RGB(030,144,255) , RGB(000,255, 255) } }


聽 聽FW_SetUnicode( .T. )
聽 聽FW_TouchFriendly( .T. )

聽 聽CheckBDCdx()
聽 聽FBD->( OrdSetFocus( "FBDIND2" ), DBGoTop() )
聽 聽if FilLock(5)
聽 聽 聽 Replace FBD->INDEXA_FBD with .f. ALL
聽 聽endif
聽 聽commit
聽 聽unlock

聽 聽go top 聽 
聽 聽SetBalloon( .t. )
聽 聽SetGetColorFocus()

聽 聽lSmallScr 聽 := ( sqrt( screenwidthmm() ^ 2 + screenheightmm() ^ 2 ) / 25.4 < 12 )

聽 聽
聽 DEFINE FONT oBold NAME "TAHOMA" SIZE 0,-12 BOLD
聽 
聽 DEFINE WINDOW oWnd MDICHILD OF oWndMain TITLE "Indexacion Base de Datos" 聽
聽 
聽 聽@ 0,0 XBROWSE oBrw 聽OF oWnd ;
聽 聽 聽 聽 聽COLUMNS "Descripcion" 聽 ;
聽 聽 聽 聽 聽JUSTIFY AL_LEFT,AL_LEFT, AL_CENTER ;
聽 聽 聽 聽 聽LINES CELL AUTOCOLS 聽FASTEDIT
聽 聽 聽 聽 聽
聽 聽 聽 oTree := BuildTree()
聽 聽 聽 oBrw:SetTree( oTree, { "OPEN", "CLOSE", "DATABASE" } ) 
聽 聽 聽 聽 聽 聽 
聽 聽 聽 ADD TO oBrw DATA oBrw:oTreeItem:Cargo[ 1 ] 聽TITLE "Base de Datos" SIZE 100
聽 聽 聽 ADD TO oBrw DATA oBrw:oTreeItem:Cargo[ 2 ] 聽TITLE "Indexar" 聽 聽 聽 SIZE 60
聽 聽 聽 
聽 聽WITH OBJECT oBrw:Indexar
聽 聽 聽 聽 聽:AddResource("ON")
聽 聽 聽 聽 聽:AddResource("OFF")
聽 聽 聽 聽 聽:bBmpData 聽 := { || iif( oBrw:oTreeItem:Cargo[ 2 ]= .T., 1, 2) }
聽 聽 聽 聽 聽:bStrData 聽 := " "
聽 聽END 聽 聽 聽 聽 
聽 聽WITH OBJECT oBrw

聽 聽 聽 :nStretchCol 聽 聽 聽:= STRETCHCOL_WIDEST
聽 聽 聽 :nColDividerStyle := LINESTYLE_RAISED
聽 聽 聽 :nRowDividerStyle := LINESTYLE_RAISED
聽 聽 聽 :nMarqueeStyle 聽 聽:= MARQSTYLE_HIGHLROWMS

聽 聽 聽 :LAllowColSwapping 聽 := .f.
聽 聽 聽 :lHScroll 聽 聽 聽 聽 聽 聽 := .f.
聽 聽 聽 
聽 聽 聽 :lColDividerComplete := .f.
聽 聽 聽 :lAllowRowSizing 聽 聽 := .f.
聽 聽 聽 :lAllowColHiding 聽 聽 := .f.
聽 聽 聽 :lKineticBrw 聽 聽 聽 聽 := .f.
聽 聽 聽 :nRowHeight 聽 聽 聽 聽 聽:= 24
聽 聽 聽 :nHeaderHeight 聽 聽 聽 := 22
聽 聽 聽 
聽 聽 聽 :bLDblClick 聽 聽 聽 := {|nRow,nCol| EditBrowse(nRow,nCol,oBrw, oDlg, oTree) }
聽 聽 聽 :bClrRowFocus 聽 聽 := { || { CLR_BLACK, aGradRowSel/*RGB(185,220,255)*/ } }
聽 聽 聽 :bClrStd 聽 聽 聽 聽 聽:= {|| { nRGB( 0, 0, 0), nRGB(255,248,220) } } // colores para lineas normales
聽 聽 聽 :bClrSel 聽 聽 聽 聽 聽:= {|| { nRGB( 0, 0, 0), aGradRowSel } } // para barra de linea selecc cuando el control no tiene el foco
聽 聽 聽 :bClrSelFocus 聽 聽 := { || { CLR_BLACK, aGradBarSel } } // para barra de linea selecc cuando el control tiene el foco 聽 聽 聽 聽 聽 
聽
聽 聽 聽 :aCols[ 1 ]:cHeader 聽:= "Descripcion"
聽 聽 聽 :CreateFromCode()

聽 聽END 

聽 聽oWnd:oClient 聽 := oBrw
聽 聽
聽 聽BtnBar( oBrw)
聽 聽oWnd:bPostEnd 聽:= { || ( cAlias )->( DBCLOSEAREA() ) } 
聽 
聽 聽ACTIVATE WINDOW oWnd ON INIT ( oBrw:SetFocus() ) 聽 
聽 聽
return nil



Code (fw): Select all Collapse
static function BuildTree()

聽 聽local oTree, cFamiBD

聽 聽TREE oTree
聽 聽 聽 while ! Eof()
聽 聽 聽 聽 聽if Empty( cFamiBD )
聽 聽 聽 聽 聽 聽 _TreeItem( FBD->FAMIBD_FBD ):Cargo := { Space( 13 ), .F. }
聽 聽 聽 聽 聽 聽 TREE
聽 聽 聽 聽 聽 聽 cFamiBD = FBD->FAMIBD_FBD
聽 聽 聽 聽 聽else
聽 聽 聽 聽 聽 聽 if cFamiBD != FBD->FAMIBD_FBD
聽 聽 聽 聽 聽 聽 聽 聽ENDTREE
聽 聽 聽 聽 聽 聽 聽 聽cFamiBD = FBD->FAMIBD_FBD
聽 聽 聽 聽 聽 聽 聽 聽_TreeItem( FBD->FAMIBD_FBD ):Cargo := { Space( 13 ), .F. }
聽 聽 聽 聽 聽 聽 聽 聽TREE
聽 聽 聽 聽 聽 聽 endif 聽 
聽 聽 聽 聽 聽endif 聽 
聽 聽 聽 聽 聽if FBD->FAMIBD_FBD == cFamiBD
聽 聽 聽 聽 聽 聽 _TreeItem( FBD->DESCRI_FBD ):Cargo := { FBD->NOMBD_FBD, FBD->INDEXA_FBD }
聽 聽 聽 聽 聽endif 聽 
聽 聽 聽 聽 聽SKIP
聽 聽 聽 enddo
聽 聽 聽 ENDTREE
聽 聽ENDTREE

聽 聽GO TOP

return oTree


Code (fw): Select all Collapse
STATIC FUNCTION EditBrowse(nRow, nCol, oBrw, oDlg, oTree)

聽 聽 聽LOCAL xVar, nRecno := RecNo()
聽 聽 聽LOCAL nColPos 聽:= 0 ,;
聽 聽 聽 聽 聽 聽nColInit := 0 ,;
聽 聽 聽 聽 聽 聽nColGet 聽:= 0 ,;
聽 聽 聽 聽 聽lAppend 聽:= .f.

聽 聽 聽lFin := cBrowse(3, oBrw)
// 聽 聽 oBrw:Refresh()
聽 聽 聽
return nil

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

static Function cBrowse(nColGet, oBrw)

聽 聽LOCAL xVar, nRecno, lEscape := .f., nTotal := 0
聽 聽LOCAL cFamiBD:= oBrw:Descripcion:Value()
聽 聽LOCAL cNomBD := oBrw:oTreeItem:Cargo[ 1 ]


聽 聽if nColGet = 3
聽 聽 聽 Select FBD
聽 聽 聽 FBD->( OrdSetFocus( "FBDIND1" ), DBGoTop() )
聽 聽 聽 if !EMPTY(cNombD)
聽 聽 聽 聽 IF 聽DbSeek ( cNomBD )
聽 聽 聽 聽 聽 聽 msgstop(FBD->NomBD_FBD)
聽 聽 聽 聽 聽IF FBD->Indexa_FBD = .f.
聽 聽 聽 聽 聽 聽 if FilLock(5)
聽 聽 聽 聽 聽 聽 聽 聽FBD->Indexa_FBD = .t.
聽 聽 聽 聽 聽 聽 聽 聽oBrw:oTreeItem:Cargo := { oBrw:oTreeItem:Cargo[ 1 ] , .T. }
聽 聽 聽 聽 聽 聽 聽 聽oBrw:Refresh()
聽 聽 聽 聽 聽 聽 endif
聽 聽 聽 聽 聽 聽 
聽 聽 聽 聽 聽ELSE
聽 聽 聽 聽 聽 聽 if FilLock(5)
聽 聽 聽 聽 聽 聽 聽 聽FBD->Indexa_FBD = .f.
聽 聽 聽 聽 聽 聽 聽 聽oBrw:oTreeItem:Cargo := { oBrw:oTreeItem:Cargo[ 1 ] , .F. }
聽 聽 聽 聽 聽 聽 聽 聽oBrw:Refresh()
聽 聽 聽 聽 聽 聽 endif
聽 聽 聽 聽 聽ENDIF
聽 聽 聽 聽 ENDIF
聽 聽 聽 聽 commit
聽 聽 聽 聽 unlock
聽 聽 聽 else
聽 聽 聽 聽 SET FILTER TO FamiBD_FBD = cFamiBD
聽 聽 聽 聽 FBD->(DbGoTop())
聽 聽 聽 聽 Do 聽while !EOF()
聽 聽 聽 聽 msgstop(FBD->NomBD_FBD)
// 聽 聽 聽 聽 聽 聽IF 聽DbSeek ( cNomBD )
聽 聽 聽 聽 聽 聽 聽 聽IF FBD->Indexa_FBD = .f.
聽 聽 聽 聽 聽 聽 聽 聽 聽 if FilLock(5)
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽FBD->Indexa_FBD = .t.
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽oBrw:oTreeItem:Cargo := { oBrw:oTreeItem:Cargo[ 1 ] , .T. }
// 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 oBrw:Refresh()
聽 聽 聽 聽 聽 聽 聽 聽 聽 endif
聽 聽 聽 聽 聽 聽 聽 聽ELSE
聽 聽 聽 聽 聽 聽 聽 聽 聽 if FilLock(5)
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽FBD->Indexa_FBD = .f.
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽oBrw:oTreeItem:Cargo := { oBrw:oTreeItem:Cargo[ 1 ] , .F. } 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 
聽 聽 聽 聽 聽 聽 聽 聽 聽 endif
聽 聽 聽 聽 聽 聽 聽 聽ENDIF
// 聽 聽 聽 聽 聽 聽ENDIF
聽 聽 聽 聽 聽 聽 commit
聽 聽 聽 聽 聽 聽 unlock
聽 聽 聽 聽 聽 聽 DBskip()
聽 聽 聽 聽 Enddo
聽 聽 聽 聽 BuildTree()
聽 聽 聽 聽 oBrw:Refresh()
聽 聽 聽 聽 set filter to
聽 聽 聽 endif
聽 聽endif

聽 聽oBrw:SetFocus()

聽 聽oBrw:DrawSelect() 聽 

RETURN lEscape



les agradezco de ante mano su apoyo y orientaci贸n.

Un gran abrazo

Sergio Vacarezza S.
Programador Freelance
sergio@vacarezza.cl
Santiago, Chile

Harbour 3.2.0dev (r2407221137) - FWH 24.08 - MariaDB 12.2.2 - FivEdit 22.0214

Posts: 83
Joined: Wed Apr 20, 2011 03:08 PM
Como refrescar Items de un de Tree en un Xbrowse &quot;SOLUCIONAD
Posted: Fri Apr 02, 2021 12:38 AM
Estimados amigos, quer铆a compartir con todos Uds. la soluci贸n sugerida por nuestro gran amigo Rao, quien gracias a su ayuda me ha dado la soluci贸n a mi manejo de selecci贸n y refresco de 脥tems de un Tree dentro de un xBrowse. Con la ayuda de Rao finalmente pude lograr una mejor soluci贸n a la que esperaba hacer y lograr una mejor perfomance de mi Sistema, en el m贸dulo de Re Indexaci贸n de Indices, al permitirme ahora seleccionar el encabezado del Grupo de 脥tems y marcar a todos los 脥tems de ese grupo, como tambi茅n cambiar el color de la cabecera del Grupo como los 脥tems marcados, de ese modo poder visualizar que Grupo que tiene todos sus 脥tems marcados, cuando tengo el 脕rbol cerrado.

xBrowse mostrando sus grupos cerrados


xBrowse con el 1er grupo abierto y sin selecci贸n de sus 脥tems


xBrowse con la selecci贸n de un solo 脥tem


xBrowse con la selecci贸n de todo el Grupo, haciendo doble click en la casilla de la cabecera del Grupo o presionando el bot贸n "IndexGroup", se aprecia el cambio de color tambi茅n de la l铆nea del Grupo contenedor.


xBrowse con su 谩rbol cerrado y mostrando los Grupos que tienen la selecci贸n de todos sus 脥tems


El c贸digo sugerido por Rao para poder realizar esto, es el siguiente:
Code (fw): Select all Collapse
#include "fivewin.ch"

REQUEST DBFCDX

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

function Main()

聽 聽local oDlg, oFont, oBrw, oCol, bIndexBlock

聽 聽USE FBASEDATOS NEW EXCLUSIVE VIA "DBFCDX"
聽 聽SET ORDER TO TAG FBDIND2
聽 聽GO TOP

聽 聽DEFINE FONT oFont NAME "TAHOMA" SIZE 0,-14
聽 聽DEFINE DIALOG oDlg SIZE 550,600 PIXEL TRUEPIXEL FONT oFont

聽 聽@ 80,20 XBROWSE oBrw SIZE -20,-20 PIXEL OF oDlg ;
聽 聽 聽 ALIAS "FBASEDATOS" ;
聽 聽 聽 COLUMNS "FAMIBD_FBD", "DESCRI_FBD", "NOMBD_FBD","INDEXA_FBD" ;
聽 聽 聽 HEADERS "Group", "Description", "DBF", "INDEX" ;
聽 聽 聽 LINES NOBORDER

聽 聽WITH OBJECT oBrw
聽 聽 聽 :lHScroll := .f.
聽 聽 聽 WITH OBJECT :Index
聽 聽 聽 聽 聽:SetCheck()
聽 聽 聽 END
聽 聽 聽 :SetTree( 2, { FWDArrow(), FWRArrow(), "c:\fwh\bitmaps\new2.bmp" } )
聽 聽 聽 :oTree:OpenAll()
聽 聽 聽 WITH OBJECT :Index
聽 聽 聽 聽 聽bIndexBlock := :bEditValue
聽 聽 聽 聽 聽:bEditValue := { |x| If( oBrw:oTreeItem:nLevel == 1, IsGroupIndexed( oBrw ), Eval( bIndexBlock, x ) ) }
聽 聽 聽 聽 聽:bLDClickData := { || If( oBrw:oTreeItem:nLevel == 1, IndexGroup( oBrw ), IndexOne( oBrw ) ) }
聽 聽 聽 END
聽 聽 聽 :bKeyChar 聽 := { |k| If( k == 32, ( If( oBrw:oTreeItem:nLevel == 1, IndexGroup( oBrw ), IndexOne( oBrw ) ), 0 ), nil ) }
聽 聽 聽 :bClrStd 聽 聽:= { || { CLR_BLACK, If( oBrw:oTreeItem:nLevel == 1, ;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 If( oBrw:Index:Value, 0x60ff60, 0XB0ffB0 ), ;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 If( oBrw:Index:Value, 0xaeffff, CLR_WHITE ) ) } }

聽 聽 聽 :nStretchCol 聽 := 1
聽 聽 聽 //
聽 聽 聽 :CreateFromCode()
聽 聽END

聽 聽@ 20, 20 BUTTON "IndexOne" 聽SIZE 200,40 PIXEL OF oDlg ACTION ( oBrw:cAlias )->( IndexOne( oBrw ) )
聽 聽@ 20,240 BUTTON "IndexGroup" SIZE 200,40 PIXEL OF oDlg ACTION ( oBrw:cAlias )->( IndexGroup( oBrw ) )

聽 聽ACTIVATE DIALOG oDlg CENTERED
聽 聽RELEASE FONT oFont

return nil

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

static function IndexOne( oBrw )

聽 聽local cDbf 聽:= FIELD->NOMBD_FBD

聽 聽if !Empty( cDbf )
聽 聽 聽 // Do your work here and set the value of the field INDEXA_FBD
聽 聽 聽 FIELD->INDEXA_FBD := !FIELD->INDEXA_FBD
聽 聽 聽 oBrw:Refresh()
聽 聽endif

return nil

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

static function IndexGroup( oBrw )

聽 聽local nSaveRec := RECNO()
聽 聽local cGroup 聽 := UPPER( If( oBrw:oTreeItem:nLevel == 1, oBrw:oTreeItem:cPrompt, FIELD->FAMIBD_FBD ) )

聽 聽Go Top
聽 聽if ( DBSEEK( cGroup ) )
聽 聽 聽 do while UPPER( FIELD->FAMIBD_FBD ) == cGroup
聽 聽 聽 聽 聽// do your work here and set INDEXA_FBD
聽 聽 聽 聽 聽FIELD->INDEXA_FBD := !FIELD->INDEXA_FBD
聽 聽 聽 聽 聽DBSKIP( 1 )
聽 聽 聽 enddo
聽 聽 聽 DBSKIP( 1 )
聽 聽endif

聽 聽DBGOTO( nSaveRec )
聽 聽oBrw:Refresh()

return nil

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

static function IsGroupIndexed( oBrw )

聽 聽local lRet 聽:= .t.
聽 聽local nSaveRec := RECNO()
聽 聽local cGroup 聽 := UPPER( If( oBrw:oTreeItem:nLevel == 1, oBrw:oTreeItem:cPrompt, FIELD->FAMIBD_FBD ) )

聽 聽Go Top
聽 聽if ( DBSEEK( cGroup ) )
聽 聽 聽 do while UPPER( FIELD->FAMIBD_FBD ) == cGroup
聽 聽 聽 聽 聽// do your work here and set INDEXA_FBD
聽 聽 聽 聽 聽if !FIELD->INDEXA_FBD
聽 聽 聽 聽 聽 聽 lRet 聽:= .f.
聽 聽 聽 聽 聽 聽 EXIT
聽 聽 聽 聽 聽endif
聽 聽 聽 聽 聽DBSKIP( 1 )
聽 聽 聽 enddo
聽 聽endif

聽 聽DBGOTO( nSaveRec )

return lRet


Finalmente al ingresar este c贸digo en mi sistema pude lograr la siguiente imagen, del m贸dulo de Re Indexaci贸n de Base de datos:




Espero que esta idea innovadora pueda a alguien servirle de ayuda, la cual quise compartir con todos Uds. Finalmente no quisiera dejar de darle las gracias a Rao por su inmenso apoyo incondicional con todos nosotros, siempre esta dispuesto a ayudarnos y guiarnos cuando lo necesitamos.

Un abrazo cari帽oso y feliz fin de Semana Santa.

Sergio Vacarezza S.
Programador Freelance
sergio@vacarezza.cl
Santiago, Chile

Harbour 3.2.0dev (r2407221137) - FWH 24.08 - MariaDB 12.2.2 - FivEdit 22.0214

Continue the discussion