Smart questions
Smart answers
Smart people
INTELLIGENT WORK FORUMS
FOR COMPUTER PROFESSIONALS

Member Login

Come Join Us!

Are you a
Computer / IT professional?
Join Tek-Tips now!
  • Talk With Other Members
  • Be Notified Of Responses
    To Your Posts
  • Keyword Search
  • One-Click Access To Your
    Favorite Forums
  • Automated Signatures
    On Your Posts
  • Best Of All, It's Free!

Join Tek-Tips
*Tek-Tips's functionality depends on members receiving e-mail. By joining you are opting in to receive e-mail.

LINK TO THIS FORUM!

Add Stickiness To Your Site By Linking To This Professionally Managed Technical Forum.
Just copy and paste the
code below into your site.

Partner With Us!

"Best Of Breed" Forums Add Stickiness To Your Site
Partner Button
(Download This Button Today!)

Feedback

"...I signed up to your site to get help with a problem and I am so glad I did. I found the help I needed immediately. Thanks to all who contribute to your site..."

Geography

Where in the world do Tek-Tips members come from?

AT() Function on Memo Field Causing "file read error".

Brak (Programmer)
29 Nov 11 14:51
I am using the AT() function to search for the number to times a sequence of characters appears in a text stored in a memo field.
After the count reaches 140779 give produces a "file read error" error message.

If there is only 140778 then the AT() should just return a 0 instead of giving me an error message.

So what is the problem, and what can I do to solve it?

Thanks in advance.
danfreeman (Programmer)
29 Nov 11 15:47
Each version of Foxpro has its own limits and it sounds like you've found one.

Which version are you using?

Occurs() would be better for this purpose than AT(), but I don't remember which version introduced it.
Brak (Programmer)
29 Nov 11 16:01
I'm using 2.6 for Windows.
jrbbldr (Programmer)
29 Nov 11 16:23
OCCURS() is indeed a valid Function in FPW2.6.  

I just checked my old FPW2.6 Help and found it.

If you have questions, look into your own help for how to use the OCCURS() Function

You may indeed encounter the same error message due to some other 'gotcha', but it is worth a try and it will more quickly/effectively give you a count of the number to times a sequence of characters appears in a text string.

Good Luck,
JRB-Bldr
 
Brak (Programmer)
29 Nov 11 16:48
Thank you so much for the info. Even though I have been programming in Fox for almost 18 year I never knew that function existed!

I ran the function but I got an "string to long to fit" error.
jrbbldr (Programmer)
29 Nov 11 17:04
You might try doing a loop to acquire parts of the Memo field value using SUBSTR() which are small enough to not generate the error and add up the OCCURS() values as you go.

Good Luck,
JRB-Bldr
 
danfreeman (Programmer)
29 Nov 11 17:05
Yes, that would make sense. String limits were smaller in FP2.x than what we enjoy today in VFP. The string limit was 16K if I recall correctly (which may very well not be the case).

The only workaround is going to be breaking that text into smaller chunks.

Use COPY MEMO to write to a temp file, and then use LLFNs to read chunks smaller than 16K from the text file until you've worked all the way through.

(Even with all those steps it should still be quite quick.)
Brak (Programmer)
29 Nov 11 17:15
That's a good idea if I was searching for single characters. But I am searching for a string - so splitting the search up would not work as if the string I'm looking for is at the "seam" it wouldn't be counted.

I wonder why this function kicks out a "too long" error when the AT() didn't, but rather gave a "read file" if looking beyond 140778.
danfreeman (Programmer)
29 Nov 11 18:46
I'm afraid you're looking at either not getting it done at all or doing it the only way you can (which includes accounting for the string spanning the "seam"). The spanning problem can be solved easily by simply starting each chunk early enough to account for the length of the search string at the end of the previous chunk.

Nobody knows why the two functions give two different error messages, but most likely it's because one of them dates from dBase and the other came later and is plugged into better error reporting.

This isn't a new problem by any means. It's always solved by brute force programming.
jrbbldr (Programmer)
29 Nov 11 22:47
If, by whatever means, you get the entire Memo field value into a number of strings, you can then do a OCCURS() on the composite string.

