FiveTech Support Forums

FiveWin / Harbour / xBase community
Board index FiveWin for Harbour/xHarbour xbrowse
Posts: 883
Joined: Thu Dec 24, 2009 12:46 AM
xbrowse
Posted: Wed Apr 10, 2013 04:34 AM
Hi all,
I have a xBrowse which has a relation between two databases...

Code (fw): Select all Collapse
dbSETRELATION( Familia , {|| (Articulo)->CodFam}, "(Articulo)->CodFam" )

So I haveit indexed by
1.- CodFam
2.- Name

I create the xBrowse like this:
Code (fw): Select all Collapse
REDEFINE xBrowse oBrw ;
    FIELDS (Articulo)->Descrip, ;
           (Familia)->Name ;
    ID 4005 OF oDlg


When I use (Familia)->(dbsetorder(1)) the second Field shows (ordered by CodFam, not ordered by name), but if I change to (Familia)->(dbsetorder(2)), the data does not even shows...

Is there a way to show the data of this Field in a different order than the one used by dbSetRelation????

=====>

Bayron Landaverry
xBasePHP.com
(215)2226600 Philadelphia,PA, USA
MayaBuilders@gMail.com
Guatemala

FWH25.06--Harbour 3.0.0--BCC7.7--UEstudio 10.10
Windows 10

FiveWin, One line of code and it's done...

Posts: 166
Joined: Wed Aug 29, 2012 08:25 AM
Re: xbrowse
Posted: Wed Apr 10, 2013 06:21 AM
Bayron wrote:Hi all,
I have a xBrowse which has a relation between two databases...

Code (fw): Select all Collapse
dbSETRELATION( Familia , {|| (Articulo)->CodFam}, "(Articulo)->CodFam" )

So I haveit indexed by
1.- CodFam
2.- Name

I create the xBrowse like this:
Code (fw): Select all Collapse
REDEFINE xBrowse oBrw ;
    FIELDS (Articulo)->Descrip, ;
           (Familia)->Name ;
    ID 4005 OF oDlg


When I use (Familia)->(dbsetorder(1)) the second Field shows (ordered by CodFam, not ordered by name), but if I change to (Familia)->(dbsetorder(2)), the data does not even shows...

Is there a way to show the data of this Field in a different order than the one used by dbSetRelation????


Using bchange , it must be possible :
oBrw:bChange := {||(Familia)->(dbsetorder(1)) , (Familia)->(Dbseek((Articulo)->CodFam)),(Familia)->(dbsetorder(2)) }

A better solution is to use a function
FUNC DB_SEEK(x,nOrder)
local cMemOrder := OrdSetFocus()
dbsetorder(nOrder)
dbseek(x)
OrdSetfocus(cMemOrder)
RETURN found()
Odlg:bInit should also call oBrw:bChange !
Frank
test
Posts: 10733
Joined: Sun Nov 19, 2006 05:22 AM
Re: xbrowse
Posted: Wed Apr 10, 2013 07:28 AM

This is not an issue relating to XBrowse, but a matter relating to understanding and managing "relationships" and "indexes" in RDD. First we handle this the way we need, without getting confused with xbrowse or some other browse. Once we do this first, browsing in any browser is a matter or routine.

Once we set relation, we can NOT change the order of the child DBF without breaking the relationship. We can change the order of the parent dbf but not the child dbf.

We can create an additional index order on the parent dbf with expression "child->columnname". This is now an additional tag of the parent dbf and so we can change to it.

SELECT ARTICULO
SET RELATION TO CODFAM INTO FAMILIA
GO TOP
INDEX ON FAMILIA->NAME TAG FAMILA_NAME TO TMP MEMORY ADDITIVE
// RESET ORDER TO THE FIRST ORDER AS YOU WANT

REDEFINE xBrowse oBrw id 4005 OF oDlg ;
COLUMNS "DESCRIP", "FAMILA->NAME" ; // Never use FIELDS. Always use COLUMNS
HEADERS "DESCRIPTION", "NAME" ;
ALIAS "ARTICULO" // Never Never Omit this

WITH OBJECT oBrw:aCols[ 2 ]
:cSortOrder := "FAMILA_NAME"
:cOrdBag := "TMP"
END

// other code
NOTE: I have assumed that ARTICULO and FAMILA are real ALIAS names and not variable names containing the alias names. If they are variable names, pls change the code accordingly

Regards



G. N. Rao.

Hyderabad, India
Posts: 883
Joined: Thu Dec 24, 2009 12:46 AM
Re: xbrowse
Posted: Wed Apr 10, 2013 12:56 PM
Mr Rao,
Your example is very concise and self explanatory, even though I have not been able to replicate, because I just started to change from NTX to CDX and my indexes are still a mess... I will change this in the future, but for now I still have them like this...

Code (fw): Select all Collapse
    Familia := Open_Dbf("Familia")
    (Familia)->(DBSETINDEX(Ruta + "CodigoF"))
    (Familia)->(DBSETINDEX(Ruta + "FamName"))
    (Familia)->(dbsetorder(1))
    
    Articulo := Open_Dbf("Articulo")
    (Articulo)->(DBSETINDEX(Ruta + "CodigoA"))
    (Articulo)->(DBSETINDEX(Ruta + "Descrip"))
    (Articulo)->(DBSETINDEX(Ruta + "CodigoC"))
    (Articulo)->(dbsetorder(1))

Where Open_Dbf() is a function which opens the database and returns a diferent Alias every time I open a database...(MDI)
That been said: How can I set COLUMNS taking under consideration that the Alias is a variable???

=====>

Bayron Landaverry
xBasePHP.com
(215)2226600 Philadelphia,PA, USA
MayaBuilders@gMail.com
Guatemala

FWH25.06--Harbour 3.0.0--BCC7.7--UEstudio 10.10
Windows 10

FiveWin, One line of code and it's done...

Posts: 883
Joined: Thu Dec 24, 2009 12:46 AM
Re: xbrowse
Posted: Wed Apr 10, 2013 01:12 PM
Franklin Demont wrote:Using bchange , it must be possible :
oBrw:bChange := {||(Familia)->(dbsetorder(1)) , (Familia)->(Dbseek((Articulo)->CodFam)),(Familia)->(dbsetorder(2)) }

A better solution is to use a function
FUNC DB_SEEK(x,nOrder)
local cMemOrder := OrdSetFocus()
dbsetorder(nOrder)
dbseek(x)
OrdSetfocus(cMemOrder)
RETURN found()
Odlg:bInit should also call oBrw:bChange !
Frank


Thanks Frank for your answer, but I am not trying to wild seek data in the browser... I am just trying to order the columns...!
I am not sure, but I think that the way you explained it, is taken care by the relation between the databases...

=====>

Bayron Landaverry
xBasePHP.com
(215)2226600 Philadelphia,PA, USA
MayaBuilders@gMail.com
Guatemala

FWH25.06--Harbour 3.0.0--BCC7.7--UEstudio 10.10
Windows 10

FiveWin, One line of code and it's done...

Posts: 883
Joined: Thu Dec 24, 2009 12:46 AM
Re: xbrowse
Posted: Wed Apr 10, 2013 02:27 PM
How can I set COLUMNS taking under consideration that the Alias is a variable???

Just in case, this is the complete list of columns as I have them right now...:
Code (fw): Select all Collapse
FIELDS (Articulo)->Descrip, ;
       (Familia)->Nombre, ;
       (Articulo)->Texto_Tecl, ;
       iIf((Articulo)->Cocina=.T.,'Sí','No'), ;
       Tran((Articulo)->pVenta_Bar,'99,999.99'), ;
       Tran((Articulo)->pVenta_Mes,'99,999.99'), ;
       Tran((Articulo)->pVenta_Ter,'99,999.99') ;


Thanks

=====>

Bayron Landaverry
xBasePHP.com
(215)2226600 Philadelphia,PA, USA
MayaBuilders@gMail.com
Guatemala

FWH25.06--Harbour 3.0.0--BCC7.7--UEstudio 10.10
Windows 10

FiveWin, One line of code and it's done...

Posts: 883
Joined: Thu Dec 24, 2009 12:46 AM
Re: xbrowse
Posted: Wed Apr 10, 2013 11:06 PM
Hello Mr. Rao:
Since the solution to this problem was a little too complex..., I did the next thing I could do...
Fixed my Index Files and included the TAG argument... (Just to be up to date)
Added a Field (Articulo)->Name and indexed by it
Set the dbRelation by that Field...

It was that simple...

And since you like my footer phrase, here is another:

Some times when programming with FiveWin for Harbour,
We expect to receive a simple solution from the forum and make us forget to use the other simple solution that we know
FiveWin, at the end, they all are simple solutions...

=====>

Bayron Landaverry
xBasePHP.com
(215)2226600 Philadelphia,PA, USA
MayaBuilders@gMail.com
Guatemala

FWH25.06--Harbour 3.0.0--BCC7.7--UEstudio 10.10
Windows 10

FiveWin, One line of code and it's done...

