Page 1 of 1

QBasic random access files, help needed.

Posted: Wed Jun 06, 2007 2:44 am
by BDProductions
A long time ago I wrote an inventory program which used random file access.... now I can not remember how I accomplished it with QB..javascript:emoticon(':oops:')
Embarassed

I now have a commercial solution for the inventory program, so no longer have my old code to look over...

Must be missing something here... I have looked at the included QBasic command index, read over what I believe to be the pertinent points, and can not get it to create the files I need (just makes blank files)javascript:emoticon(':oops:')
Embarassed

I need to open a new file with :

INPUT "Enter file name: ", filename$
filenum% = FREEFILE

OPEN R, filenum%, filename$, LEN = 81
or
OPEN filename$ FOR RANDOM AS filenum% LEN = 81

field #1, 36 as id$, 3 as fln$, 32 as typ$, 4 as ply$, 6 as dte$
____________________


This is where I think I am getting lost... I think there is supposed to be some kind of PUT statement in there... and eventually a close...

As indicated, I need 5 fields, random access, Probably not more than 200 entries... but I need to load all of them into an array for sorting and rewriting to a new file.

Here is the scenario:
I have short files that need scheduling...
Field 1 is up to 36 characters for filename (eg. file0023.mpg)
Field 2 is 3 characters for playtime in seconds (never more than 300s)
Field 3 is 32 characters for 2 reasons -
1. Classification of content by type (eg. Promo, song, etc.)
2. Sorting by rules such that one type never follows the same type in the completed list. (list never goes promo, promo, music, still, promo, promo....) If it were music, no 2 songs would be the same genre.

Field 4 is 4 characters (1-1500) which is divided by 30 and multiplied by 7 ( I know it could be represented by less characters, but it will be easier to use if the number is based off of a month's file playout.

Field 5 is a 6 digit number stored as a string, also for sorting purposes... notably it is the YYMMDD when the file should no longer be in the lists generated.

So, what we need is a list entry and randomizer that will assure out of aprox. 200 files, some are played more than others (Field 4), some never play back to back(Field 3), and some will expire (possibly in the middle of a list) sooner than others(Field 5), and also they must output in groups each totaling 2 minutes (or up to 2 seconds less) based on Field 2...

I have no problem with the sorting routine... it's just the file access and updates I am having trouble with...javascript:emoticon(':oops:')
Embarassed

At some point I will need to open these new files with another program and integrate them in another script, but I do not yet know the format of that file yet. I am still awaiting the whitepaper on the format...

It is assumed that possibly I may write the first program to output the 3rd file format, once I know what it is...

Permission has been granted by my hardware supplier to write code to do exactly what I propose, since their scripting is too clumsy to schedule with when the inserted file list must be changed every 7 days, and each day needs apx. 120 files to be inserted depending on lengths... and of course no 2 days can contain the same or similar lists.

The hardest part is that there is a skeleton schedule of local files which play without exception on a very rigid schedule, and the inserted files will need to be quite literally inserted between other lines of scripting....

What I will have to do is make an exception list for static filenames, and search and replace individual files from the insert list into the skeleton list.

It's my fault... I ordered the hardware... but the solution is fairly close at hand, I believe...

The skeleton file is somewhat readable in wordpad... (not encrypted)... I can see the files that need to be replaced, but not necessarily their lengths, which is imperative.

For tonight I will try to see about locating file lengths in the skeleton....

Please help me figure the random access file part...
Thank You in advance.

Posted: Wed Jun 06, 2007 11:18 pm
by buff1
Generally random files (fixed length files) are used with a type definition.
Here are some program fragments. Not meant to be a running or complete program but to illustrate open/read/write functions with random files.

Code: Select all

Type InventoryStock
  PartNumber as string * 10
  Description as String * 30
  Cost as single
end type
dim MyInventoy as InventoryStock
open "Inventory.Fil" for random as #1 len=len(MyInventory)
NR%=LOF(1)/Len(MyInventory)
For RN%=1 to NR%
 Get #1,RN%,MyInventory
 print MyInventory.PartNumber
 print MyInventory.Description
 print MyInventory.Cost
next
MyInventory.Partnumber = Part$
MyInventory.Description=Desc$
MyInventory.Cost=Amount
Put #1,RN%,MyInventory

Posted: Wed Jun 13, 2007 4:16 pm
by Mac
Did you understand buff1's suggestion? Here it is in more detail

Mac

Code: Select all

CLS
TYPE Song
  id AS STRING * 36
  fln AS STRING * 3
  typ AS STRING * 32
  ply AS STRING * 4
  dte AS STRING * 6
END TYPE
CONST MaxSongs = 100
DIM s(MaxSongs) AS Song
DIM Ls AS INTEGER: Ls = LEN(s(1))
DIM i AS INTEGER, j AS INTEGER

'========= Create test data
RANDOMIZE TIMER
OPEN "Old.sng" FOR OUTPUT AS #1: CLOSE #1 ' Ensure zero length
OPEN "Old.sng" FOR RANDOM AS #1 LEN = Ls
DIM r AS LONG: r = FIX(RND * MaxSongs)
PRINT "Writing"; r; " test records"
FOR i = 1 TO r
  RSET s(0).id = STR$(FIX(RND * 999999))
  RSET s(0).fln = STR$(i)
  PUT #1, i, s(0)
NEXT i
CLOSE #1

'========= Do run that sorts by ID
OPEN "Old.sng" FOR RANDOM AS #1 LEN = Ls
DIM NumberOfSongs AS INTEGER: NumberOfSongs = LOF(1) / Ls
IF NumberOfSongs > MaxSongs THEN PRINT "Too many songs": END
PRINT "Reading"; NumberOfSongs; " test records"
FOR i = 1 TO NumberOfSongs: GET #1, i, s(i): NEXT i
CLOSE #1
PRINT "Sorting"
FOR i = 1 TO NumberOfSongs - 1
  FOR j = i TO NumberOfSongs
    IF s(i).id > s(j).id THEN SWAP s(i), s(j)
  NEXT j
NEXT i
PRINT "Writing"
OPEN "New.sng" FOR OUTPUT AS #1: CLOSE 'Ensure zero length
OPEN "New.sng" FOR RANDOM AS #1 LEN = Ls
FOR i = 1 TO NumberOfSongs: PUT #1, i, s(i): NEXT i
CLOSE #1

'========== See if new file created properly
PRINT "Testing"
OPEN "New.sng" FOR RANDOM AS #1 LEN = Ls
DIM ns2 AS INTEGER: ns2 = LOF(1) / Ls
PRINT "Reading"; ns2; " records"
LINE INPUT "Press Enter to continue test"; e$
FOR i = 1 TO ns2
  GET #1, i, s(i)
  PRINT s(i).id; s(i).fln
NEXT i
CLOSE #1
LINE INPUT "That's all Folks! Press Enter"; e$
SYSTEM

BDProductions is a Ephemeralus

Posted: Mon Aug 06, 2007 8:21 pm
by Mac
Don't you just hate people who post a question and never come back?

Mac

Posted: Tue Aug 07, 2007 8:57 am
by buff1
Yes. I have clients, i'll send an update to fix a problem and they never get
back to me unless there's another problem. Of course, that usually means
it's ok but one still likes to be told thanks every now and then. LOL.