Page 1 of 1

ArrayIncrFilter

Posted: Mon May 28, 2018 8:10 pm
by ORibeiro
How can I cancel the filter using ArrayIncrFilter and restore the standard view of xBrowse?

Re: ArrayIncrFilter

Posted: Mon May 28, 2018 11:38 pm
by Eric.Developer
Did you try this?

Code: Select all

oBrw:ArrayIncrFilter('')
then try this, but only for temporary testing:

Code: Select all

oBrw:lIncrFilter:=.f.
ORibeiro wrote:How can I cancel the filter using ArrayIncrFilter and restore the standard view of xBrowse?

Re: ArrayIncrFilter

Posted: Tue May 29, 2018 10:50 am
by ORibeiro
I tried it, but it does not work.

Do you have other idea?

Re: ArrayIncrFilter

Posted: Tue May 29, 2018 10:59 pm
by nageswaragunupudi
oBrw:Seek( "" ) clears the filter and displays the full array

Re: ArrayIncrFilter

Posted: Tue May 29, 2018 11:58 pm
by ORibeiro
Rao,

I tried it but does not work too.

Re: ArrayIncrFilter

Posted: Wed May 30, 2018 4:52 am
by Eric.Developer
You wrote little information.
What information are you filtering on the browse?
How did you define the browse lines? addRow or SetArray ...

if I'm not mistaken, you can not restore the rows because they have been removed (you can easily check this by debugging your system and browse instance).
Then you have to reassign with oBrw:setArray(...)
If you filled the browse with addRow then you should make a copy of oBrw:arrayData before the filter.

In my browse (in another tool), I show normal or just deleted lines, alternate doing reassignments.
ORibeiro wrote: Do you have other idea?

Re: ArrayIncrFilter

Posted: Wed May 30, 2018 5:28 am
by nageswaragunupudi
if I'm not mistaken, you can not restore the rows because they have been removed (you can easily check this by debugging your system and browse instance).
Then you have to reassign with oBrw:setArray(...)
XBrowse's incremental filter does not remove any lines. They are all there. User sees only the filtered lines.

Re: ArrayIncrFilter

Posted: Wed May 30, 2018 6:19 am
by nageswaragunupudi
ORibeiro wrote:Rao,

I tried it but does not work too.
This has to work, if I understood your requirement correctly.

Here is a sample:

Code: Select all

function Incfilter()

   local oDlg, oBrw, oFont
   local aData

   USE CUSTOMER
   aData := FW_DbfToArray( "FIRST,LAST,CITY" )
   CLOSE CUSTOMER

   DEFINE FONT oFont NAME "TAHOMA" SIZE 0,-14
   DEFINE DIALOG oDlg SIZE 700,500 PIXEL TRUEPIXEL FONT oFont

   @ 60,20 XBROWSE oBrw SIZE -20,-20 PIXEL OF oDlg ;
      DATASOURCE aData AUTOCOLS HEADERS "First", "Last", "City" ;
      CELL LINES NOBORDER AUTOSORT FOOTERS

   WITH OBJECT oBrw
      :lIncrFilter   := .t.
      // :lSeekWild  := .t.  // optional
      :aCols[ 1 ]:bFooter  := { || "Records : " + Str( oBrw:nLen ) }
      //
      :CreateFromCode()
   END

   @ 20,20 SAY oBrw:oSeek VAR oBrw:cSeek SIZE 150,20 PIXEL OF oDlg COLOR CLR_HRED, CLR_YELLOW UPDATE

   @ 10,200 BTNBMP PROMPT "Clear Filter" SIZE 200,40 PIXEL OF oDlg FLAT ;
      ACTION ( oBrw:Seek( "" ), oBrw:SetFocus() )

   ACTIVATE DIALOG oDlg CENTERED
   RELEASE FONT oFont

return nil
 
Pressing any key incrementally sets filter. Pressing backspace clears the filter.
At any stage, clicking the button "clear filter" clears the filter.

Re: ArrayIncrFilter

Posted: Wed May 30, 2018 2:01 pm
by ORibeiro
Rao,

What is wrong in this code?

Code: Select all

