Posts: 8
Threads: 1
Joined: Apr 2003
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
BTW, As I advance in learning more about this stuff, I may have more questions (But I'm fine for now)
Posts: 480
Threads: 24
Joined: Mar 2003
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.
Posts: 8
Threads: 1
Joined: Apr 2003
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
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
Posts: 480
Threads: 24
Joined: Mar 2003
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.
Posts: 8
Threads: 1
Joined: Apr 2003
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
Posts: 480
Threads: 24
Joined: Mar 2003
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.
Posts: 480
Threads: 24
Joined: Mar 2003
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.
Posts: 480
Threads: 24
Joined: Mar 2003
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.
Posts: 8
Threads: 1
Joined: Apr 2003
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
Posts: 480
Threads: 24
Joined: Mar 2003
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.
|