XBrowse Array Incremental Search

XBrowse Array Incremental Search

Postby TimStone » Tue Feb 09, 2010 7:12 pm

With a DBF, using xBrowse, I can implement an incremental search as follows:

oLbx:bSeek := { |c| oDbf:Seek( c ) }

I am having difficulty with an incremental search on an array in an xBrowse.

Can someone point me in the right direction ? For an example, use the browse object oLbx and the array list is aValList

Thanks
Tim Stone
http://www.MasterLinkSoftware.com
http://www.autoshopwriter.com
timstone@masterlinksoftware.com
Using: FWH 23.10 with Harbour 3.2.0 / Microsoft Visual Studio Community 2022-24 32/64 bit
User avatar
TimStone
 
Posts: 2944
Joined: Fri Oct 07, 2005 1:45 pm
Location: Trabuco Canyon, CA USA

Re: XBrowse Array Incremental Search

Postby Antonio Linares » Tue Feb 09, 2010 8:20 pm

Tim,

Please try this:

oBrowse:bSeek := { | c | SeekOnArray( oBrowse, oBrowse:aArrayData, c ) }
regards, saludos

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

Re: XBrowse Array Incremental Search

Postby TimStone » Tue Feb 09, 2010 8:57 pm

OK ... this is a 3 element array so I want to do the seek on element 3. It is in the first column.

As your code is written it does not move the array ...

How can I limit to column 1, element 3 for the seek ?
Tim Stone
http://www.MasterLinkSoftware.com
http://www.autoshopwriter.com
timstone@masterlinksoftware.com
Using: FWH 23.10 with Harbour 3.2.0 / Microsoft Visual Studio Community 2022-24 32/64 bit
User avatar
TimStone
 
Posts: 2944
Joined: Fri Oct 07, 2005 1:45 pm
Location: Trabuco Canyon, CA USA

Re: XBrowse Array Incremental Search

Postby Antonio Linares » Tue Feb 09, 2010 9:23 pm

Tim,

function SeekOnArray() source code is located in source\classes\xbrowse.prg. You can easily trace it and check how it is behaving, or please provide a small working example that we may test here, thanks
regards, saludos

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

Re: XBrowse Array Incremental Search

Postby TimStone » Tue Feb 09, 2010 10:18 pm

I guess I'm trying to understand the logic of SeekOnArray.

It scans the array of columns for one that is not empty with a cOrder value. How do I set the cOrder value for a multi dimensional array ? I do not see anything in the existing code that does this.

That is probably why I can't get this to work.

Tim
Tim Stone
http://www.MasterLinkSoftware.com
http://www.autoshopwriter.com
timstone@masterlinksoftware.com
Using: FWH 23.10 with Harbour 3.2.0 / Microsoft Visual Studio Community 2022-24 32/64 bit
User avatar
TimStone
 
Posts: 2944
Joined: Fri Oct 07, 2005 1:45 pm
Location: Trabuco Canyon, CA USA

Re: XBrowse Array Incremental Search

Postby Antonio Linares » Tue Feb 09, 2010 11:43 pm

Tim,

You can use that DATA cOrder value to select the column where you want to do the search :-)

oBrowse:aCols[ 1 ]:cOrder = "A" // "A" for Ascending, "D" for Descending

1 for first column, etc.
regards, saludos

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

Re: XBrowse Array Incremental Search

Postby TimStone » Wed Feb 10, 2010 2:04 am

Here is the actual function. The array passed to it is a 3 element array of GL numbers. It displays with the number in column 1. The idea is to be able to type in a GL number and reposition the browse. Now it just dings when I type in a number. Except for the incremental seek not functioning, it works perfectly.

FUNCTION GLFind2( )

// Declare EXTERNAL variables
MEMVAR oWnd, aGLList
// Declare LOCAL variables
PRIVATE lx, ItmFound := .F., cGLRetVal, oDlgl, oLbxgl, nPos, oHd1, oHd2, nItem := 1

// Create the dialog
DEFINE BRUSH olBrush RESOURCE "SKY"
DEFINE DIALOG oDlglf RESOURCE "PROBROW" BRUSH olBrush transparent OF oWnd TITLE "GL Accounts" FONT oWnd:oFont

// Create the control buttons
REDEFINE BTNBMP RESOURCE "HROK" PROMPT "Accept" ID 2101 of oDlglf TOOLTIP "Accept" NOBORDER TRANSPARENT ;
ACTION ( cGLRetVal := aGLList[oLbxglf:nArrayAt][3], oDlglf:End()) MESSAGE "Use the highlighted GL Account"