*********************************************************************************************
static function Sample2() // With ArrayIncFilter()
*********************************************************************************************
   local oDlg, oBrw, oFont, oBold
   local n
   local aData

   USE CUSTOMER NEW SHARED
   aData := FW_DbfToArray( "FIRST,LAST,CITY,HIREDATE,SALARY" )
   CLOSE CUSTOMER

   DEFINE FONT oFont NAME "TAHOMA" SIZE 0,-12
   DEFINE FONT oBold NAME "TAHOMA" SIZE 0,-12 BOLD

   DEFINE DIALOG oDlg SIZE 800,500 PIXEL TRUEPIXEL ;
      FONT oFont TITLE FWVERSION + " : Bar Get"

   @ 110,20 XBROWSE oBrw SIZE -20,-20 PIXEL OF oDlg ;
      DATASOURCE aData AUTOCOLS CELL LINES NOBORDER FASTEDIT

   // Relevant Code
   for n := 1 to Len( oBrw:aCols )
      WITH OBJECT oBrw:aCols[ n ]
         if     ValType(:Value) = 'C'
            :uBarGetVal := uValBlank(Space( :nDataLen ))
         elseif ValType(:Value) = 'N'    // 28-05-18: Ainda não consegui desenvolver o filtro para campos numéricos
            :uBarGetVal := 0.00
            :cBarGetPic := '@E 99999.99' // NumPict( :nDataLen, :nDataDec )
         elseif ValType(:Value) = 'D'
            :uBarGetVal := CTOD("")
            :cBarGetPic := '@D'
         endif
      END
   next
   oBrw:bClrEdits   := { || { CLR_BLACK, CLR_YELLOW } }
   oBrw:lIncrFilter := .T.
   oBrw:lGetBar     := .T.
   // End of Relevant Code

   oBrw:CreateFromCode()

   @ 10,20 SAY "Gets under Headers. Entered values can be used" + ;
      "for filtering or any othe purpose" + CRLF + ;
      "Usage: oCol:uBarGetVal := Space( 10 ); oBrw:lGetBar := .t." ;
      SIZE oDlg:nWidth - 40,40 PIXEL OF oDlg CENTER

   @ 60, 20 BTNBMP PROMPT { || If( oBrw:lGetBar, "Hide GetBar", "ShowGetBar" ) } ;
      SIZE 100,40 PIXEL OF oDlg FLAT ;
      ACTION ( oBrw:lGetBar := ! oBrw:lGetBar, oBrw:Refresh() )

   @ 60,140 BTNBMP PROMPT "Set Filter" ;
      SIZE 100,40 PIXEL OF oDlg FLAT ;
      ACTION xSetFilter( oBrw )

   @ 60,250 BTNBMP PROMPT "Clear Filter" ;
      SIZE 100,40 PIXEL OF oDlg FLAT ;
      ACTION ( oBrw:Seek( "" ), oBrw:SetFocus() )

   ACTIVATE DIALOG oDlg CENTERED
   RELEASE FONT oFont, oBold
return nil
*********************************************************************************************
static function xSetFilter( oBrw )
*********************************************************************************************
   local n, oCol, uVal, cType, cName:=""
   for n := 1 to Len( oBrw:aCols )
      oCol := oBrw:aCols[ n ]
      if !Empty( uVal := oCol:uBarGetVal ) // Procura as colunas onde houve digitação no filtro
         cType := oCol:cDataType
         cName := oCol:cHeader
         do case                           // Monta o filtro de acordo com o tipo da coluna
         case cType == 'C'
            uVal    := Upper( AllTrim( uVal ) )
         case cType == 'D'
            uVal    := DTOC( uVal )
         case cType == 'N'
            uVal    := Alltrim(Str( uVal ,18,2))
         endcase
         oBrw:cFilterFld := cName          // seleciona a coluna que será ativado o filtro
         oBrw:lSeekWild  := .T.
         oBrw:ArrayIncrFilter( uVal )
      endif
   next
   oBrw:Refresh()
   oBrw:Update()
   oBrw:SetFocus()
Return nil
*********************************************************************************************
 

Re: ArrayIncrFilter

Posted: Thu May 31, 2018 1:43 am
by nageswaragunupudi

Code: Select all

#include "fivewin.ch"

