For those colleagues who are comfortable with the use of array of key numbers, I have made a derived class.
- Code: Select all Expand view RUN
#include 'fivewin.ch'
#include 'hbcompat.ch'
#include 'xbrowse.ch'
//------------------------------------------------------------------//
CLASS TQBrowse FROM TXBrowse
CLASSDATA lRegistered AS LOGICAL // This is compulsory for derived classes
DATA bColClass INIT { || TQBrwColumn() }
//
DATA aSQKeys INIT Array( 0 )
DATA lDescend INIT .f.
//
METHOD Adjust()
METHOD SetRDD( lAddColumns, lAutoOrder, aFldNames, aRows )
METHOD Paint()
//
METHOD SQKeyNo( n )
METHOD BuildSqKeyArray()
ENDCLASS
//----------------------------------------------------------------------------//
METHOD Adjust() CLASS TQBrowse
::Super:Adjust()
if ValType( ::aSQKeys ) == 'A'
( ::cAlias )->( ::BuildSqKeyArray() )
endif
return Self
//----------------------------------------------------------------------------//
METHOD SetRDD( lAddColumns, lAutoOrder, aFldNames, aRows ) CLASS TQBrowse
::Super:SetRDD( lAddColumns, lAutoOrder, aFldNames, aRows )
::bKeyCount := { || ( ::cAlias )->( OrdKeyCount() ) }
::bKeyNo := { |n| ( ::cAlias )->( ::SQKeyNo( n ) ) }
return nil
//----------------------------------------------------------------------------//
METHOD Paint() CLASS TQBrowse
if ValType( ::aSqKeys ) == 'A' .and. Len( ::aSqKeys ) != ::nLen
// in rare cases of addition / deletion of records
( ::cAlias )->( ::BuildSqKeyArray() )
endif
return ::Super:Paint()
//----------------------------------------------------------------------------//
METHOD SQKeyNo( nGoTo ) CLASS TQBrowse
local nRet
if Empty( ::aSqKeys )
nRet := If( nGoTo == nil, OrdKeyNo(), OrdKeyGoTo( nGoTo ) )
else
if nGoTo == nil
nRet := AScan( ::aSqKeys, RecNo() )
if ::lDescend
nRet := ::nLen - nRet + 1
endif
else
if ::lDescend
nGoTo := ::nLen - nGoTo + 1
endif
DbGoTo( ::aSqKeys[ nGoTo ] )
endif
endif
return nRet
//----------------------------------------------------------------------------//
METHOD BuildSqKeyArray() CLASS TQBrowse
local nKey, nRec := RecNo()
CursorWait()
::lDescend := .f.
if ! Empty( OrdSetFocus() )
::lDescend := OrdDescend()
endif
::aSqKeys := Array( ::nLen := OrdKeyCount() )
DbGoTop()
if ::lDescend
nKey := Len( ::aSqKeys )
DBEVAL( { || ::aSqKeys[ nKey ] := RecNo(), nKey-- } )
else
nKey := 1
DBEVAL( { || ::aSqKeys[ nKey ] := RecNo(), nKey++ } )
endif
DbGoTo( nRec )
return nil
//----------------------------------------------------------------------------//
//----------------------------------------------------------------------------//
CLASS TQBrwColumn FROM TXBrwColumn
METHOD SetOrder()
ENDCLASS
//----------------------------------------------------------------------------//
METHOD SetOrder() CLASS TQBrwColumn
local lSorted
local cAlias := ::oBrw:cAlias
local cOrder := ( cAlias )->( OrdSetFocus() )
local nRec := RecNo()
lSorted := ::Super:SetOrder()
if lSorted .and. ValType( ::oBrw:aSqKeys ) == 'A'
::oBrw:lDescend := ( cAlias )->( OrdDescend() )
if ( cAlias )->( OrdSetFocus() ) == cOrder
else
( cAlias )->( ::oBrw:BuildSqKeyArray() )
endif
DbGoTo( nRec )
endif
return lSorted
//----------------------------------------------------------------------------//
You may use this new class in your program:
1. oBrw := TQBrowse():New( oWnd )
OR
2. @ r,c XBROWSE <........ clauses .......> CLASS TQBrowse()
I have tested with MySql tables on my local MySql server and performance is okay.
I shall be glad to have feedback from the users.