CODE

  * --- By whatever means populate the various cStringN ---
  * --- variables with the overall Memo Field Value ---
  nTestStrCount = OCCURS(cTstString,(cString1 + cString2 + cString3)

I just tested the above with the following and it accurately shows the number of "0"'s:

CODE

cString1 = repl('1',999) + "0"
cString2 = repl('1',999) + "0"
cString3 = repl('1',999) + "0"
cString4 = repl('1',999) + "0"
cString5 = repl('1',999) + "0"
cString6 = repl('1',999) + "0"
cString7 = repl('1',999) + "0"
cString8 = repl('1',999) + "0"
cString9 = repl('1',999) + "0"
?OCCURS("0",(cString1 + cString2 + cString3 + cString4 + cString5 + cString6 + cString7 + cString8 + cString9))

Perhaps that approach would eliminate your issue of the Test String possibly occurring at the boundary.

Good Luck,
JRB-Bldr
 
dbMark (Programmer)
8 Dec 11 1:41

Quote:

String limits were smaller in FP2.x than what we enjoy today in VFP. The string limit was 16K if I recall correctly (which may very well not be the case).
Ah, the old days, I remember FPD 2.6 had a max limit of 1KB in a parameter.  Oh well, that's not the subject at hand...

Today's VFP 9.0 appears to have a maximum memo field length of 16MB but I determined that by experimentation, I didn't find it in the VFP system capacities chart.  I don't know what the maximum size is for your version, but the code below assumes it is similar.

Presuming your version can use SUBSTR() up to the maximum size of your memo fields, then this should work.

CODE

FUNCTION myOccurs
PARAMETERS cSearchExp, cSearchFld, nBlockSize
PRIVATE nMemoLen, nBlock, cChunk, nBeg, nEnd, nMatches
nMemoLen = LEN(EVALUATE(cSearchFld))
nBlock = IIF(TYPE("nBlockSize")="N", nBlockSize, 15000)  && optional, set 15000 as default block size
cChunk = ""
nBeg = 0
nMatches = 0
IF nBlock > LEN(cSearchExp)
   DO WHILE nBeg + LEN(cChunk) <= nMemoLen
      IF nBeg = 0
         nBeg = 1
      ELSE
         nBeg = nEnd - (LEN(cSearchExp)-1)
      ENDIF    
      nEnd = MIN(nBeg + nBlock - 1, nMemoLen)
      cChunk = SUBSTR(EVALUATE(cSearchFld), nBeg, nBlock - 1)
      nMatches = nMatches + OCCURS(cSearchExp, cChunk)
   ENDDO
ELSE
   ? "You specified a search block size smaller than the search expression."
ENDIF
RETURN nMatches
This is an example using myOccurs().  Remember to include the alias if you are not in that work area.

CODE

? myOccurs("text here", "MyMemoFld", 5000)
* if 3rd parm not sent, default is 15000
 
dbMark (Programmer)
8 Dec 11 1:47
This code is incorrect.

CODE

IF nBlock > LEN(cSearchExp)
This code is better.

CODE

IF nBlock => LEN(cSearchExp)
 
dbMark (Programmer)
8 Dec 11 1:57
This code addresses the possibility of the search phrase lying across the end boundary of the string segment being searched.  To handle that possibility, the next segment (which I named nChunk) begins not on the next character after the end of the segment but offset backward for the length of the search phrase less 1.
danfreeman (Programmer)
8 Dec 11 14:37

Quote:

Today's VFP 9.0 appears to have a maximum memo field length of 16MB but I determined that by experimentation, I didn't find it in the VFP system capacities chart.  I don't know what the maximum size is for your version, but the code below assumes it is similar.

This is incorrect. Memo fields are limited only by disk space and the 2GB file size limit.

The 16MB limitation you've observed applies to strings in memory -- not to memo fields themselves.

Reply To This Thread

Posting in the Tek-Tips forums is a member-only feature.

Click Here to join Tek-Tips and talk with other members!

Close Box

Join Tek-Tips® Today!

Join your peers on the Internet's largest technical computer professional community.
It's easy to join and it's free.

Here's Why Members Love Tek-Tips Forums:

Register now while it's still free!

Already a member? Close this window and log in.

Join Us             Close