Author Topic: Dynamic Random Access Field creation  (Read 2260 times)

0 Members and 1 Guest are viewing this topic.

Offline JohnUKresults

  • Newbie
  • Posts: 40
    • View Profile
Dynamic Random Access Field creation
« on: May 24, 2021, 01:38:50 pm »
Hi folks

I'm trying to figure out how to set up a random access file where I don't know the overall record size at the outset.

The purpose is to store a number of times for laps of a race. Each race will have its own number of laps which may be (for example) as few as 3 or as many as 12.

The first couple of fields will be of fixed size (4 characters each) to store a race number and also a record number pointer, to access a linked file. The remaining fields will store an 11 character content, which will be a time down to 2 decimal places, such as 01:14:23.21. However, the program needs to be able to set up the RA file on the fly, depending on the number of laps.

It's simple enough to define the total record size (8 plus (laps*11)) but I'm having a problem getting my head round how to set up the FIELD instruction for the file when I don't know how many separate fields will be within the file.

I could make the record size as big as I might ever need (e.g. 96 for 8 laps or 118 for 10 laps) but that seems a bit inefficient and also won't help if I then get a 20 lap race, without rewriting that part of the program.

Has anyone overcome this sort of problem previously?

I'm sure there's a relatively simple solution staring me in the face. If not, I'll go with the 20 lap option even though I may never get that many....

So you know, the number of laps is fixed at the outset of the program, after user input of the value. It's stored in a variables file so won't change after setup, and is read when that file is opened.

Thanks for your time and any input.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Dynamic Random Access Field creation
« Reply #1 on: May 24, 2021, 01:42:58 pm »
Fields are the old way, use Type with fixed strings if you need strings.

Check Wiki Open For Random Access for Type method.

Note: the Type method had replaced the Field method (from old GW?) way back with QB4.5 in 90's.
I was using Random Access with QB4.5 or VB for DOS for Inventories at work in early 90's. Type (User Defined Type = UDT) makes it pretty easy.
« Last Edit: May 24, 2021, 01:57:21 pm by bplus »

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Dynamic Random Access Field creation
« Reply #2 on: May 24, 2021, 02:08:47 pm »
I am reading more of your post...

Don't confuse record with file length. One record makes a "row" in a file, the file of records can be any number of records, each "field" of Type item = a column of data:

Type record
  name as string * 16
  date as string * 10   ' MM/DD/xxxx
  phone as string * 12 ' xxx-xxx-xxxx
end type

                  Name           Date                 Phone
record 1
record 2
...


The beauty of Random Access is you can add and edit records to file (and back) by a simple Get or Put of a record number.

Yes, you can have a record with only one field or Type Item like lap.

Probably the fastest way to go is arrays, load and save your data from | to files by array blocks.
File access is slow, in old days when memory was much more precious they used files to extend RAM memory now not needed so much.
« Last Edit: May 24, 2021, 02:20:38 pm by bplus »

Offline 191Brian

  • Newbie
  • Posts: 91
    • View Profile
    • My Itch page
Re: Dynamic Random Access Field creation
« Reply #3 on: May 24, 2021, 02:25:35 pm »
Hi @JohnUKresults

In this situation I would use 2 files 1 file to hold the race details (header) 1 to hold the laps or drivers (details) it makes the programming a bit more complicated but ultimately much more efficient.
Brian ...

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Dynamic Random Access Field creation
« Reply #4 on: May 24, 2021, 03:30:30 pm »
If it's just Race, lap, lap, lap... x amount of laps, use variable length strings with comma delimiters and a 2nd delimiter for each line = race, maybe chr$(10), use split and join to save and load the data. With Chr$(10) between lines = races you could edit the file in a regular word processor!

Split #1 with chr$(10) to make an array or lines = races and laps
Split #2 with comma delimiter and make a line the race header followed by laps, number of laps = number of lines in 2nd array split out by comma minus the race header.

But you could make the file name the race header (Location + date + time) and just store all laps in file, heck a sequential will do for that.

Offline SpriggsySpriggs

  • Forum Resident
  • Posts: 1145
  • Larger than life
    • View Profile
    • GitHub
Re: Dynamic Random Access Field creation
« Reply #5 on: May 24, 2021, 03:37:26 pm »
One could even do a MySQL database :)
Shuwatch!

Offline JohnUKresults

  • Newbie
  • Posts: 40
    • View Profile
Re: Dynamic Random Access Field creation
« Reply #6 on: May 24, 2021, 08:11:03 pm »
Thanks all. Food for thought.

I think I can't do what I want which is to create a record containing x number of fields which are not predefined. I probably didn't fully explain.