// Create the browse
REDEFINE XBROWSE oLbxglf ID 2100 OF oDlglf ON DBLCLICK( cGLRetVal := aGLList[oLbxglf:nArrayAt][3], oDlglf:End()) ;
MESSAGE "Double click on an item to select an account"

// Attach the array
oLbxglf:setArray( aGLList )
oLbxglf:aCols := {}

// Add the columns
ADD TO oLbxglf DATA ARRAY ELEMENT 3 HEADER "Account" SIZE 80 ALIGN LEFT
ADD TO oLbxglf DATA ARRAY ELEMENT 1 HEADER "Description" SIZE 150 ALIGN LEFT
ADD TO oLbxglf DATA ARRAY ELEMENT 2 HEADER "D/C" SIZE 50 ALIGN CENTER

// Provide the header gradient
oLbxglf:bClrGrad := { | lInvert | If( ! lInvert, { { 0.50,16776960,16777215 }, ;
{ 0.50,16777215,16776960 } }, { { 0.50,128,16777215 }, { 0.50,16777215,128 } } ) }
// Set the header and row heights
oLbxglf:nHeaderHeight := 30
oLbxglf:nRowHeight := 24
oLbxglf:nStretchCol( STRETCHCOL_WIDEST )

// Turn off horizontal scrolling
oLbxglf:lHScroll := .F.

// Set the styles
oLbxglf:nMarqueeStyle := MARQSTYLE_HIGHLROW
oLbxglf:nColDividerStyle := LINESTYLE_RAISED
oLbxglf:nRowDividerStyle := LINESTYLE_RAISED

oLbxglf:aCols[ 1 ]:cOrder = "A" // "A" for Ascending, "D" for Descending
oLbxglf:bSeek := { | c | SeekOnArray( oLbxglf, oLbxglf:aArrayData, c ) }

FOR nCCol := 1 TO LEN( oLbxglf:acols )
oLbxglf:aCols[nCCol]:nHeadStrAlign := AL_CENTER
NEXT

// Activate the dialog
ACTIVATE DIALOG oDlglf ON INIT ( oDlglf:center(wndmain()) )

RETURN( cGLRetVal )
Tim Stone
http://www.MasterLinkSoftware.com
http://www.autoshopwriter.com
timstone@masterlinksoftware.com
Using: FWH 23.10 with Harbour 3.2.0 / Microsoft Visual Studio Community 2022-24 32/64 bit
User avatar
TimStone
 
Posts: 2944
Joined: Fri Oct 07, 2005 1:45 pm
Location: Trabuco Canyon, CA USA

Re: XBrowse Array Incremental Search

Postby Antonio Linares » Wed Feb 10, 2010 11:28 am

Tim,

Here you have a working example:
Code: Select all  Expand view
#include "FiveWin.ch"
#include "XBrowse.ch"

function Main()

   local oDlg, oBrw
   local aValues := { { "one", "two", "three" }, { "four", "five", "six" }, { "seven", "eight", "nine" } }

   DEFINE DIALOG oDlg SIZE 400, 300

   @ 1, 1 XBROWSE oBrw ARRAY aValues SIZE 185, 120
   
   oBrw:CreateFromCode()
   oBrw:bSeek := { | cKey | SeekOnArray( oBrw,, cKey ) }
   
   ACTIVATE DIALOG oDlg CENTER ;
      ON INIT ( oBrw:aCols[ 1 ]:cOrder := "D" )

return nil
 
regards, saludos

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

Re: XBrowse Array Incremental Search

Postby nageswaragunupudi » Wed Feb 10, 2010 11:41 am

XBrowse's built-in incremental seek functionality is very good. But in case of Arrays this functionality works perfectly only when the Array columns are set sequentially from columns 1,2,3 ... The logic fails when the order of the columns is not sequential.

I propose this sample code to address Mr. Tim's problem:
Code: Select all  Expand view
#include "FiveWin.Ch"
#include "xbrowse.ch"

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

