Here my Tfilter class easy to understand.
I used customers.dbf on all samples.
your comments are wellcome.
I have to thank my friend Mr Rao Nages for his example xbrarray.prg from which I started creating this class
Filter.ch
you can personalize it with your string language
- Code: Select all Expand view
- #DEFINE ERRORE "ERROR FILTER"
#DEFINE ERRORE1 "Error on data inserted ."
#DEFINE ERRORE2 "I cannot continue you must define thename of the filter"
#DEFINE ERRORE3 "I cannot continue you must define an dbf archive"
#DEFINE DIALOG_FILTERS "Filter creation"
#DEFINE FILTER_NAME "Filter name :"
#DEFINE FILTER_MSG "Filter :"
#DEFINE TXT_OPERATOR "Operator"
#DEFINE TXT_FIELD "Field"
#DEFINE TXT_CONDITION "Condition"
#DEFINE TXT_EXPRESSION "Expression"
#DEFINE TXT_UPPER "Upper/Lowcase"
#DEFINE TXT_BUTTON_ADD "Add"
#DEFINE TXT_BUTTON_INSERT "Insert"
#DEFINE TXT_BUTTON_DELETE "Delete "
#DEFINE TXT_BUTTON_ACTIVATE "&Activate"
#DEFINE TXT_BUTTON_EXIT "&Exit"
#DEFINE TXT_MANAGER_TITLE "Filter Manager"
#DEFINE TXT_MANAGER_TABLE_TITLE "Filters"
#DEFINE FILTER_SECTION_INI "Filters"
#DEFINE FILTER_ARRAY_MENU "New/Modify"
#DEFINE OpRelacion1 " "
#DEFINE OpRelacion2 "<> desigual "
#DEFINE OpRelacion3 "!= desigual "
#DEFINE OpRelacion4 "# desigual "
#DEFINE OpRelacion5 "$ contiene "
#DEFINE OpRelacion6 "< menor que "
#DEFINE OpRelacion7 "<= menor o igual que"
#DEFINE OpRelacion8 "> mayor que "
#DEFINE OpRelacion9 ">= mayor o igual que"
#DEFINE OpRelacion10 "= igual "
#DEFINE OpRelacion11 "== exactamente igual"
#DEFINE Operators1 " "
#DEFINE Operators2 "And"
#DEFINE Operators3 "Or"
#DEFINE Operators4 "Not"
the File Manager to use with tfilter class
FManager.prg
- Code: Select all Expand view
#include "FiveWin.ch"
#include "xBrowse.ch"
#include "constant.ch"
#include "Filter.ch"
#DEFINE LIGHTCYAN nRGB( 203, 225, 252 )
* +- Program ----------------------------------------------------------------+
* ¦ Application: Filter Manager ¦
* ¦ Description: -usable with Tfilter ¦
* ¦ Author: Falconi Silvio ¦
* ¦ Date created 09.12.2013 Date updated: 00.00.0000 ¦
* ¦ Time created: Time updated: ¦
* ¦ Make File: ¦
* ¦ Exec File: Docs By: ¦
* ¦ Copyright: (c) 2013 ¦
* ¦ FILE: crea automaticamente un file INI ¦
* +--------------------------------------------------------------------------+
Function Filter_Manager(cDbf,oGrid,cPref)
Local nBottom:=12
Local nRight:=55
Local nWidth := Max( nRight * DLG_CHARPIX_W, 180 )
Local nHeight := nBottom * DLG_CHARPIX_H
Local oBtnPrev,oBtnGo,oBtnExit,oBtnHelp
Local nitem1,oBtn[6]
Local aFilters:= {}
cIniFilter := cFilePath( GetModuleFileName( GetInstance() ) ) + cPref +".ini"
aFilters := GETPVPROFSECTIONS( cIniFilter )
nFilters:= Len( aFilters )
DEFINE DIALOG oDlgFilterList ;
SIZE nWidth, nHeight;
TITLE TXT_MANAGER_TITLE PIXEL;
STYLE nOr( DS_MODALFRAME, WS_POPUP, WS_CAPTION, 4 )
@ 1, 1 XBROWSE oLbx OF oDlgFilterList ;
SIZE nWidth/2, (nHeight/4)+32 PIXEL ;
ARRAY aFilters AUTOCOLS NOBORDER
WITH OBJECT oLbx
:lRecordSelector := .f.
:nMarqueeStyle := MARQSTYLE_HIGHLWIN7
:lHScroll := .f.
:nStretchCol:= -1
:aCols[1]:cHeader := TXT_MANAGER_TABLE_TITLE
:CreateFromCode()
END
@ oLbx:nbottom+2,2 BUTTON oBtn[1] PROMPT "&Load" SIZE 30, 10 ;
PIXEL OF oDlgFilterList ACTION ( oDlgFilterList:End(),Load_Filter(cDbf,oGrid,oLbx) ) WHEN nFilters>0
@ oLbx:nbottom+2,36 BUTTON oBtn[2] PROMPT "&Clear" SIZE 30, 10 ;
PIXEL OF oDlgFilterList ACTION (oDlgFilterList:end(), (cDbf)->(DbClearFilter()),(cDbf)->(DbGoTop()),oGrid:refresh() )
@ oLbx:nbottom+2,71 BUTTON oBtn[3] PROMPT "&New" SIZE 30, 10 ;
PIXEL OF oDlgFilterList ACTION Create_Filter(cDbf,oGrid,oLbx)
@ oLbx:nbottom+2,176 BUTTON oBtn[6] PROMPT "&Exit" SIZE 30, 10 ;
PIXEL OF oDlgFilterList ACTION oDlgFilterList:End()
ACTIVATE DIALOG oDlgFilterList centered
Return nil
//---------------------------------------------------------------------//
Function Load_Filter(cDbf,oGrid,oLbx)
Local nLen := Len( oGrid:aCols )
Local aCampos [ nLen ]
Local aTitulos[ nLen ]
Local aTipos [ nLen ]
Local lNew:=.f.
Local n
Local cFilter:= ""
FOR n = 1 TO nLen
aCampos [ n ]:= oGrid:aCols[ n ]:cExpr
aTitulos [ n ]:= oGrid:aCols[ n ]:cHeader
aTipos [ n ]:= oGrid:aCols[ n ]:cDataType
NEXT
IF !EMPTY(oLbx)
cSection := oLbx:aArrayData[oLbx:nArrayAt]
ENDIF
// call the filter class
oFilter:= TFilter():New(aCampos,aTitulos,aTipos, cDbf,oGrid,lNew,cSection)
oFilter:Dialog()
oFilter:Activate()
cFilter := oFilter:SetFilter()
IF ! Empty( cFilter)
SET FILTER TO &cFilter
(cDbf)->( dbGoTop() )
oGrid:refresh()
Endif
RETURN NIL
//---------------------------------------------------------------------//
Function Create_Filter(cDbf,oGrid,oLbx)
Local nLen := Len( oGrid:aCols )
Local aCampos [ nLen ]
Local aTitulos[ nLen ]
Local aTipos [ nLen ]
Local lNew:=.t.
Local n
Local cFilter:= ""
FOR n = 1 TO nLen
aCampos [ n ]:= oGrid:aCols[ n ]:cExpr
aTitulos [ n ]:= oGrid:aCols[ n ]:cHeader
aTipos [ n ]:= oGrid:aCols[ n ]:cDataType
NEXT
cSection := ""
// call the filter class
oFilter:= TFilter():New(aCampos,aTitulos,aTipos, cDbf,oGrid,lNew,cSection)
oFilter:Dialog()
oFilter:Activate()
cFilter := oFilter:SetFilter()
IF ! Empty( cFilter)
SET FILTER TO &cFilter
(cDbf)->( dbGoTop() )
oGrid:refresh()
Endif
RETURN NIL
//-------------------------------------------------------------------------------------------//
Function Go_Filter(cDbf,oGrid,cFilter)
Local nLen := Len( oGrid:aCols )
Local aCampos [ nLen ]
Local aTitulos[ nLen ]
Local aTipos [ nLen ]
Local lNew
FOR n = 1 TO nLen
aCampos [ n ]:= oGrid:aCols[ n ]:cExpr
aTitulos [ n ]:= oGrid:aCols[ n ]:cHeader
aTipos [ n ]:= oGrid:aCols[ n ]:cDataType
NEXT
IF alltrim(cFilter)== FILTER_ARRAY_MENU
lNew:=.t.
cSection:=""
else
cSection := cFilter
lNew:=.F.
Endif
// call the filter class
oFilter:= TFilter():New(aCampos,aTitulos,aTipos, cDbf,oGrid,lNew,cSection)
oFilter:Dialog()
oFilter:Activate()
cFilter := oFilter:SetFilter()
IF ! Empty( cFilter)
SET FILTER TO &cFilter
(cDbf)->( dbGoTop() )
oGrid:refresh()
Endif
RETURN
STATIC FUNCTION GETPVPROFSECTIONS( cIni )
LOCAL cBuf := SPACE( 65536 )
LOCAL aSec := {}
GETPRIVATEPROFILESECTIONNAMES( cBuf, 65536, cIni )
WHILE LEFT( cBuf, 1 ) != CHR( 0 )
AADD( aSec, LEFT( cBuf, AT( CHR( 0 ), cBuf ) - 1 ) )
cBuf = SUBSTR( cBuf, AT( CHR( 0 ), cBuf ) + 1 )
ENDDO
RETURN aSec
DLL STATIC FUNCTION GETPRIVATEPROFILESECTIONNAMES( cRetBuf AS LPSTR, nSize AS LONG, cFileName AS LPSTR ) AS DWORD;
PASCAL FROM "GetPrivateProfileSectionNamesA" LIB "kernel32.dll"
Test1.prg
a sample with a button to call file manager and set a filter
- Code: Select all Expand view
#include "FiveWin.ch"
#include "xBrowse.ch"
#include "constant.ch"
#include "Filter.ch"
#DEFINE LIGHTCYAN nRGB( 203, 225, 252 )
Function Test()
local oDlg, oBrw, oFont
Local oBtnFiltro[2]
SET DATE ITALIAN
SET CENTURY ON
FwNumFormat( 'E', .t. )
USE CUSTOMER ALIAS CUST
DEFINE FONT oFont NAME 'Tahoma' SIZE 0, -14
DEFINE DIALOG oDlg SIZE 640,440 PIXEL ;
FONT oFont TITLE 'XBrowse Windows 7 Bars' ;
COLOR CLR_BLACK,RGB(250,250,250)
@ 10,20 XBROWSE oBrw OF oDlg SIZE -10,-20 PIXEL ;
COLUMNS "First", "State", "Age", "HireDate", "Salary" ;
ALIAS 'CUST' NOBORDER
oBrw:lRecordSelector := .f.
oBrw:nMarqueeStyle := MARQSTYLE_HIGHLWIN7
WITH OBJECT oBrw:InsCol( 1 )
:cHeader := " "
:bEditValue := { || If( AScan( oBrw:aSelected, oBrw:BookMark ) > 0, .t., nil ) }
:SetCheck()
:nHeadBmpNo := { || If( Len( oBrw:aSelected ) == oBrw:nLen, 1, 2 ) }
:bLClickHeader := { |r,c,f,oCol| If( Len( oBrw:aSelected ) == oBrw:nLen, ;
oBrw:SelectNone(), oBrw:SelectAll() ) }
END
oBrw:CreateFromCode()
@ 204,2 BUTTON oBtnFiltro[1] Prompt "Filter Manager" SIZE 60,10 PIXEL;
ACTION Filter_Manager('CUST',oBrw,'CUST')
@ 204,102 BUTTON oBtnFiltro[2] Prompt "Cancellare filtro" SIZE 60,10 PIXEL;
ACTION ( CUST->(DbClearFilter()),CUST->(DbGoTop()),oBrw:refresh() )
ACTIVATE DIALOG oDlg CENTERED
RELEASE FONT oFont
Return nil
Test2.prg
a sample to show a combobox with filters and set the filter ( it is incluede a button forr call the filemanager)
- Code: Select all Expand view
#include 'fivewin.ch'
#include 'xbrowse.ch'
#include 'Filter.ch'
* +- Program ----------------------------------------------------------------+
* ¦ Application: Tfilter ¦
* ¦ Description: Dialog per creare o caricare un filtro ¦
* ¦ Author: Falconi Silvio ¦
* ¦ Date created 09.12.2013 Date updated: 00.00.0000 ¦
* ¦ Time created: Time updated: ¦
* ¦ Make File: ¦
* ¦ Exec File: Docs By: ¦
* ¦ Copyright: (c) 2013 ¦
* ¦ FILE: crea automaticamente un file INI ¦
* +--------------------------------------------------------------------------+
function Main()
local oDlg, oBrw, oFont
Local oBtnFiltro[3],cFilter:=""
//-------------//
Local cIniFilter:=triM(cFilePath( GetModuleFileName( GetInstance() ) ) + "Cust" +".ini")
Local aFilters := GETPVPROFSECTIONS( cIniFilter )
//---------------//
/* If !Empty( cIniFilter)
hIniFile := HB_ReadIni( cIniFilter )
aFilters:=HGetKeys( hIniFile )
endif
* */
aadd(aFilters, FILTER_ARRAY_MENU)
SET DATE ITALIAN
SET CENTURY ON
FwNumFormat( 'E', .t. )
USE CUSTOMER ALIAS CUST
DEFINE FONT oFont NAME 'Tahoma' SIZE 0, -14
DEFINE DIALOG oDlg SIZE 640,440 PIXEL ;
FONT oFont TITLE 'Filter test' ;
COLOR CLR_BLACK,RGB(250,250,250)
@ 10,20 XBROWSE oBrw OF oDlg SIZE -10,-20 PIXEL ;
COLUMNS "First", "State", "Age", "HireDate", "Salary" ;
ALIAS 'CUST' NOBORDER
oBrw:lRecordSelector := .f.
oBrw:nMarqueeStyle := MARQSTYLE_HIGHLWIN7
WITH OBJECT oBrw:InsCol( 1 )
:cHeader := " "
:bEditValue := { || If( AScan( oBrw:aSelected, oBrw:BookMark ) > 0, .t., nil ) }
:SetCheck()
:nHeadBmpNo := { || If( Len( oBrw:aSelected ) == oBrw:nLen, 1, 2 ) }
:bLClickHeader := { |r,c,f,oCol| If( Len( oBrw:aSelected ) == oBrw:nLen, ;
oBrw:SelectNone(), oBrw:SelectAll() ) }
END
oBrw:CreateFromCode()
@ 204,22 COMBOBOX oBtnFiltro[1] VAR cFilter ITEMS aFilters SIZE 140,90 PIXEL OF oDlg ;
ON CHANGE (Go_Filter('CUST',oBrw,cFilter))
@ 204,172 BTNBMP oBtnFiltro[2] FILENAME "SH_FILTER.bmp" SIZE 10,10 PIXEL OF oDlg NOBORDER ;
ACTION ( CUST->(DbClearFilter()),CUST->(DbGoTop()),oBrw:refresh() ) ;
TOOLTIP "Erase filter active" // WHEN !empty(cFilter)
@ 204,242 BUTTON oBtnFiltro[3] PROMPT "MANAGER" SIZE 40,10 PIXEL OF oDlg ;
ACTION (Filter_Manager('CUST',oBrw,"Cust"),;
aFilters := GETPVPROFSECTIONS( cIniFilter ),;
oBtnFiltro[1]:REFRESH())
ACTIVATE DIALOG oDlg CENTERED
RELEASE FONT oFont
return nil
STATIC FUNCTION GETPVPROFSECTIONS( cIni )
LOCAL cBuf := SPACE( 65536 )
LOCAL aSec := {}
GETPRIVATEPROFILESECTIONNAMES( cBuf, 65536, cIni )
WHILE LEFT( cBuf, 1 ) != CHR( 0 )
AADD( aSec, LEFT( cBuf, AT( CHR( 0 ), cBuf ) - 1 ) )
cBuf = SUBSTR( cBuf, AT( CHR( 0 ), cBuf ) + 1 )
ENDDO
RETURN aSec
DLL STATIC FUNCTION GETPRIVATEPROFILESECTIONNAMES( cRetBuf AS LPSTR, nSize AS LONG, cFileName AS LPSTR ) AS DWORD;
PASCAL FROM "GetPrivateProfileSectionNamesA" LIB "kernel32.dll"
Tfilter.prg
- Code: Select all Expand view
- #include "FiveWin.ch"
#include "xBrowse.ch"
#include "constant.ch"
#include "Filter.ch"
#DEFINE LIGHTCYAN nRGB( 203, 225, 252 )
* +- Program ----------------------------------------------------------------+
* ¦ Application: Tfilter ¦
* ¦ Description: Dialog per crare o caricare un filtro ¦
* ¦ Author: Falconi Silvio ¦
* ¦ Date created 09.12.2013 Date updated: 00.00.0000 ¦
* ¦ Time created: Time updated: ¦
* ¦ Make File: ¦
* ¦ Exec File: Docs By: ¦
* ¦ Copyright: (c) 2013 ¦
* ¦ FILE: crea automaticamente un file INI ¦
* +--------------------------------------------------------------------------+
CLASS TFilter
DATA aCampos,aTitulos,aTipos AS ARRAY
DATA oDlgFilter,cDlgTitle
DATA oBrwFilter
DATA oDlgFilterList
DATA cIniFilter
DATA lNew
DATA cFilter
DATA cDbf
DATA oBrwDbf
DATA cNameFilter
DATA cField
DATA cCondition
DATA oCursorBtn
DATA oFontDialog
DATA lFilter
DATA cFiltro
DATA cOperator
DATA cEspressione
DATA cCampo1
DATA cRelacion1
DATA cValor1
DATA nLogico
DATA acOpRelacion
DATA acOperators
DATA cAlias
DATA lUpper
DATA lFirstrow
DATA nRigheSection, cSection
DATA aGet AS ARRAY
DATA oBtn
DATA aRighefiltro AS ARRAY
DATA aStringFilter, aRowData
DATA aArrayFilter
METHOD New(aCampos,aTitulos,aTipos, cDbf,oBrwDbf,lNew,cNameFilter) CONSTRUCTOR
METHOD Dialog()
METHOD Activate()
*METHOD End()
METHOD AddFiltro()
METHOD BlankRow()
METHOD InsertRow()
METHOD DeleteRow()
METHOD AddRow()
METHOD SetFilter()
ENDCLASS
//-------------------------------------------------------------------------------------------//
METHOD New(aCampos,aTitulos,aTipos, cDbf,oBrwDbf,lNew,cNameFilter) CLASS TFilter
Local n,k
DEFAULT cNameFilter := space(40)
::aCampos := aCampos
::aTitulos := aTitulos
::aTipos := aTipos
::cDbf := cDbf
::oBrwDbf := oBrwDbf
::lNew := lNew
::cNameFilter := cNameFilter
::cIniFilter := cFilePath( GetModuleFileName( GetInstance() ) ) + ::cDbf +".ini"
::cSection := cNameFilter
::nRigheSection := 0
::aArrayFilter := {}
::aRighefiltro := {}
::oCursorBtn := TCursor():New(,'HAND')
*::i := 0
::lFilter := .F.
::cFiltro := ""
::aget:=array(6)
::oBtn:=array(10)
::cOperator := Space( 10 )
::cEspressione := Space( 10 )
::cCampo1 := Space( 20 )
::cRelacion1 := Space( 20 )
::cValor1 := Space( 20 )
::nLogico := 1
::acOpRelacion := {OpRelacion1 ,;
OpRelacion2 ,;
OpRelacion3 ,;
OpRelacion4 ,;
OpRelacion5 ,;
OpRelacion6 ,;
OpRelacion7 ,;
OpRelacion8 ,;
OpRelacion9 ,;
OpRelacion10 ,;
OpRelacion11 }
::acOperators := {Operators1,Operators2,Operators3,Operators4 }
::cAlias := Alias()
DEFINE FONT ::oFontDialog NAME 'Tahoma' SIZE 0, -14
IF Empty( ::cAlias )
MsgStop( OemToAnsi( ERRORE3 ) )
RETURN NIL
ENDIF
IF ::lNew
::lUpper := .F.
::cNameFilter := space(40)
::lFirstrow :=.t.
ELSE
::lFirstrow :=.F.
::nRigheSection := VAL(GetIni( ::cIniFilter, ::cSection, "Totalerighe", ))
::lUpper := IIF(GetIni( ::cIniFilter, ::cSection, "UpperCase", )=="S",.t.,.f.)
// scompongo le righe del file INI
FOR n=1 to ::nRigheSection
AaDd(::aRighefiltro,GetIni( ::cIniFilter, ::cSection, "Riga"+ALLTRIM(str(n)), ))
NEXT
FOR k=1 to len(::aRighefiltro)
::aStringFilter := New_aToken( ::aRighefiltro[k], "|" )
::cOperator := ::aStringFilter[1]
::cField := ::aStringFilter[2]
::cCondition := ::aStringFilter[3]
::cEspressione := ::aStringFilter[4]
::aRowData:= { ::cOperator, ::cField, ::cCondition, ::cEspressione}
AaDd(::aArrayFilter,::aRowData)
NEXT k
::cOperator := ""
::cField := ""
::cCondition := ""
::cEspressione := ""
adel(::aStringFilter)
ENDIF
IF ::cNameFilter =FILTER_ARRAY_MENU
::cNameFilter := space(40)
ENDIF
* ::Dialog()
RETURN self
//-----------------------------------------------------------------------------------//
METHOD Dialog() CLASS TFilter
Local nBottom := 21
Local nRight := 70
Local nWidth := Max( nRight * DLG_CHARPIX_W, 180 )
Local nHeight := nBottom * DLG_CHARPIX_H
Local oBtnPrev,oBtnGo,oBtnExit,oBtnHelp
Local bClrGrad := { | lPressed | If( ! lPressed,;
{ { 1, nRGB( 253, 254, 255 ), nRGB( 179, 217, 255 ) } },;
{ { 1, nRGB( 179, 217, 255 ), nRGB( 253, 254, 255 ) } } ) }
Local oThis:=self
DEFINE DIALOG ::oDlgFilter ;
SIZE nWidth, nHeight PIXEL ;
TITLE ::cDlgTitle ;
GRADIENT { { 1,CLR_WHITE, LIGHTCYAN } } TRANSPARENT
::oDlgFilter:lHelpIcon := .F.
::oDlgFilter:nStyle := nOR( DS_MODALFRAME, WS_POPUP, WS_CAPTION, 4 )
::oDlgFilter:SetFont( ::oFontDialog )
@ 2,1 XBROWSE oThis:oBrwFilter OF oThis:oDlgFilter ;
COLUMNS 1, 2, 3, 4 ;
HEADERS TXT_OPERATOR,TXT_FIELD,TXT_CONDITION,TXT_EXPRESSION ;
COLSIZES 100, 100, 160, 150 ;
ARRAY oThis:aArrayFilter LINES FASTEDIT CELL SIZE 260,80 // NOBORDER
WITH OBJECT oThis:oBrwFilter
:nEditTypes := EDIT_GET
:bPastEof := { || oThis:AddRow() }
:bKeyDown := { |nKey| If( nKey == VK_DELETE, oThis:DeleteRow(), ;
If( nKey == VK_INSERT, oThis:InsertRow(), ;
nil ) ) }
:lRecordSelector := .f.
:lHScroll := .f.
:lVScroll := .f.
:nMarqueeStyle := MARQSTYLE_HIGHLWIN7
:nColDividerStyle := LINESTYLE_LIGHTGRAY
:lColDividerComplete := .t.
:CreateFromCode()
END
@ 120,8 COMBOBOX ::aGet[1] VAR ::cOperator ITEMS ::acOperators OF ::oDlgFilter SIZE 50,60 PIXEL STYLE CBS_DROPDOWN
@ 120,59 COMBOBOX ::aGet[2] VAR ::cField ITEMS ::aTitulos OF ::oDlgFilter SIZE 50,60 PIXEL STYLE CBS_DROPDOWN
@ 120,115 COMBOBOX ::aGet[3] VAR ::cCondition ITEMS ::acOpRelacion OF ::oDlgFilter SIZE 75,60 PIXEL STYLE CBS_DROPDOWN
@ 120,195 GET ::aGet[4] VAR ::cEspressione OF ::oDlgFilter SIZE 75,12 PIXEL
@ 10,10 SAY FILTER_NAME OF ::oDlgFilter SIZE 80,10 PIXEL
@ 10,55 GET ::aGet[5] VAR ::cNameFilter OF ::oDlgFilter SIZE 80,10 PIXEL
@ 10,150 CHECKBOX ::aGet[6] VAR ::lUpper Prompt TXT_UPPER OF ::oDlgFilter SIZE 80,10 PIXEL
@ 140, 10 BUTTON ::oBtn[1] PROMPT TXT_BUTTON_ADD SIZE 45, 12 PIXEL OF ::oDlgFilter;
ACTION ( oThis:AddRow( ::oBrwFilter,::aGet,::cField,::cCondition, ::cEspressione,;
::cOperator,::lFirstRow,::oDlgFilter ), ::oBrwFilter:SetFocus() )
@ 140, 60 BUTTON ::oBtn[2] PROMPT TXT_BUTTON_INSERT SIZE 45, 12 PIXEL OF ::oDlgFilter;
ACTION ( oThis:InsertRow(), ::oBrwFilter:SetFocus() )
@ 140,110 BUTTON ::oBtn[3] PROMPT TXT_BUTTON_DELETE SIZE 45, 12 PIXEL OF ::oDlgFilter;
ACTION ( oThis:DeleteRow(), ::oBrwFilter:SetFocus() )
@ 140, 165 BUTTON ::oBtn[4] PROMPT TXT_BUTTON_ACTIVATE SIZE 45, 12 PIXEL OF ::oDlgFilter ACTION ( ::oDlgFilter:end( IDOK ))
@ 140, 221 BUTTON ::oBtn[5] PROMPT TXT_BUTTON_EXIT SIZE 45, 12 PIXEL OF ::oDlgFilter ACTION ( ::oDlgFilter:end( IDCANCEL ) )
RETURN NIL
//-------------------------------------------------------------------------------------------//
METHOD Activate() CLASS TFilter
local o := self
ACTIVATE DIALOG o:oDlgFilter center;
ON INIT IIF(o:lNew,o:aGet[1]:hide(),)
RETURN ( ::oDlgFilter:nResult == IDOK )
//-------------------------------------------------------------------------------------------//
METHOD AddRow() CLASS TFilter
Local RowData:= { ::cOperator, ::cField, ::cCondition, ::cEspressione}
AAdd( ::oBrwFilter:aArrayData, RowData )
::oBrwFilter:Refresh()
::oBrwFilter:GoBottom()
::aGet[1]:show()
::aGet[1]:set(" ")
::aGet[2]:set(" ")
::aGet[3]:set(" ")
::aGet[4]:ctext:=" "
FOR n=1 TO 4
::aGet[n]:refresh()
NEXT
::oDlgFilter:refresh()
return nil
//-------------------------------------------------------------------------------------------//
METHOD InsertRow() CLASS TFilter
AIns( ::oBrwFilter:aArrayData, ::oBrwFilter:nArrayAt, ::BlankRow(), .t. )
::oBrwFilter:Refresh()
return nil
//-------------------------------------------------------------------------------------------//
METHOD BlankRow CLASS TFilter
return { " ", " ", " ", " "}
//-------------------------------------------------------------------------------------------//
METHOD DeleteRow() CLASS TFilter
if ! Empty( ::oBrwFilter:aArrayData )
ADel( ::oBrwFilter:aArrayData, ::oBrwFilter:nArrayAt, .t. )
::oBrwFilter:Refresh()
endif
return nil
//-----------------------------------------------------------------------//
METHOD AddFiltro(cNomeCampo, cOpRelazione, cValore ,lUppercase) CLASS TFilter
LOCAL i := 0
LOCAL cCampo := ""
Local cFilterString:=""
IF Empty( cNomeCampo ) .OR. Empty( cOpRelazione ) .OR. Empty( cValore )
MsgStop( ERRORE1, ERRORE )
ELSE
cOpRelazione := Left( cOpRelazione, 2 )
FOR i := 1 TO Len( ::aTitulos )
IF AllTrim( ::aTitulos[ i ] ) == AllTrim( cNomeCampo )
cCampo := ::aCampos[ i ]
IF AllTrim( ::aTipos[ i ] ) = "C"
If lUppercase
cCampo := "Upper( " + cCampo + " )"
cValore := "Upper( " + Chr(34) + AllTrim( cValore ) + Chr( 34 ) + " )"
else
cCampo := " " + cCampo + " "
cValore := " " + Chr(34) + AllTrim( cValore ) + Chr( 34 ) + " "
endif
ELSEIF AllTrim( ::aTipos[ i ] ) = "D"
cCampo := "DTOS( " + cCampo + " )"
cValore := "DTOS( " + AllTrim( cValore ) + " )"
ENDIF
EXIT
ENDIF
NEXT
cFilterString += AllTrim( cCampo ) + " " + AllTrim( cOpRelazione ) + " " + ;
AllTrim( cValore )
ENDIF
RETURN cFilterString
//-----------------------------------------------------------------------//
METHOD SetFilter() CLASS TFilter
Local cStringFilter :=""
IF ::oDlgFilter:nresult == IDOK
IF !Empty(::cNameFilter)
cSection:=ALLtrim(::cNameFilter)
SetIni( ::cIniFilter, cSection,"NomeFiltro", ::cNameFilter)
SetIni( ::cIniFilter, cSection,"Uppercase", IIF(::lUpper,"S","N"))
SetIni( ::cIniFilter, cSection,"TotaleRighe", ALLTRIM(str(Len( ::oBrwFilter:aArrayData))))
For n=1 to Len( ::oBrwFilter:aArrayData)
If n=1
::cFiltro += ::AddFiltro( ::oBrwFilter:aArrayData[n][2],;
::oBrwFilter:aArrayData[n][3],;
::oBrwFilter:aArrayData[n][4],::lUpper )
SetIni( ::cIniFilter, cSection, "Riga"+ALLTRIM(str(n)),;
ALLTRIM(::oBrwFilter:aArrayData[n][1]+"|"+;
::oBrwFilter:aArrayData[n][2]+"|"+;
::oBrwFilter:aArrayData[n][3]+"|"+;
::oBrwFilter:aArrayData[n][4]))
Elseif n>1
DO CASE
CASE ::oBrwFilter:aArrayData[n][1] = Operators2
::cFiltro += " .AND. "
CASE ::oBrwFilter:aArrayData[n][1] = Operators3
::cFiltro += " .OR. "
CASE ::oBrwFilter:aArrayData[n][1] = Operators4
::cFiltro += " .NOT. "
ENDCASE
::cFiltro += ::AddFiltro(::oBrwFilter:aArrayData[n][2],;
::oBrwFilter:aArrayData[n][3],;
::oBrwFilter:aArrayData[n][4],::lUpper )
SetIni( ::cIniFilter, cSection, "Riga"+ALLTRIM(str(n)),;
ALLTRIM(::oBrwFilter:aArrayData[n][1]+"|"+;
::oBrwFilter:aArrayData[n][2]+"|"+;
::oBrwFilter:aArrayData[n][3]+"|"+;
::oBrwFilter:aArrayData[n][4]))
endif
next
// attiva filtro
// Alert( FILTER_MSG + ::cfiltro )
return ::cFiltro
ELSE
msgstop(ERRORE2)
ENDIF
ENDIF
RETURN NIL
* +--------------------------------------------------------------------------+
* ¦ Functions ¦
* +--------------------------------------------------------------------------+
STATIC FUNCTION SetIni( cIni, cSection, cEntry, xVar )
LOCAL oIni
INI oIni FILE cIni
SET SECTION cSection ;
ENTRY cEntry ;
TO xVar ;
OF oIni
ENDINI
RETURN nil
STATIC FUNCTION GetIni( cIni, cSection, cEntry, xDefault )
LOCAL oIni
LOCAL xVar := xDefault
INI oIni FILE cIni
GET xVar ;
SECTION cSection ;
ENTRY cEntry ;
DEFAULT xDefault ;
OF oIni
ENDINI
RETURN xVar
STATIC FUNCTION New_aToken( cString, cSeparator )
LOCAL nPos
LOCAL aString := {}
DEFAULT cSeparator := "|"
cString := ALLTRIM( cString ) + cSeparator
DO WHILE .T.
nPos := AT( cSeparator, cString )
IF nPos = 0
EXIT
ENDIF
AADD( aString, SUBSTR( cString, 1, nPos-1 ) )
cString := SUBSTR( cString, nPos+1 )
ENDDO
RETURN ( aString )