Race 1 may have 5 laps, each record containing a number (4 digits), a file pointer (also 4 digits which says which record in another random access file contains competitor information for that race number) and then 6 fields, one for each lap time plus one for the total of those times.

Race 2 might be 10 laps, so 2 x 4 character fields, plus 11 for laps and total.

What I am trying to discover is if there is a way to extend the FIELD line in the program to accommodate any number of laps without having to specify every field e.g. FIELD 1, 4 AS n$(1), 4 AS n$(2), 11 AS n$(3), 11 AS n$(4).... then up to 11 AS n$(×) where x is the number of laps plus 3 (plus 3 to allow for the 3 non-lap fields) just by specifying x at some point in the program.

All of the time fields in each record are the same size, it's just the first 2 which are 4 characters.

Suspect I can't do that.

Whilst I could temporarily work with arrays I would still need files to store that data for future access.

I had thought of sequential files but they are slower to handle and read from.

Felix - if I could handle MySQL I probably wouldn't be asking the question! :-)

Cheers

Offline JohnUKresults

  • Newbie
  • Posts: 40
    • View Profile
Re: Dynamic Random Access Field creation
« Reply #7 on: May 24, 2021, 08:13:54 pm »
Sorry, that last comment should be directed to Spriggsy. Not sure why I put Felix!! I blame extreme old age and a late night ;-)

Offline 191Brian

  • Newbie
  • Posts: 91
    • View Profile
    • My Itch page
Re: Dynamic Random Access Field creation
« Reply #8 on: May 25, 2021, 03:12:14 am »
If you only need to access the data from QB64 then using arrays is probably best as it is quite simple to read and write whole arrays to and from a binary file plus they're much faster than file i/o. To save an arrays to file I write a single line comma delimited file with the array sizes then use PUT to write the arrays to binary files.
Brian ...

Offline euklides

  • Forum Regular
  • Posts: 128
    • View Profile
Re: Dynamic Random Access Field creation
« Reply #9 on: May 25, 2021, 04:18:32 am »
Exemple for fielding( from an old of my programs...)

DIM ca$(30), cr$(50), cp$(12, 50), co$(50), n$(60), rc(6)

OUVRE1: OPEN "r", #1, "c:\temp\soc.dat", 3000: longc = LOF(1) / 3000
FIELD #1, 3000 AS to$
FOR x = 1 TO 30: GET #4, x + 10: z$ = "*"
    IF z$ = "*" THEN a = CVI(db$): b = CVI(fi$): FIELD #1, a - 1 AS mu1$, b - a + 1 AS ca$(x)
    NEXT: FOR x = 1 TO 50: GET #4, x + 40: z$ = LEFT$(ki$, 1): a = CVI(db$)
FIELD #1, a - 1 AS mu$, 4 AS cr$(x): NEXT
FOR rub = 1 TO 50: GET #4, rub + 90: z$ = LEFT$(ki$, 1): a = CVI(db$): IF rub > 44 THEN z$ = ""
    IF z$ <> "*" THEN FOR mois = 1 TO 12: z = a - 1 + ((mois - 1) * 4): FIELD #1, z AS mu$, 4 AS cp$(mois, rub): NEXT mois
NEXT rub:
'especially here
FOR rub = 1 TO 50: a = 2800 + (rub - 1) * 4: FIELD #1, a AS mu$, 4 AS co$(rub): NEXT
FIELD #1, 1 AS mu$:


No explanation, but observe the ' mu$ ' variable use repeatedly to generate the fields.
This is the way to enter a dimensioned variable in a random file
« Last Edit: May 25, 2021, 04:24:35 am by euklides »
Why not yes ?

Offline JohnUKresults

  • Newbie
  • Posts: 40
    • View Profile
Re: Dynamic Random Access Field creation
« Reply #10 on: May 25, 2021, 06:30:51 am »
ok thanks :-)

Offline Dimster

  • Forum Resident
  • Posts: 500
    • View Profile
Re: Dynamic Random Access Field creation
« Reply #11 on: May 25, 2021, 09:14:41 am »
I ran into something similar but with Select Case, where I wanted the program to add a Case or two during the run of the program and dependent on input from the user of the program. I couldn't do it. But one of the things I tried was to use a Select Case inside a Do Loop. Each Case had a Redim _Preserve of an array. It was the closest I could get to the flexibility of resizing an array on the run. Honestly it crashed more often than naught. Pushing the boundaries can be quite adventurous.

Offline JohnUKresults

  • Newbie
  • Posts: 40
    • View Profile
Re: Dynamic Random Access Field creation
« Reply #12 on: May 26, 2021, 07:08:50 am »
Hi all

Thanks for all your suggestions

Decided to use 2D arrays instead!

However, I'm now experiencing another issue - mathematical accuracy! I'll post separately