Page 1 of 2
Grid & SET FILTER
Posted: Tue Nov 16, 2021 11:19 am
by Georg_BA
Hello everyone
I would need to consult the GRID function over databases when I use SET FILTER

- Grid_3.jpg (84.66 KiB) Viewed 2881 times
in the first picture is the whole database

- Grid_3.jpg (84.66 KiB) Viewed 2881 times
the second image is the result after I used the filter "TYPE" # "X"
line 3 "Doklad" ..... 505
as well as "Doklad" ..... 452
is a duplicate and one blank line is displayed
the number of GRID report lines displayed is the same
the third picture shows the state after using SET FILTER "TYPE" = "P"
is "Doklad" .... 903 is displayed 4x and the other lines are empty

- Grid_3.jpg (84.66 KiB) Viewed 2881 times
source code
select 13
DBSETFILTER({ || left(druh,1) $ patri_win2 })
dbgotop()
mrn := recno()
win_2.Grid_2.recno := mrn
Win_2.Grid_2.ClearBuffer
//win_2.Grid_2.value:=recno()
Win_2.grid_2.refresh(.t.)
Win_2.grid_2.SetFocus
Thanks for help
Re: Grid & SET FILTER
Posted: Wed Nov 17, 2021 10:41 am
by Georg_BA
friends no one really uses "grid" and "set filter"
Re: Grid & SET FILTER
Posted: Wed Nov 17, 2021 12:29 pm
by serge_girard
Did you try with old syntax:
SET FILTER TO <field> == cValue
GO TOP
Serge
Re: Grid & SET FILTER
Posted: Wed Nov 17, 2021 12:41 pm
by edk
serge_girard wrote: ↑Wed Nov 17, 2021 12:29 pm
Did you try with old syntax:
SET FILTER TO <field> == cValue
GO TOP
Serge
Serge, this is a good tip.
@Georg_BA
https://www.hmgforum.com/viewtopic.php?p=67611#p67611
IMHO Grid uses DbFilter () internally for rendering. Therefore, if you are using dbSetFilter () you should either define both params: <bCondition> and <cCondition>, or use the SET FILTER TO [<lCondition>] command.
Below is a sample that shows the behavior of the Grid depending on the method you define the filtering conditions:
Code: Select all
#include "hmg.ch"
Function Main
Local aValue := { 0 , 0 }, i
DBCREATE('test.dbf', { {'ID','N',10,0} , {'NAME','C',30,0}, {'FLAG','C',3,0} } )
USE TEST
FOR i := 1 TO 20
APPEND BLANK
REPLACE id WITH i
REPLACE name WITH "Name #" + AllTrim(Str(i))
REPLACE flag WITH IF (i % 3 = 0, "C", IF ( i % 2 = 0, "B", "A" ) )
NEXT i
GO TOP
* Grid Column Controls Definitions
aCtrl_1 := {'TEXTBOX','NUMERIC','9999999999'}
aCtrl_2 := {'TEXTBOX','CHARACTER'}
aCtrl_3 := {'TEXTBOX','CHARACTER'}
DEFINE WINDOW Form_1 ;
AT 0,0 ;
WIDTH 800 ;
HEIGHT 510 ;
TITLE 'SET FILTER Test' ;
MAIN
DEFINE MAIN MENU
POPUP 'File'
ITEM 'dbSetFilter ( { || Left(flag , 1) $ "A" }, "Left(flag , 1) $ "A" )' ACTION SetFilter("A")
ITEM 'dbSetFilter ( { || Left(flag , 1) $ "B" }, "Left(flag , 1) $ "B" )' ACTION SetFilter("B")
ITEM 'dbSetFilter ( { || Left(flag , 1) $ "C" }, "Left(flag , 1) $ "C" )' ACTION SetFilter("C")
ITEM 'dbSetFilter ()' ACTION SetFilter()
SEPARATOR
ITEM 'dbSetFilter ( { || Left(flag , 1) $ "A" }' ACTION SetFilter2("A")
ITEM 'dbSetFilter ( { || Left(flag , 1) $ "B" }' ACTION SetFilter2("B")
ITEM 'dbSetFilter ( { || Left(flag , 1) $ "C" }' ACTION SetFilter2("C")
ITEM 'dbSetFilter ()' ACTION SetFilter2()
SEPARATOR
ITEM 'Set Filter TO FLAG = "A"' ACTION SetFilter3("A")
ITEM 'Set Filter TO FLAG = "B"' ACTION SetFilter3("B")
ITEM 'Set Filter TO FLAG = "C"' ACTION SetFilter3("C")
ITEM 'Set Filter TO ' ACTION SetFilter3()
END POPUP
END MENU
@ 10,10 GRID Grid_1 ;
WIDTH 770 ;
HEIGHT 440 ;
HEADERS {'Id','Name','Flag'} ;
WIDTHS {50,140,50};
VALUE { 1 , 1 } ;
ROWSOURCE "Test" ;
COLUMNFIELDS { 'Id' , 'Name' , 'Flag' } ;
COLUMNCONTROLS { aCtrl_1 , aCtrl_2 , aCtrl_3 } ;
EDIT ;
ALLOWAPPEND ;
ALLOWDELETE
END WINDOW
CENTER WINDOW Form_1
ACTIVATE WINDOW Form_1
Return
***************************************
Function SetFilter( cFlag )
IF !Empty( cFlag )
dbSetFilter ( { || Left(flag , 1) $ cFlag }, "Left(flag , 1) $ '" + cFlag + "'")
ELSE
dbSetFilter ()
ENDIF
dbGoTop()
Form_1.Grid_1.RecNo := RecNo()
Form_1.Grid_1.Refresh
RETURN
***************************************
Function SetFilter2( cFlag )
IF !Empty( cFlag )
dbSetFilter ( { || Left(flag , 1) $ cFlag } )
ELSE
dbSetFilter ()
ENDIF
dbGoTop()
Form_1.Grid_1.RecNo := RecNo()
Form_1.Grid_1.Refresh
RETURN
***************************************
Function SetFilter3( cFlag )
IF !Empty( cFlag )
Set Filter TO Left(flag , 1) $ cFlag
ELSE
Set Filter TO
ENDIF
GO TOP
Form_1.Grid_1.RecNo := RecNo()
Form_1.Grid_1.Refresh
RETURN
PS.
My good advice. Test filtering in the Grid on a large number of records and in a network environment if the application will run on them. You may find that you will be disappointed with the speed of this solution.
Re: Grid & SET FILTER
Posted: Wed Nov 17, 2021 12:56 pm
by serge_girard
For this purposes I DO miss the dBASE dot command !
Re: Grid & SET FILTER
Posted: Wed Nov 17, 2021 3:03 pm
by serge_girard
Georg_BA
Also be sure what you want/ask:
Code: Select all
SET FILTER TO ALLTRIM(some_field) = '0'
SET FILTER TO ALLTRIM(some_field) == '0'
SET FILTER TO some_field = '0'
SET FILTER TO some_field == '0'
This can give confusing results when field_len > 1 !
I always use TRIMMED values..
Serge
Re: Grid & SET FILTER
Posted: Wed Nov 17, 2021 4:33 pm
by Georg_BA
Txh serge_girard and edk
it never occurred to me that this could be in the command syntax used
i used "set filter to" and everything works as it should
thanks again
Re: Grid & SET FILTER
Posted: Thu Nov 18, 2021 11:07 am
by dragancesu
The problem is solved, but here are some of my ideas
When there is little data according to me it is better to use BROVSE, if I use GRID then I rewrite the data from dbf to grid and if necessary I use some condition or filter
The grid "knows" how much data it had to display and if it needs less then it needs to be deleted before the new display otherwise "ghosts" remain
MD_Form_1.MD_Grid_1.DeleteAllItems ()
Code: Select all
aGrid := {}
SELECT table2
// set filter to ... <- one way
dbgotop()
DO WHILE .NOT. EOF()
IF _key1 != some_filter // second way
DBSKIP()
LOOP
ENDIF
Aadd(aGrid, {str(recno()),str(field_1),dtoc(field_2), ...,str(field_n)})
DBSKIP()
ENDDO
MD_Form_1.MD_Grid_1.DeleteAllItems()
FOR i = 1 to LEN(aGrid)
MD_Form_1.MD_Grid_1.AddItem(aGrid[i])
NEXT
SELECT table1
just one way to solve your problem
Re: Grid & SET FILTER
Posted: Fri Nov 19, 2021 5:34 pm
by franco
My thoughts.
I use browse for viewing or looking for table contents and grid for working with data.
I try not to use set filter on files larger then ? 50 items. Can be to slow in network as Edk suggested.
I use local temporary indexes instead.
At start of MAIN program I create a local temporary folder so table lookups (which is in server.) are local lookups and much faster.
Code: Select all
CREATEFOLDER("C:\Hmtemp") \\ if it exists it continues.
Then in your Grid program
Code: Select all
local hm:= " ", prname := 'your Grid program name'
select table ?
if reccount() > 50
index on fieldname to c:\hmtemp\prname.ntx for $ patri_win2
else
set filter
endif
go top
----- your code ----
----- end of program ----
hm := "c:\hmtemp\prname.ntx"
erase(hm)
return
Re: Grid & SET FILTER
Posted: Fri Nov 19, 2021 6:53 pm
by Georg_BA
thank you for the contribution, I basically also avoid GRID
I only see a lot of problems here, I don't know why we deviated from BROWSE
I see the biggest problem is that TBROSE in HMG has stopped being supported
Georg