简体   繁体   中英

Can i use a function in SET FILTER TO

I have a simple Function

FUNCTION TEST
    LOCAL lcExp
    FOR I = 0 TO 10
        lcExp = lcExp + " AND plz="+STR(I)
    ENDFOR
    RETURN lcExp
ENDFUNC

It's only an example. These function here makes no sense.

Now i want to use this function to build my string for SET FILTER . I have tried

SET FILTER TO test()

SET FILTER TO EVALUATE(test())

Anyone know how to get this working?

I'm working with visual foxpro8. Thanks for help.

The first syntax - SET FILTER TO test() - is perfectly all right, as long as Fox can find the function. Eg you may need to do SET PROCEDURE TO foo ADDITIVE if the function resides in foo.prg .

However, the function will be called frequently for wildly different records when a browse is open for the cursor, since Fox needs to call the filter to find out what the 'active' records are - ie those that pass the filter expression. You can see this if you execute the following commands:

strto("debugout alias(), recno()", "foo.prg")
set proc to foo addi
acti wind debug
sele 0
use sys(2005) shar noup agai
brow last nowa
set filt to foo()

If you want to achieve some side effect whenever the current record changes then it can be better abuse SET RELATION for the purpose, because it only ever gets called for the current record.

Obviously, the SET RELATION needs some target cursor, so the function used for this trick will usually receive an index expression as its first argument and pass it through (ie RETURN it) after doing something interesting. Fox evaluates the relation expression very often, which means it is best to cache the key and only perform side effects when the key has changed.

I've been using this at work for decades now to make Fox start displaying the image related to the keys in the current table (we do a lot of prescription form processing). A hotkey instantiates the global image manager if necessary and sets up the relation for the current workarea (with a dummy sink cursor if necessary), and from then on I can always see the image for whatever the then-current record might be. A second press of the hotkey unwires the whole shebang. Simple, efficient, and bloody convenient.

Having said that, I think that valid (ab)uses of filter and relation expressions for side effects are very few and very far between...

PS: if you have a function that returns an expression that you want to use as a filter then you have to catch the expression in a variable, so that you can use what the docs call macro substitution:

local cExpr
cExpr = test()
set filter to &cExpr

If you used

set filter to evaluate(test())   && usually a bad idea!

then the filter expression would be recomputed every time Fox needs to evaluate to filter, which is very often indeed.

If you used

local cExpr
cExpr = test()
set filter to evaluate(m.cExpr)  && often not a good idea!

then the variable would not be available once execution leaves the local scope. That problem could be avoided by using a global variable for the expression, but compiling the expression into the filter (via macro substitution) is more efficient. The difference becomes very notable with tables that have non-homoeopathic record counts...

your function will need to return a boolean value -> .t.|.f.

USE ( _samples + "data\customer")
SET FILTER TO myFilter()
browse 

myFilter.prg:

LOCAL llok
llok = "a" $ contact and  LEFT(city,1) = "C"
RETURN llok

Using "set filter" by itself is not a good idea. Many Foxpro developers have it in their list of "not to use commands". Its behavior is ugly and you can experience unpredictable results. It is not worth to demonstrate its side effects, simply do not use it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM