Level Extreme platform
Subscription
Corporate profile
Products & Services
Support
Legal
Français
Seek() with wildcards (*?)
Message
From
14/05/2001 13:28:31
Cetin Basoz
Engineerica Inc.
Izmir, Turkey
 
 
To
14/05/2001 11:26:26
General information
Forum:
Visual FoxPro
Category:
Coding, syntax & commands
Miscellaneous
Thread ID:
00506837
Message ID:
00506929
Views:
14
>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 = '*' && Worst case
  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
     * Plain seek() only-best case
     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
Çetin Basöz

The way to Go
Flutter - For mobile, web and desktop.
World's most advanced open source relational database.
.Net for foxheads - Blog (main)
FoxSharp - Blog (mirror)
Welcome to FoxyClasses

LinqPad - C#,VB,F#,SQL,eSQL ... scratchpad
Previous
Reply
Map
View

Click here to load this message in the networking platform