>I am rewriting an application originally done in Access (by someone else). The application uses an Access filtering function were wildcards can be used to search for data. The client very often gets partial information fron the customer and has to search for container # "TEST12345MI" by using "*12345*". Is there a way to use wildcards with FoxPro seek(). I am probably going to do some kind of search using at() unless someone has a better suggestion. The filtering method being used in the Access application is very slow and I would like to improve the speed.
Larry,
For seek() itself wildcards are not supported. There is like() that you could use with commands like 'locate for ..' ie:
locate for like('*12345*', myField)
Also SQL supports wildcards in the form ' ... like "%123_5%"' ( correspond to *123?5* ). ie:
select * from mytable where myField like '%12345%'
Both like() and like are case sensitive. ATC() is case insensitive but you should build the pattern with it. Instead a search :
locate for like(upper(lcSearchPattern), upper(myField) )
is more appropriate.
If string is like you showed (starting with an *) then with 'set exact off' you could first do a seek on partial string (part where another wildcard occurs if any) and from there on continue with locate. ie:
lparameters tcSearchExpr, tcField
if tcSearcExpr = '*'
locate for like(upper(tcSearchExpr), upper(eval(tcField)))
return !eof()
endif
lnAsterixPos = at(tcSearchExpr,'*')
lnQuestionPos = at(tcSearchExpr,'?')
do case
case lnAsterixPos>0 and lnQuestionPos>0
lcSearch = left(tcSearchExpr,min(lnAsterixPos, lnQuestionPos)-1)
case lnAsterixPos>0
lcSearch = left(tcSearchExpr,lnAsterixPos-1)
case lnQuestionPos>0
lcSearch = left(tcSearchExpr,lnQuestionPos-1)
otherwise
return seek(tcSearchExpr,lcTable,lcTag)
endcase
if seek(lcSearch,lcTable,lcTag)
locate for like(lcSearchExpr, upper(eval(tcField))) ;
while upper(eval(tcField)) = lcSearch
return !eof()
endif
If wildcard searches almost always done on a few fields (which are not very long) you could also create a series of tags for those fields and seek() in a loop. This might seem to be a silly thing to do but served me well on 286 computers years ago :)
for ix=1 to len(myField)-1
index on substr(myField,ix) tag ('sub'+padl(ix,2,'0'))
endfor
Collecting all records from these tags into an intermediate cursor and then do a second pattern matching unbelieveably boosted up wildcard search eliminating worst case '*' preceding :)
Cetin