Posts: 10733
Joined: Sun Nov 19, 2006 05:22 AM
Re: xbrowse
Posted: Wed Apr 10, 2013 11:15 PM
Code (fw): Select all Collapse
// Somewhere at the very beginning in the Main() function
XbrNumFormat( "A", .t. )
   // When XBrowse automatically generates pictures or numeric values
   // American format ( commas as thousand separators ) is used 
   // and thousand separators are used.
   // If First parameter is 'E', numbers are formatted in European Format


function BrowseArticulo

// Open all DBFs and set relations

// define dialog    

cAmtPic     := NumPict( 7, 2 )  // FW Generates picture clause --> "99,999.99" or "@E 99,999.99" 
                         // depending on XbrNumFormat(....)

REDEFINE xBrowse oBrw ID 4005 OF oDlg ALIAS Articulo ;
   COLUMNS "Descrip", { || ( Familia )->Nombre }, "Texto_Tecl", ;
      "Cocina",  "pVenta_Bar", "pVenta_Mes", "pVenta_Ter" ;
   HEADERS "Description", "Nombre", "Tecl", "Cocina", "Bar", "Mes", "Ter" ;
   PICTURES nil, nil, nil, nil, cAmtPic, cAmtPic, cAmtPic ;
   AUTOSORT CELL LINES      

/*
   Notes:  (1) "ALIAS Atrticulo".  We need to inform xbrowse that we want to
   use Articulo as the main Table to navigate
   (2) COLUMNS: XBrowse examines the columns and determines the datatypes,
   pictures, sort indexes, proper alignment of data and generates necessary
   codeblocks. 
   (3) PICTURES: This is optional. Because XBrowse knows that the main table is
   Articulo, it knows what columns are numeric and automatically generates 
   picture clauses based on field length and field dec.
   We can override by providing our own pictures.
   
*/


WITH OBJECT oBrw
   :Cocina:SetCheck( nil, nil, { 'Si', 'No' } )
END

ACTIVATE DIALOG oDlg CENTERED
Regards



G. N. Rao.

Hyderabad, India
Posts: 10733
Joined: Sun Nov 19, 2006 05:22 AM
Re: xbrowse
Posted: Thu Apr 11, 2013 12:06 AM
Hello Mr. Rao:
Since the solution to this problem was a little too complex..., I did the next thing I could do...
Fixed my Index Files and included the TAG argument... (Just to be up to date)
Added a Field (Articulo)->Name and indexed by it
Set the dbRelation by that Field...


I would still advise you not to maintain regular indexes (on disk) with aliased expressions and in particular with alias of related tables. Instead you may use temporary indexes in memory for such purposes as and when needed.

In your above example you need not have to change anything in the existing indexes.
Here is the code I suggest:
Code (fw): Select all Collapse
// open the tables in ur present way

Familia := Open_Dbf("Familia")
(Familia)->(DBSETINDEX(Ruta + "CodigoF"))
(Familia)->(DBSETINDEX(Ruta + "FamName"))
(Familia)->(dbsetorder(1))
 
Articulo := Open_Dbf("Articulo")
(Articulo)->(DBSETINDEX(Ruta + "CodigoA"))
(Articulo)->(DBSETINDEX(Ruta + "Descrip"))
(Articulo)->(DBSETINDEX(Ruta + "CodigoC"))
(Articulo)->(dbsetorder(1))

dbSETRELATION( Familia , {|| (Articulo)->CodFam}, "(Articulo)->CodFam" )

GO TOP
INDEX ON (Famila)->NAME TAG F_NAME TO TMP_FNAME MEMORY ADDITIVE
DBSETORDER( 1 )
GO TOP


// create dialog etc

REDEFINE xBrowse oBrw ID 4005 OF oDlg ALIAS Articulo ;
   COLUMN  "Descrip", { || (Familia)->Name } ;
   HEADERS "Description", "Name" ;
   SORT nil, "F_NAME" ;
   AUTOSORT CELL LINES
   
oBrw:aCols[ 2 ]:cOrdBag := "TMP_FNAME"

// other code

ACTIVATE DIALOG oDlg CENTERED
Regards



G. N. Rao.

Hyderabad, India
Posts: 883
Joined: Thu Dec 24, 2009 12:46 AM
Re: xbrowse
Posted: Thu Apr 11, 2013 01:29 AM

Thank you Mr. Rao,
I really like your approach... Very concise...

=====>

Bayron Landaverry
xBasePHP.com
(215)2226600 Philadelphia,PA, USA
MayaBuilders@gMail.com
Guatemala

FWH25.06--Harbour 3.0.0--BCC7.7--UEstudio 10.10
Windows 10

FiveWin, One line of code and it's done...

Continue the discussion