I have to ask a silly question. :-[
For years i have used Random files to store data and had this elaborate way of keeping track of the next field to enter data into.
So FINALLY, i read the PB help file on SEEK in a Random File to determine the next line of entry.
I am assembling a wizard to help me manage Random files and I am trying to automate the entire process. (Duhh, perhaps using SQL will be better, but moving an old habit is HARD.)
Ok, but when i use seek after opening a Random File, it keeps on returning 1 as the next field of entry, which is quite useless.
Or am I as usual overlooking the obvious?
:-[
I think we need to see some code to be able to help ... :)
Eddy wrote:
QuoteI think we need to see some code to be able to help
I agree.
What created this random file? If it's a new (empty) file then you would expect seek to return 1.
If you open it in random-access mode, it returns the next record. So it depends on the record length that you define when you open the file. I don't know what PB returns if you specify a 'strange' record length. But if you give us more info, maybe we can help better...
Wilko
PLEASE FORGIVE the language comments. Its just for my forgetful mind.
Basically record lengths are 5000. That allows me to use the same function for numerous forms saving data.
Thats the plan anyway.
Function Add_record(datastring As String, filename As String) As Long '(0=Error 1=Korrek)
'All records in all files is van nou af as volg:
'EEN lang string, opgesplit met PARSE.
'ALLE file_lenghts is van nou af 5000. Hopelik is meer nie nodig nie. 5000 chrs per lyn.
'eerste segmet van alle lyne is die lyn nommer waar die entry geplaas is.
Dim NEWLEN As Long
NEWLEN = FreeFile
Try
Open filename For Random As #NEWLEN Len = 5000
'Find last line in File:
Position&& = Seek(NEWLEN)
MsgBox Str$(position&&) 'so i can see while debugging what it is at this point.
'Die datastring is reeds korrek saamgestel deur die BIND_string funksie.
Put #NEWLEN,position&&, datastring
Close #NEWLEN
Catch
Close #newlen
Add_record = 0
Exit Function
End Try
Add_record = 1
End Function
Usually it is something small i overlook in my haste....thanks heavens for good friends on this forum!
Hi Petrus,
No need to apologize for the language comments. They are even helpful ;)
What you do:
- you open the file; you are then at the beginning of the file; 'Position&&' therefore returns 1
- then you put the string at record #1 explicitly (Put #Newlen, position&& etc), NOT at the end of the file (what you probably want or am I wrong)
- you close the file
I guess you mean to put the new record at the end. Have a look at the help of the Put statement:
For random access files, RecPos is the record to be written, in the range 1 to (2^63)-1. If RecPos is omitted, the next record in sequence (following the one specified by the most recent GET, PUT or SEEK) is written. If the file was only just opened, the first record is written.
Groeten,
Wilko
Hi Wilko
Yes Wilko, you will understand most of my comments. Dankie my vriend! :P
Yes, as i read the helpfile, it suggested it will give me the next available number in the file to write to.
With other types of file you can just do EOF or something like that, but i have to have it random files so i can easily save, extract and delete certain lines.
So yes, an easier way of how i used to do it to determine the last line in a Random file would be nice as the way i do it takes WAY TOO LONG.
I tried something like this in a function:
Function nextplace(openfilenum As Long) As Long
Dim p As Long 'P = 5000 (all records the same)
p = 5000
nextplace = Int(Lof(openfilenum) / Len(P)) + 1
End Function
But that had surprising results.... :P
1, 2 , 19890 , 79879797987987897 etc. Good grief.
The purpose of the Seek statement (From PBWin manual):
QuoteSet the position in a file for the next input or output operation.
Your comment suggests your understanding of the purpose of the Seek statement is not correct:
'Find last line in File:
Position&& = Seek(NEWLEN)Instead, try:
'Find last line in File:
Position&& = LOF(NEWLEN)/5000 + 1 ' There are LOF(NEWLEN)/5000 records... Add 1 to point to the next one.
thanks David, but now i am back to square one again. It gives me 1 again.
It sounded so simple, and turned out to be intriguingly complex.
Ha, after 25 years in basic i feel very stupid suddenly.
Not sure how you are testing it, but here is my test code:#COMPILE EXE
#DIM ALL
FUNCTION PBMAIN () AS LONG
LOCAL i AS LONG
KILL "Test.txt"
FOR i = 1 TO 5
Add_record(STRING$(5,TRIM$(STR$(i))), "Test.txt")
NEXT
END FUNCTION
FUNCTION Add_record(datastring AS STRING * 5, filename AS STRING) AS LONG '(0=Error 1=Korrek)
'All records in all files is van nou af as volg:
'EEN lang string, opgesplit met PARSE.
'ALLE file_lenghts is van nou af 5000. Hopelik is meer nie nodig nie. 5000 chrs per lyn.
'eerste segmet van alle lyne is die lyn nommer waar die entry geplaas is.
LOCAL Position&&
DIM NEWLEN AS LONG
NEWLEN = FREEFILE
TRY
OPEN filename FOR RANDOM AS #NEWLEN LEN = 5
'Find last line in File:
Position&& = LOF(NEWLEN)/5 + 1
'MsgBox Str$(position&&) 'so i can see while debugging what it is at this point.
'Die datastring is reeds korrek saamgestel deur die BIND_string funksie.
PUT #NEWLEN,position&&, datastring
CLOSE #NEWLEN
CATCH
CLOSE #newlen
Add_record = 0
EXIT FUNCTION
END TRY
Add_record = 1
END FUNCTION
Also, notice I changed your datastring declaration from "as string" (dynamic string) to "as string * 5" (fixed length string) because my test records are 5 characters long. PB dynamic strings are stored with the first two bytes representing the string length. So the last two characters will be truncated. This would happen if you your datastring was a UDT also. So you should declare datastring as such:FUNCTION Add_record(datastring AS STRING, filename AS STRING) AS LONG 'This will lose 2 bytes of data
FUNCTION Add_record(datastring AS STRING * SIZEOF(MyUDT), filename AS STRING) AS LONG 'This one is correct
:D
David, it was that SIZEOF trick that did it.
Thanks a million, its running like clockwork now!
I appreciate all the help today very much!
;D