Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Need some Qbasic help me Random Files/ Records (Please)
#1
I've been trying for the past week, and I don't know how to do the following. Any help would be appreciated.

1. Delete a record (Have the user enter the record number they want deleted, and have it deleted)

2. Count how many records are in a file (for sorting purposes)

Thanks Smile

BTW, As I advance in learning more about this stuff, I may have more questions (But I'm fine for now)
Reply
#2
1. Delete a record.

One way to delete a record is to make a variable of whatever size your record is, use the ERASE command to clear it (if it is $STATIC, which it will be unless you have used the $DYNAMIC metacommand), and then use the PUT command to put the now-blank record into your file at whatever spot. For example

Code:
TYPE RecordType
  FirstName as STRING * 10
  LastName as STRING * 10
  Age as INTEGER
  PhoneNumber as STRING * 10
END TYPE

DIM CurrentRecord as RecordType

' This will add a record to spot #{Location} of your file

CurrentRecord.FirstName = "Jane"
CurrentRecord.LastName = "Doe"
CurrentRecord.Age = 21
CurrentRecord.PhoneNumber = "5551234567"
OPEN "records.dat" FOR RANDOM AS #1 LEN = LEN(CurrentRecord)
  PUT #1, Location, CurrentRecord
CLOSE #1

' This will erase spot #{Location} of your file

ERASE CurrentRecord
OPEN "records.dat" FOR RANDOM AS #1 LEN = LEN(CurrentRecord)
  PUT #1, Location, CurrentRecord
CLOSE #1

So there you go. Alternatively, you could DIM another variable dynamically, use it, and then erase it:

Code:
REM $DYNAMIC
DIM RecordBlank AS RecordType
OPEN "records.dat" FOR RANDOM AS #1 LEN = LEN(RecordBlank)
  PUT #1, Location, RecordBlank
CLOSE #1
ERASE RecordBlank

2. Count how many records are in a file.

Again, there are several ways to do this. One method is to use the EOF (end of file) command. However, this gets a bit tricky because the way EOF figures out whether it's at the end of a file opened as RANDOM is whether or not the LAST attempted GET command made a new record. Which means you could do a loop until EOF(filenumber), but it will keep tacking blank records onto the enf of your file. For example:

Code:
OPEN "records.dat" FOR RANDOM AS #1 LEN = LEN(CurrentRecord)
  Location = 0
  DO
    Location = Location + 1
    GET #1, Location, CurrentRecord
  LOOP UNTIL EOF(1)
CLOSE #1

This piece of code will end up with the variable "Location" equal to the LAST record in the file, which it will have just created at spot "Location." Does that make sense? So, Location will equal the total number of previously existing entries, PLUS ONE THAT IT MAKES. This would work for a single run-through, but each run-through will add one more blank record to the end of your file.

Another way to do this which will only add a blank record ONCE, is to do the following:

Code:
OPEN "records.dat" FOR RANDOM AS #1 LEN = LEN(CurrentRecord)
  Location = 0
  DO
    Location = Location + 1
    GET #1, Location, CurrentRecord
  LOOP UNTIL EOF(1) OR CurrentRecord.Age = -1
  CurrentRecord.Age = -1
  PUT #1, Location, CurrentRecord
CLOSE #1

This code will end up with Location again equaling the total number of records in the file PLUS ONE, and it will add an additional record to the end of the file that acts as a "marker" for the next time it's called.

Finally, if you want your code to just count, say, the number of records in the file that have actual first names entered, as opposed to being blank, and you don't care how many blank records get thrown at the end, try this code:

Code:
DIM CurrentRecord as RecordType, BlankRecord as RecordType

OPEN "records.dat" FOR RANDOM AS #1 LEN = LEN(CurrentRecord)
  Location = 0
  Counter = 0
  DO
    Location = Location + 1
    GET #1, Location, CurrentRecord
    IF CurrentRecord.FirstName <> BlankRecord.FirstName
      Counter = Counter + 1
    END IF
  LOOP UNTIL EOF(1)
CLOSE #1

Now, Counter will be equal to the number of records in the file that have first names entered.

Hope that helps!

*peace*

Meg.
Reply
#3
Wow, thanks.

I believe I understand know, although it is still slightly unclear. I'm sure I will understand as soon as practice a little bit more though Big Grin

Thanks.


Edit: Oh yea, for the erasing of a record, I can merely call the record (lets say it is called "Record"), type

Quote:Erase Record
OPEN "records.dat" FOR RANDOM AS #1 LEN = LEN(CurrentRecord)
PUT #1, RequiredNumber, Record
CLOSE #1

and I now have a blank record?

thanks a lot Big Grin
Reply
#4
Look up the following commands in QB's help:

ERASE, $STATIC, $DYNAMIC, DIM, TYPE, OPEN (for random), EOF

That should contain all the info you need. The code I wrote will make sense, then. You'll see what I mean about the way the EOF (end of file) command operated on files that have been opened different ways--FOR RANDOM, FOR INPUT, and FOR APPEND

If you have any other questions, post 'em.

*peace*

Meg.
Reply
#5
Quote:DIM CurrentRecord as RecordType, BlankRecord as RecordType

OPEN "records.dat" FOR RANDOM AS #1 LEN = LEN(CurrentRecord)
Location = 0
Counter = 0
DO
Location = Location + 1
GET #1, Location, CurrentRecord
IF CurrentRecord.FirstName <> BlankRecord.FirstName
Counter = Counter + 1
END IF
LOOP UNTIL EOF(1)
CLOSE #1

In this code, you have "BlankRecord.Firstname" what does this signify? Do I just Dimension a new one and keep it blank?

thx Smile
Reply
#6
in the short code you put there, typos aside, i have some comments:

1. if your record is called "Record" (which i'm not positive is a legal variable name.. but I could be wrong.. it might be reserved for a command) then you need to make sure that when you open the data file, you specify that the LENGTH OF EACH RECORD IN IT ( LEN = ) is set to the LENGTH OF YOUR RECORD. So:

Code:
ERASE MyVariableIsCalledRecord
OPEN "records.dat" FOR RANDOM AS #1 LEN = LEN(MyVariableIsCalledRecord)

See? They have to match.

2. In your code, "RequiredNumber" refers to the LOCATION IN THE DATA FILE that you wish to put the (now blank) record. If it is 4, then the 4th slot in the data file will be deleted. Actually, it's technically the fifth slot, because there is a slot at 0, too.

*peace*

Meg.
Reply
#7
Quote:
Quote:DIM CurrentRecord as RecordType, BlankRecord as RecordType

OPEN "records.dat" FOR RANDOM AS #1 LEN = LEN(CurrentRecord)
Location = 0
Counter = 0
DO
Location = Location + 1
GET #1, Location, CurrentRecord
IF CurrentRecord.FirstName <> BlankRecord.FirstName
Counter = Counter + 1
END IF
LOOP UNTIL EOF(1)
CLOSE #1

In this code, you have "BlankRecord.Firstname" what does this signify? Do I just Dimension a new one and keep it blank?

Exactly. The reason for doing this is as follows:

When you use TYPE to declare a user-defined variable type--in this case, RecordType--and then use DIM to declare a variable as that type:

Code:
DIM CurrentRecord AS RecordType

Then the elements of that record (such as Age, FirstName, etc, which are defined in the TYPE definition) are accessed by:

{name of record}.{element}

for example, CurrentRecord.Age or CurrentRecord.FirstName

The reason why I made another variable of RecordType called BlankRecord, and left it blank, is because when you DIM CurrentRecord as RecordType, the elements in there that are defined in RecordType to be 10-character strings will default to 10-character strings full of (I believe) spaces.. NOT NULL STRINGS ("")

So when you want to see if the record is blank, testing whether

CurrentRecord.FirstName <> ""

will always be TRUE, even if the Record IS blank! So instead, I made a blank record and tested the FirstName element in CurrentRecord against that in BlankRecord.

If the default for strings IS to fill them with spaces, which I can't remember, then you could get rid of BlankRecord, and replace the test with

CurrentRecord <> " " (that's 10 spaces)

Hope that makes sense.

*peace*

Meg.
Reply
#8
in the short code you put there, typos aside, i have some comments:

1. if your record is called "Record" (which i'm not positive is a legal variable name.. but I could be wrong.. it might be reserved for a command) then you need to make sure that when you open the data file, you specify that the LENGTH OF EACH RECORD IN IT ( LEN = ) is set to the LENGTH OF YOUR RECORD. So:

Code:
ERASE MyVariableIsCalledRecord
OPEN "records.dat" FOR RANDOM AS #1 LEN = LEN(MyVariableIsCalledRecord)

See? They have to match.

2. In your code, "RequiredNumber" refers to the LOCATION IN THE DATA FILE that you wish to put the (now blank) record. If it is 4, then the 4th slot in the data file will be deleted. Actually, it's technically the fifth slot, because there is a slot at 0, too.

*peace*

Meg.
Reply
#9
ok, I understand now.

Also, instead of using

Code:
DIM CurrentRecord as RecordType, BlankRecord as RecordType

IF CurrentRecord.FirstName <> BlankRecord.FirstName

If FirstName is dimensioned at 15 characters, could I just do

Code:
If CurrentRecord.FirstName <> "///////////////"

/ = space, there are 15 spaces.


One more thing. When I print out my Records, and I use a FOR NEXT LOOP, will it print out my "erased" records that have blank spaces.

Code:
FOR Next = 1 to counter
Get #1, Counter, CurrentRecord
PRINT CurrentRecord.Firstname
NEXT X

or will it have to be

Code:
FOR X = 1 to counter
Get #1, Counter, CurrentRecord
IF CurrentRecord.Firstname <> "///////////////" THEN
             PRINT CurrentRecord.Firstname
END IF
NEXT X


The reason I am asking is because I want to be able to bubble sort my records (after I place them into an array) by doing the following:

Code:
FOR X = 1 to Counter
GET #1, Counter, CurrentRecord
Let CurrentRecord.Firstname = Firstname(x)
NEXT X
Reply
#10
You *will* have to make some kind of check for it not to print out the blank records. Checking the FirstName field against a blank string of the proper length would do the trick, like you suggested.

If you want to load the entire data file into an array, you could do it:

Code:
REM $DYNAMIC

TYPE RecordType
  FirstName AS STRING * 10
  LastName AS STRING * 10
  Age AS INTEGER
END TYPE

DIM CurrentRecord AS RecordType

REM {get the # of records}
OPEN "records.dat" FOR RANDOM AS #1 LEN = LEN(CurrentRecord)
  Location = 0
  Counter = 0
  DO
    Location = Location + 1
    GET #1, Location, CurrentRecord
    IF CurrentRecord.FirstName <> "          " THEN
      Counter = Counter + 1
    END IF
  LOOP UNTIL EOF(1)
CLOSE #1

REM {make an array of size =  # of records in the file}
REDIM RecordArray(1 TO Counter) AS RecordType

REM {load the entire data file into the array}
OPEN "records.dat" FOR RANDOM AS #1 LEN = LEN(CurrentRecord)
  Location = 0
  FOR x = 1 TO Counter
    Found = 0
    DO
      Location = Location + 1
      GET #1, Location, CurrentRecord
      IF CurrentRecord.FirstName <> "          " THEN
        RecordArray(x) = CurrentRecord
        Found = 1
      END IF
    LOOP UNTIL Found = 1
  NEXT x
CLOSE #1

So you see, this code does the following:

1. Finds out how many non-blank records are in your file (and creates one blank one at the end in the process)

2. Creates an array called RecordArray that's the proper size. You can access elements of this array like RecordArray(x).{element}, for example: RecordArray(1).FirstName, or RecordArray(3).Age

3. Unless I've made an error, it will load all the non-blank records into this array (this process should NOT make a blank record at the end of the file)

Hope this helps!

*peace*

Meg.
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)