function Main()

   local oDlg, oBrw
   local aData := { ;
     { 4578, 'Sales',    'B012' }, ;
     {  234, 'Purchaes', 'B342'  }, ;
     {   75, 'Wages',    'C567'  }, ;
     { 1435, 'Freight',  'C203' } }


   DEFINE DIALOG oDlg SIZE 440,240 PIXEL
   @ 10,10 XBROWSE oBrw SIZE 200,100 PIXEL OF oDlg ;
      COLUMNS 3, 2, 1 ;
      HEADERS 'Account', 'Description', 'D/C' ;
      COLSIZES 80,150,80 ;
      ARRAY aData ;
      AUTOSORT ;
      ON DBLCLICK ( MsgInfo( oBrw:aRow[ 3 ] ), oDlg:End() )
      // Note: oBrw:aRow is shortcut for oBrw:aArrayData[oBrw:nArrayAt]

   oBrw:nStretchCol := 2

   //  Following three lines are needed till XBrowse is rectified
   oBrw:aCols[ 1 ]:cOrder := 'D'
   oBrw:aCols[ 1 ]:SetOrder()
   oBrw:bSeek  := { |c| ArrayIncrSeek( oBrw, aData, c ) }

   // < .. other browse settings .. >

   oBrw:CreateFromCode()

   ACTIVATE DIALOG oDlg CENTERED

return ( 0 )

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

function ArrayIncrSeek( oBrw, aData, cSeek )

   local nRow, nCol
   local cVal

   if ( nCol := AScan( oBrw:aCols, { |oCol| ! Empty( oCol:cOrder ) } ) ) > 0
      // following line is ommitted in TXBrowse source code
      nCol  := oBrw:aCols[ nCol ]:nArrayCol
      cSeek := Upper( cSeek )
      for nRow := 1 to Len( aData )
        if Upper( cValToChar( aData[ nRow ][ nCol ] ) ) = cSeek     // non-exact =
            oBrw:nArrayAt := nRow
            return .t.
         endif
      next nRow
   endif

return .f.

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

This code may be compiled to see that now the incremental seek works. After verifying, Mr. Tim may please add his specific functionality.

The above incremental seek function can be used generally for all array browses where the columns are not sequential.

If Mr. Antonio permits, I shall separately communicate my proposed fixes to the XBrowse code.
Regards

G. N. Rao.
Hyderabad, India
User avatar
nageswaragunupudi
 
Posts: 10627
Joined: Sun Nov 19, 2006 5:22 am
Location: India

Re: XBrowse Array Incremental Search

Postby Antonio Linares » Wed Feb 10, 2010 11:46 am

Dear Rao,

many thanks for your great feedback and help as usual :-)
regards, saludos

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

Re: XBrowse Array Incremental Search

Postby TimStone » Thu Feb 11, 2010 9:00 pm

Thank you. I had noted that the behavior was not working correctly when the columns were not in order. I look forward to the fix in xBrowse.

The interim solution works great. Thanks.
Tim Stone
http://www.MasterLinkSoftware.com
http://www.autoshopwriter.com
timstone@masterlinksoftware.com
Using: FWH 23.10 with Harbour 3.2.0 / Microsoft Visual Studio Community 2022-24 32/64 bit
User avatar
TimStone
 
Posts: 2944
Joined: Fri Oct 07, 2005 1:45 pm
Location: Trabuco Canyon, CA USA

Re: XBrowse Array Incremental Search

Postby anserkk » Wed Mar 03, 2010 11:07 am

Hi,

Is this problem solved ?

As Per Antonio, Whats new in FWH 10.2 wrote:* Fix: XBrowse.prg: Incremental seek on Arrays works only when columns are added sequentially and that too in the
SetArray method. Now fixed. Incremental seek works irrespective of the order of the array columns if lAutoSort is
set to true in SetArray method.


I am getting compilation error When I tried the Sample Posted above by Mr.Antonio
Code: Select all  Expand view

#include "FiveWin.ch"
#include "XBrowse.ch"

function Main()

   local oDlg, oBrw
   local aValues := { { "one", "two", "three" }, { "four", "five", "six" }, { "seven", "eight", "nine" } }

   DEFINE DIALOG oDlg SIZE 400, 300

   @ 1, 1 XBROWSE oBrw ARRAY aValues SIZE 185, 120
   
   oBrw:CreateFromCode()
   oBrw:bSeek := { | cKey | SeekOnArray( oBrw,, cKey ) }
   
   ACTIVATE DIALOG oDlg CENTER ;
      ON INIT ( oBrw:aCols[ 1 ]:cOrder := "D" )

return nil


Compilation Error :=
Unresolved external '_HB_FUN_SEEKONARRAY' referenced from D:\FwhTest\Test.Obj


When I changed the line to
Code: Select all  Expand view
oBrw:bSeek := { | cKey | oBrw:SeekOnArray( oBrw,, cKey ) }


Then there are no compilation errors, but I get the following Run time error

Application
===========
Path and name: D:\FWHTest\test.exe (32 bits)
Size: 1,769,984 bytes
Time from start: 0 hours 0 mins 2 secs
Error occurred at: 03/03/10, 16:25:59
Error description: Error BASE/1004 Message not found: TXBROWSE:SEEKONARRAY
Args:

