620 likes | 912 Views
Data Files. In all your projects so far, the user has entered information through text-boxes This input method is unsatisfactory for large quantities of data Many computer applications require data to be saved from one run to the next e.g. inventory records, customer files etc.
E N D
Data Files • In all your projects so far, the user has entered information through text-boxes • This input method is unsatisfactory for large quantities of data • Many computer applications require data to be saved from one run to the next e.g. inventory records, customer files etc.
File Organisation • The manner in which data are organised,stored and retrieved. • 2 Common file organisations: • Sequential • Random
Opening and Closing Data Files • Open the file. Before any data may be placed on the disk or read from the disk, the file must be opened. Generally done in Form_Load procedure. • Read or Write the data records. • Close the file.
Open Statement Open “Filename” For {Input/Output/Append/Random} As #FileNumber • The Open statement elements shown in the chain brackets are the file mode, indicating the way that you will access the file. This is a required entry, so one of the modes must be chosen. • The first three choices are used for sequential files.
Open Statement • The FileNumber may be from 1 to 511 • Record Length may be up to 32,767 characters Open “A:\DataFile.dat” For Output As #1 Open “C:\VB6\Names.txt” For Input As #2
FreeFile and Close Statements • FreeFile function returns the next unused file number • intFileNumber = FreeFile • In large projects, file numbers are hard to track and allocate • Close issued automatically when you end • Issue Close statement before leaving prog. • Close #1 or Close #1, #2
To locate an available file number for a large project, always use the FreeFile function to locate an unused file number. • You don’t care what number is chosen—only that it is available. • Store the retrieved file number in a module or global variable so other forms can manipulate the files, if necessary.
Obtain an available file number this way: • Dim intFileNumb As Integer • intFileNumb = FreeFile ‘Obtain next available file number • Open “File.dat” For Output As #intFileNumb • Whenever you reference the preceding file, you do so with the intFileNumb variable rather than a literal (number).
Example: Private Sub cmdCreateFile_Click() Dim name1 As String, name2 As String ' Demonstrate use of Write # statement Open "PIONEER.TXT" For Output As #1 Write #1, "ENIAC" Write #1, 1946 Write #1, "ENIAC", 1946 name1 = "Eckert" name2 = "Mauchly" Write #1, 14 * 139, "J.P. " & name1, name2, "John" Close #1 End Sub Reference number File name Write to the file Close the file
Sequential File Organization • Sequential file records are stored one after another • Use Write to output data • Use Input to read data • File must be opened prior to first use • Form: Write #fn, item1, item2,…, itemn Input #fn, item1, item2,…, itemn • EOF function signals end of file
Output fields are placed one after another and end with <CR> • If you create a form to add records to a file, the Open statement is commonly placed in the form Load event procedure, whereas the write statement is placed in the click procedure of an Add button. • Input statement reads sequential data • Input #1, lblName.Caption, lblStreet.Caption • Input #2, stAccount, stDescription, cPrice • When reading a sequential file, the EOF (End Of File) condition is raised when you attempt to read the n+1st record (n records total).
The EOF function is used to determine when EOF occurs • EOF form: EOF(filenumber) • Example reading sequential data file and populating two list boxes: Do Until EOF(intFileNumb) Input #intFileNumb, stName, stPhone lstName.AddItem stName ‘add name to a list box lstPhone.AddItem stPhone ‘add phone to a list box Loop Close #intFileNumb ‘close the input file
Writing to a Sequential File • Write statement places data in output • Form: Write #file, o1, o2, …, on • You can separate fields with commas or semicolons • Output fields are separated with commas, and strings are quoted. • <Cr>/<Lf> ends each record • Write #1, txtLname.Text, 54.89
Example (Adding a player to a BASEBALL1.TXT file) Private Sub Form_Load() Open App.Path & "\BASEBALl.TXT" For Append As #1 End Sub Private Sub cmdAddRec_Click() Write #1, txtPlayer.Text, txtTimes.Text, txtHits.Text txtPlayer.Text = “ “ txtTimes.Text =“ ” txtHits.Text=“ ” txtPlayer.SetFocus End Sub Private Sub cmdQuit_Click() Close #1 End End Sub Opening the file in append mode
Reading Data in a Sequential File • Form: Input #fn, item1,…,itemn • Separate fields items with commas • File number must be that of an open file • When you read the last record, end-of-file signals • You detect end of file with the EOF function: EOF(FileNumber)
EOF returns false until end of file is reached. • Typical read loop: • Do Until EOF(1) • Input #1, strCofFlavor, strRoastName, strRoastCity • Loop • If the file contains five records, then EOF is raised on the fifth input execution, not on the sixth Input.
Trapping Program Errors • Errors may be trapped asynchronously • Visual Basic generates an error number whenever an error occurs • To handle errors, you must • Turn on error handling feature: On Error... • Create error handling code • Determine what is to be done after processing the error (continue, end program,…)
Place On Error in any procedure that is to traps and processes errors • Example: • Private Sub Form_Load() • On Error GoTo HandleErrors 'Turn on error trapping • Open "A:\Testdata.dat" For Input As #1 • … (more code here) • Exit Sub 'exit to avoid executing error routine • HandleErrors: • ‘some code to handle error • Resume • End Sub
A line label is a name followed by a colon on a line by itself • HandleErrors is a line label • Forms of On Error statement: • On Error GoTolinelabel transfer control to label in module • On Error Resume Next skip error line & continue with next • On Error GoTo 0 turns off error handling
The Err Object • The Err object holds information about error that just occurred • Err.Source holds the source of the error • Err.Number holds the error number • Err.Description contains error description • You can raise an error condition—turn on an error—with: Err.Raise Number:=xx
Err.Number Err.Description • 7 Out of memory • 9 Subscript out of range • 11 Division by zero • 13 Type mismatch • 52 Bad filename or number • 53 File not found (fnf) • 54 Bad file mode • 58 File already exists • 61 Disk full • 67 Too many files • 68 Device unavailable • 70 Permission denied • 71 Disk not ready • 75 Path/file access error • 76 Path not found • 482 Printer error • Raise error 76 in program code: Err.Raise Number:=76
Coding Error-Handling Routines • On Error statement designates error handler • Code to handle errors follows line label • Line label appears on line by itself and ends with a colon • A Case statement works well to sort out errors with a "switchboard" • Continue execution with Resume statement
Using Case to handle errors with a "Switchboard": • Select Case Err.Number • Case 53 'Handle error # 53 here • … • Case 71 'Handle error # 71 here • ... • Case Else 'Handle all other errors here • … • End Select
Resume statement forms: • Resume continues with line causing error (careful!) • Resume Next continues with line following one that caused error • Resume linelabel continues at line label, which must be in same proc • Exit statement jumps out of structure--a function, subroutine, or loop • Exit should be placed before line label of error handling routine so normal program flow doesn't drop through the error code.
Exit and Exit Sub Statements • Exit Sub immediately exits current sub procedure • Exit Function immediately exits current function • Exit is used to prematurely halt execution of sub procedure or function when extraordinary conditions occur • Place Exit Sub above error handling label
Saving Changes to a File • When data changes, ask users if they want to save the changes before program ends • Changed data is known as “dirty” data • Keep track of data changes with a global boolean flag • Any procedure that allows data to change should set the flag to True—indicating “dirty” data file • Check file just before ending program
You should Unload all forms before executing an End statement. • This triggers each form’s Unload event (and each Class’s Terminate event), giving you control at that point to check for “dirty” data files. • The best way to ask the user if they want to save changes is in the QueryUnload event procedure. • The QueryUnload event procedure obtains control when the (what else!) QueryUnload event occurs. • QueryUnload occurs when the user: • clicks an Exit button or menu command to exit • clicks on a window’s Close button • or exits Windows altogether
QueryUnload procedure example: Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer) Dim intResponse As Integer If mblnIsDirty Then IntResponse = MsgBox(“Data has changed. Save it?”, _ vbYesNo + vbQuestion, “Coffee List Changed Warning”) If intResponse = vbYes Then mnuFileSave_Click End If End If End Sub
Sequential File Prog. Example • You can load a combo box by reading from a data file and executing the AddItem method • Reading file & list filling halts when EOF occurs on input file
Random Access Files • A Random Access file is like an array of records stored on a disk. • The records are numbered 1,2,3, and so on, and can be referred to by their numbers. • Therefore, a Random Access File resembles a box of index cards, each having a numbered tab. Any card can be selected from the box without first reading every index card preceding it; similarly any record of a random access file can be read without having to read every record preceding it.
Random File Organization • Records are fixed length and have a record number (data type=long integer) for reference • Fields are fixed length and position • Less data then length will be padded with spaces • More data than length will be truncated
Random File Example • Read or written in any order • Think of the structure being "like a table"
Defining the Record Structure • Must be done before reading or writing • Use Type/End Type statements • Code in General Declarations • Use fixed length strings • Specify length in Dim statement • Ex: Dim strFName as String * 20 • Number variables do not require explicit length
Type/End Type Private Type Person intEmpNum AsInteger strFName AsString* 20 strLName AsString*30 strPhone AsString*12 curRate AsCurrency End Type Dim mudtPersonRecord As Person Open App.Path & "\Names.dat"For Random as #1 Len=Len (mudtPersonRecord) Note: mudt prefix for User Defined Type
Open Statement • Once the random file is opened it can be used for both input and output unlike sequential files! • If you open a file that does not exist, VB will create it as an empty file • Once opened, data are available for read/write operations one record at a time
Reading a Random File • Open an existing file for Random • Use Get Statement to read the records
Get Statement • Usually coded in Form_Load • If populating a listbox or combo use a Do Until reach last record to read data Get #FileNumber, [RecordNumber],RecordName Get #2, 4, mudtPersonRecord Get #2,intRecordNumber, mudtPersonRecord [ ] indicates optional, if RecordNumber is omitted, the next record is read
Put Statement • Use to place/save data in a random file • File must already be opened "For Random" • Place code in mnuFileSave, mnuFileClose or Form_QueryUnload • Follow with a Close statement
Put Statement Example Put #FileNumber, [RecordNumber],RecordName Put #2,4, mudtPersonRecord Put #2,intRecordNumber, mudtPersonRecord [ ] indicates optional, if RecordNumber is omitted, the next record is read
Accessing the Fields • Get and Put operate on an entire record • Reference the individual fields using dot notation for the User Defined Type
Accessing the Fields (cont.) • Read using Get then update textbox Get #2, 1, mudtPersonRecord txtLName.Text = mudtPersonRecord.strLName • Update field from textbox the Write using Put: mudtPersonRecord.strPhone = txtPhone.Text Put #2, 1, mudtPersonRecord
LOF Function • Length of File function returns the size of the file in bytes • Use instead of EOF used for sequential files • To determine the highest record number in the file divide LOF by the size of one record LOF(FileNumber) LOF(3) intNumRecords=LOF(3)/Len(mudtPersonRecord)
Seek Function • Returns the current location of the pointer = the next record in the file to be processed Seek(FileNumber) intNextRecord=Seek(3)
Trim Functions • Remove extra blank spaces in a string • Trim ==> removes spaces from both ends • LTrim==> removes spaces at left end • RTrim ==> removes spaces at right end Trim(String) LTrim(String) RTrim(String) txtLName.Text=RTrim(mudtPersonRecord.strLName)
Reading/Retrieving Records – Sample Code Sub GetRecord(lngRecNum as Long) Get #1, lngRecNum, mudtPersonRecord With mudtPhoneRecord txtEmpNum.Text = .intEmpNum txtFName.Text = RTrim(.strFName) txtLName.Text = Rtrim(.strLName) txtPhone.Text = Rtrim(.strPhone) txtRate.Text = .curRate End With End Sub
Writing Records –Sample Code Sub PutRecord(lngRecNum as Long) With mudtPhoneRecord .intEmpNum=Val(txtEmpNum.Text) .strFName = txtFName.Text .strLName = txtLName.Text .strPhone = txtPhone.Text .curRate = Val(txtRate.Text) End With Put #1, lngRecNum, mudtPersonRecord End Sub
Using ListBox to Store Random File Key Field (p 413) • When you Get or Put a record you need to know the record number • To keep track of record numbers store them in ItemData property of ListBox • When user selects a value from the list, read its ItemData property to retrieve the desired record
Updating a Random File • Create routines to • Edit existing records • Add new records • Delete existing records