Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Filters and Grids

Status
Not open for further replies.

stanlyn

Programmer
Sep 3, 2003
945
US
Hi,

What would allow records to show on a grid that a filter excludes. The grids record source type is alias. When applying a filter the grid is updated properly with the expected records. As soon as I scroll the grid, I begin seeing records that are outside the filter's scope.

Thanks,
Stanley

 
3 words
Code:
set filter to

Utmost blessings!

(EDIT: Profuse apologies! I oversimplified and did not fully read/comprehend. Please disregard the above.)
 
In afterrowcolchange event check set('filter'). If It is different from the one you have defined previously,then set filter to condition is resetting somewhere in the program.
 
mydocpro, you only read the first sentence and assumed that's what stanlyn wants. No it's what happens and is unwanted.

Stynlyn, there is nothing, that is showing what's not fulfilling the filter, unless as KALP1 says, the filter is reset. I rather assume you have a condition, which you THINK filters somethin, twhich it doesn't, for example, again, because of using = where you want exact match ==

Bye, Olaf.
 
Stanley, are you sure that the filter is being applied before you do the scrolling?

My point is that the act of setting the filter does not itself change anything in the visible portion of the grid - regardless of whether the visible records are part of the filter or not. You have to set focus to the grid, either programmatically or interactively, for the filter to become visible.

You would normally call the grid's SetFocus method immediately after the SET FILTER. But if you didn't do that, dragging the scroll bars would have the effect of setting focus.

The reason I mention this is that it could confirm what Olaf said, that the filter wasn't being set in the first place for some reason. Given the issue you asked about in thread184-1769720, it could be that you need to either use [tt]==[/tt] or ensure that EXACT is set on.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Hi Mike,

Mike said:
it could be that you need to either use == or ensure that EXACT is set on.

As said earlier, using the == does not allow for records Amy, Amber, or Amanda to be included by the filter when I enter only "Am". With ==, both sides must be equal before being included by the filter and that makes sense. Using set exact off and using the = allows the left side of the comparison be equal to the length of the right side, therefore "Amber" = "A" is true, whereas "A" == "A" is false.

Testing for an "" or empty is something different altogether.

KALP1 said:
afterrowcolchange event check set('filter')
I need to check this, thanks...

Olaf said:
I rather assume you have a condition, which you THINK filters somethin, twhich it doesn't, for example, again, because of using = where you want exact match ==
OK, I'll dig deeper...

Thanks,
Stanley
 
Stanley said:
Quote (KALP1)
afterrowcolchange event check set('filter')

I need to check this, thanks...

You don't need to write any code in the AfterRowColChange event in order to check this.

Assuming you are running in the development environment, just suspend the program (from the Program) menu, and then open the Debugger (from the Tools menu). In the Watch window, look at SET("FILTER").

Mike
__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
I don't know your filter expression, so please provide it and say what records you see in the grid, which you shouldn't see. I still guess it has to do with the expectation ="" filters out rows, while it doesn't at all.

Bye, Olaf.
 
One other point:

Are you sure your filter is being applied to the correct work area? Grids have been known to surreptitiously change the work area when they receive focus?

Just a thought.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Another possible cause is the use of "THIS" in the filter expression which makes the filtering out of scope when an object in the grid loses or gets the focus.


kilroy [knight]
philippines

"Once a king, always a king. But being a knight is more than enough."
 
Hi kilroy,

Another possible cause is the use of "THIS" in the filter expression

Are you saying
this.parent.parent.txtUserName.value = "UserName" - can produce going out of scope???

whereas
thisform.txtUserName.value = "UserName" - would NOT cause the going out of scope???

Thanks, Stanley
 
Hi kilroy,

I just tried changing this, still same problem...

Code:
SET DELETED ON

lcFindValue = UPPER(ALLTRIM(thisform.pageframe1.pagRecordLicense.container1.txtFind.Value))
*lcFindValue = UPPER(ALLTRIM(This.Parent.txtFind.Value))
lnCount = 0

if EMPTY(lcFindValue)
	lcFindValue = 'FindValueIsEmpty'
ENDIF
	
Select 'Applicant2'

With This
	Do Case
		Case .Parent.opgSearchBy.Value = 1
			Set Filter To license_id = Val(lcFindValue)

		Case .Parent.opgSearchBy.Value = 2
			Set Filter To Upper(party1_name) = lcFindValue

		Case .Parent.opgSearchBy.Value = 3
			Set Filter To Upper(party2_name) = lcFindValue

		Case .Parent.opgSearchBy.Value = 4
			Set Filter To license_date >= Date() - 30

		Case .Parent.opgSearchBy.Value = 5
			Set Filter To
	Endcase

	GO top
	Count To lnCount

Picture0007_db86mu.png

Thanks for the suggestion...
Stanley
 
Hi Mike,

Mike said:
Are you sure your filter is being applied to the correct work area?

Yes, only one work area open. The data that shows is from the correct table, just not filtered as they should be. The grid in not messed up with bad values or columns, just ignoring the filter as soon as you scroll the grid.

Thanks,
Stanley
 
FINALLY FIXED...

And so simple that we all overlooked it. And I'm ashamed to admit it...