Stack Calls
===========
Called from: .\source\function\HARBOUR.PRG => _CLSSETERROR(166)
Called from: .\source\classes\XBROWSE.PRG => TXBROWSE:SEEKONARRAY(6980)
Called from: test.prg => (b)MAIN(14)
Called from: .\source\classes\XBROWSE.PRG => TXBROWSE:SEEK(5383)
Called from: .\source\classes\XBROWSE.PRG => TXBROWSE:KEYCHAR(2185)
Called from: => TWINDOW:HANDLEEVENT(0)
Called from: .\source\classes\CONTROL.PRG => TCONTROL:HANDLEEVENT(1464)
Called from: .\source\classes\XBROWSE.PRG => TXBROWSE:HANDLEEVENT(10470)
Called from: .\source\classes\WINDOW.PRG => _FWH(3378)
Called from: => DIALOGBOXINDIRECT(0)
Called from: .\source\classes\DIALOG.PRG => TDIALOG:ACTIVATE(273)
Called from: test.prg => MAIN(17)


Am I doing anything wrong ?

With Mr.Rao's sample, incremental search on Array using xBrowse is working fine.

Regards
Anser
User avatar
anserkk
 
Posts: 1332
Joined: Fri Jun 13, 2008 11:04 am
Location: Kochi, India

Re: XBrowse Array Incremental Search

Postby nageswaragunupudi » Wed Mar 03, 2010 12:29 pm

It is working fine for me with 10.2.

I advise you to keep in mind that when we specify AUTOSORT clause in the XBROWSE command or specify lAutoSort as parameter in any of the set methods like SetRDD, SetADO, SetODBF, SetArray, XBrowse automatically constructs bSeek codeblock. This default codeblock is generally much superior to what we can ourselves construct in our program. It is always desirable that we depend on the default codeblock created by XBrowse and not to disturb it by ourselves assigning our own codeblock to bSeek, unless we want an unconventional behavior.

In case of arrays, the SeekOnArray function of XBrowse had a minor bug till version 10.1 which effects array browses not having columns in serial from 1,2... Hence the need to have our own function.

SeekOnArray function in XBrowse is static function. Therefore it is not available for linking in our programs.

Mr. TimStone said
oLbx:bSeek := { |c| oDbf:Seek( c ) }

My personal advice is not to assign any codeblock to bSeek. The default codeblock generated by xBrowse is much better.
Regards

G. N. Rao.
Hyderabad, India
User avatar
nageswaragunupudi
 
Posts: 10627
Joined: Sun Nov 19, 2006 5:22 am
Location: India

Re: XBrowse Array Incremental Search

Postby nageswaragunupudi » Wed Mar 03, 2010 12:32 pm

Mr. Anser
With Mr.Rao's sample, incremental search on Array using xBrowse is working fine.

This is the one you should have for versions upto 10.1. Even this is needed only if your array browse is not columns 1,2,3 ... in serial order.

You may even replace SeekOnArray function inside xbrowse.prg and recompile.
Regards

G. N. Rao.
Hyderabad, India
User avatar
nageswaragunupudi
 
Posts: 10627
Joined: Sun Nov 19, 2006 5:22 am
Location: India

Re: XBrowse Array Incremental Search

Postby anserkk » Wed Mar 03, 2010 1:02 pm

Dear Mr.Rao,

Mr.Rao wrote:SeekOnArray function in XBrowse is static function. Therefore it is not available for linking in our programs.

This was the reason for the RunTime error. I misunderstood that Mr.Antonio was referring to the function SeekOnArray() which was available in xBrowse.Prg. As I received a compilation error, I assumed that Mr.Antonio must have missed the oBrw: in the sample code and changed the code to oBrw:bSeek := { | cKey | oBrw:SeekOnArray( oBrw,, cKey ) } which gave run time error. :oops:

Mr.Rao wrote:My personal advice is not to assign any codeblock to bSeek. The default codeblock generated by xBrowse is much better.


I was of the impression that oBrw:bSeek should be provided in our code for incremental search to work.

I removed the oBrw:bseek and let xBrowse to do the work for me and now everything is working as expected. Perfect !!! :)

Thank you very much. :)

Regards
Anser
User avatar
anserkk
 
Posts: 1332
Joined: Fri Jun 13, 2008 11:04 am
Location: Kochi, India

Next

Return to FiveWin for Harbour/xHarbour

Who is online

Users browsing this forum: Google [Bot] and 99 guests