function Main()

   local oDlg, oBrw, oFont
   local aData

   USE CUSTOMER
   aData := FW_DbfToArray( "FIRST,LAST,CITY" )
   CLOSE CUSTOMER

   DEFINE FONT oFont NAME "TAHOMA" SIZE 0,-14
   DEFINE DIALOG oDlg SIZE 700,500 PIXEL TRUEPIXEL FONT oFont

   @ 60,20 XBROWSE oBrw SIZE -20,-20 PIXEL OF oDlg ;
      DATASOURCE aData AUTOCOLS HEADERS "First", "Last", "City" ;
      CELL LINES NOBORDER AUTOSORT FOOTERS

   WITH OBJECT oBrw
      :aCols[ 1 ]:bFooter  := { || "Records : " + Str( oBrw:nLen ) }
      //
      :uBarGetVals   := Space( 10 )
      :bClrEdits     := { || { CLR_BLACK, CLR_YELLOW } }
      :lBarGetOnKeys := .t.
      :lGetBar       := .t.
      //
      :CreateFromCode()
   END

   @ 10, 20 BTNBMP PROMPT "Set Filter" SIZE 200,40 PIXEL OF oDlg FLAT ;
      ACTION ( xSetFilter( oBrw ), oBrw:SetFocus() )

   @ 10,240 BTNBMP PROMPT "Clear Filter" SIZE 200,40 PIXEL OF oDlg FLAT ;
      ACTION ( xClearFilter( oBrw ), oBrw:SetFocus() )

   ACTIVATE DIALOG oDlg CENTERED
   RELEASE FONT oFont

return nil

function xSetFilter( oBrw )

   local cFilter  := ""
   local oCol, c

   for each oCol in oBrw:aCols
      if !Empty( oCol:uBarGetVal )
         c  := Upper( AllTrim( oCol:uBarGetVal ) )
//         c  := "'" + c + "' $ Upper( aRow[" + LTrim( Str( oCol:nArrayCol ) ) + "] )"
         c  := "'" + c + "' $ Upper( cValToChar( aRow[" + LTrim( Str( oCol:nArrayCol ) ) + "] ) )"  // can be char,date,num
         if !Empty( cFilter )
            cFilter  += " .AND. "
         endif
         cFilter  += c
      endif
   next

   if Empty( cFilter )
      xClearFilter( oBrw )
   else
      cFilter  := "{ |c,aRow,oBrw| " + cFilter + " }"
      oBrw:bFilterExp  := &( cFilter )
      oBrw:ArrayIncrFilter( "dummy" )
      oBrw:Refresh()
      oBrw:SetFocus()
   endif

return .t.

function xClearFilter( oBrw )

   AEval( oBrw:aCols, { |o| If( o:oBarGet == nil, nil, o:oBarGet:cText := uValBlank( o:uBarGetVal ) ) } )
   if oBrw:nLen < Len( oBrw:aArrayData )
      oBrw:bKeyCount    := { || Len( oBrw:aArrayData ) }
      oBrw:Refresh()
   endif
   oBrw:SetFocus()

return .t.
 

Re: ArrayIncrFilter

Posted: Thu May 31, 2018 12:21 pm
by ORibeiro
Thanks a lot Rao.

It´s completely fine with numeric and date field too.

Code: Select all


*********************************************************************************************
static function xSetFilter( oBrw )
*********************************************************************************************
   local oCol, uVal, cFilter:=""
   for each oCol in oBrw:aCols
      if !Empty( uVal := oCol:uBarGetVal )
         do case
         case oCol:cDataType == 'C'
            uVal    := Upper( AllTrim( uVal ) )
            cFilter := cFilter + iif(!Empty(cFilter), ".AND.","") + '"' + uVal + '" $ Upper( aRow[' + AllTrim(Str( oCol:nArrayCol )) + "] )"
         case oCol:cDataType == 'D'
            uVal    := DTOC( uVal )
            cFilter := cFilter + iif(!Empty(cFilter), ".AND.","") + '"' + uVal + '" = DTOC( aRow[' + AllTrim(Str( oCol:nArrayCol )) + "] )"
         case oCol:cDataType == 'N'
            uVal    := Alltrim(Str( uVal ,18,2))
            cFilter := cFilter + iif(!Empty(cFilter), ".AND.","") + '"' + uVal + '" = Alltrim(Str( aRow[' + Alltrim(Str( oCol:nArrayCol )) +'] ,18,2))'
         endcase
      endif
   next
   if Empty( cFilter )
      xClearFilter( oBrw )
   else
      cFilter  := "{ |c,aRow,oBrw| " + cFilter + " }"
      oBrw:bFilterExp  := &( cFilter )
      oBrw:ArrayIncrFilter( "dummy" )
      oBrw:Refresh()
   endif
   oBrw:SetFocus()
Return nil


 

Re: ArrayIncrFilter

Posted: Thu May 31, 2018 1:15 pm
by nageswaragunupudi
All this long code is not necessary.
I made a small modification to my earlier sample.
That is enough to handle all types

Re: ArrayIncrFilter

Posted: Thu May 31, 2018 5:44 pm
by ORibeiro
Yes Rao, your code looks great. Thank you.

I noticed that with a large array, the get fields become messy when the User scrolls quickly. So, Is it possible to refresh the get line when you place the cursor or click on some get field?

Thanks.