Changing lcFindValue's variable type from local to public done the trick.

It works perfectly now... just like my many other implementations of this.

Also, note that it also works perfectly using the this reference as in
This.Parent.txtFind.Value

Thanks to everyone,
Stanley
 
Public variables is a terrible idea, and should be avoided. Instead you can make it a property of the form, or one of it's objects.
 
You spotted it, fine. Like tore says public variables should be avoided as hell. If you don't need the aspect of your filter auto adjusting when the variable value changes, you can avoid the use of any variable or property in filters.

Alon the aspect of using THIS. No filter know what THIS would even mean. Just because you SET FILTER TO .... inside a controls method, THIS is not meaning the control to the filter. You need to remember the filter expression isn't just evaluated once when you set it in the context of that code setting it, it is a separate context outside of any control, form, etc. It has no THIS nor THISFORM. So avoid any references, which are not global anyway, you can use _SCREEN, that's available in any scope/context, but donb't ever use THIS, THISFORTM, THIS.PARENT, THISOFRM.text1 etc. All these only are constant references in the context of a control or form, but filter are belonging to a workarea, nothing else. That's their context, not any form or object.

And yes, it strikes out now, since you used filter expressions using variables, they can't work after the method ends. Local variables are released then.

Bye, Olaf.
 
Hi tble-ken and Olaf,

Public variables is a terrible idea, and should be avoided. Instead you can make it a property of the form, or one of it's objects.

Yes I know, but that's not the point here. I was asking WHY am I getting this behavior when I only have one workspace and lcFindValue's value was NOT changed anywhere at anytime.

If you don't need the aspect of your filter auto adjusting when the variable value changes
But the value was NOT changing...

Alon the aspect of using THIS. No filter know what THIS would even mean. Just because you SET FILTER TO .... inside a controls method, THIS is not meaning the control to the filter. You need to remember the filter expression isn't just evaluated once when you set it in the context of that code setting it, it is a separate context outside of any control, form, etc. It has no THIS nor THISFORM. So avoid any references, which are not global anyway, you can use _SCREEN, that's available in any scope/context, but don't ever use THIS, THISFORTM, THIS.PARENT, THISOFRM.text1 etc. All these only are constant references in the context of a control or form, but filter are belonging to a workarea, nothing else. That's their context, not any form or object.

Thanks Olaf for this info. Makes perfect sense. I have some refactoring to do...

they can't work after the method ends. Local variables are released then.

Exactly...

Thanks, Stanley
 
Hi Olaf,

If you don't need the aspect of your filter auto adjusting when the variable value changes, you can avoid the use of any variable or property in filters.

With your statement above, I'm curious to see how you would write my filter below that uses a value of a textbox.

lcFindValue = thisform.txtFind.Value
set Filter To table.party1_name = lcFindValue

Thanks, Stanley


 
>But the value was NOT changing...

You seem to misunderstand aagain. A variable changing or staying with a value both are NO problem, the releasing of a variable is a problem.

A filter condition using a variable that avoids that scope problem by being available also to the filter/workarea outside of any method/object/form scope, eg through being public or being a property of a public object like _screen.filtervalue or anyhting like that, enables you to set a filter once and then change how/what it filters by changing that value.

You act like you thnik the filter expression only is evaluated once during SET FILTER, but that's not the case. It is evaluated over and over again any moment the record pointer in the workarea changes, and it makes a skip 1 a skip whatever-number-or-rows-needed to the next record fulfilling the filter condition, for example. Also when you change data the changed row may fall out of the filter when you leave it, especially using a browse window while a filter is set. Try it out and you see. Filters in themselves are a construct not working nicely.

When you query data with a same/similar WHERE clause, you get the result set fulfilling that conditions and that makes better use of rushmore optimization than a filer. It might just take much longer in case there are lots of data fitting the filter/where clause. In general SQL is to be preferred, though. Not a top of your todo list right now, as that needs even more refactoring.

As a simple demo do this: USE some dbf, BROWSE that and then SET FILTER TO IsNull(_vfp.DoCmd("? SECONDS()")). It will not filter/remove any data from the browse, as the return value of _vfp.doCmd always is NULL, but you'll see when the filter expression is evaluated, each time you click in the window, for example, or when you move via arrow keys. For that to work, obviously a variable only existing at the time you SET FILTER can't work.

Bye, Olaf.
 
Thinking about what Olaf just said ....

The only time I use SET FILTER is within a processing routine. In other words, in a chunk of code that performs some action without user intervention. I almost never use it in an interactive process, precisely because of the need to keep the controlling variables in scope.

To go back to your original question, Stanley, since you want to show your filtered records within a grid, that would be an argument for not using SET FILTER. Instead, create a cursor that contains the sub-set of records that you want to show, and use that cursor to populate the grid.

The problem with that is that, if you allow the user to edit the data in the grid, those edits would not get sent back to the underlying table. You can solve that either by programatically updating the underlying table when the form closes (or when the user hits a Save button); or by using a local view to populate the grid (a local view is essentially a cursor with some wrapping that enables it to sync to the underlying table).

I realise it's a bit late in the day to be saying all this, but it's something you might want to keep in mind.

Mike


__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top