home account info subscribe login search FAQ/help site map contact us


 
Brief Full
 Advanced
      Search
 Search Tips
To access the contents, click the chapter and section titles.

Advanced Visual Basic Techniques
(Publisher: John Wiley & Sons, Inc.)
Author(s): Rod Stephens
ISBN: 0471188816
Publication Date: 06/01/97

Search this book:
 
Previous Table of Contents Next


Using DataModified

When the user wants to close the document, open a new document, or exit the application, ExpenseReporter must decide if the document is safe. If DataModified is false, the data has not been changed since it was loaded or since the last time it was saved. In that case, the document is safe and ExpenseReporter can grant the user’s request with no more trouble.

If DataModified is true, the application cannot immediately do the user’s bidding without losing changes to the data. To prevent this, the program first asks the user if it should save the changes. ExpenseReporter gives the user three choices.

•  Yes, save the data.
•  No, discard the changes.
•  Cancel the requested operation and resume editing the document.

To make managing all of this easier, ExpenseReporter uses the function DataSafe. This function returns true if the data is safe and false otherwise.

DataSafe begins by checking the value of DataModified. If DataModified is false, the data is safe and no more checking is required.

Next, if the document has been modified, DataSafe asks the user if the program should save the changes. The function takes the question it should ask the user as a parameter so the program can match the question to the situation. For example, when the user wants to exit, ExpenseReporter passes DataSafe the string, “Do you want to save the changes before exiting?”

If the user responds by clicking the Yes button, DataSafe invokes the SaveData function. This function, which is described later, attempts to save the document. It returns true if it succeeds and false otherwise. SaveData may fail if it encounters trouble writing the data file.

A less obvious problem can arise if the document is new. In that case, the application does not yet have a name for the document’s data file, so SaveData asks the user to select a file for saving. If the user cancels the file selection dialog, the file will not be saved so SaveData will return false. In turn, DataSafe will return false so the original operation, such as closing the file or exiting ExpenseReporter, will be considered unsafe.

When DataSafe asks the user if the program should save the modified data, the user may click the No button. In that case the user wants to discard the changes so the data is considered safe. DataSafe returns true so the user can close the document, open a new file, or exit.

Finally, when DataSafe asks the user if it should save the data, the user may click the Cancel button. In that case, the user has decided not to close the current document. DataSafe returns false to indicate that the data is not safely saved. The application will not close the document, open a new document, or exit.

The following code shows how DataSafe works in detail.

Function DataSafe(prompt As String) As Boolean
Dim result As Integer

    If DataModified Then
        ‘ See if the user wants to save the data.
        result = MsgBox( _
            “The data has been modified. ” & prompt, _
            vbYesNoCancel, “Data Modified”)
        If result = vbYes Then
            ‘ The data is safe if the user
            ‘ successfully saves it.
            DataSafe = SaveData()
        ElseIf result = vbNo Then
            ‘ The user does not want to save the
            ‘ changes so the data is “safe.”
            DataSafe = True
        Else
            ‘ The user canceled the exit operation.
            ‘ Set DataSafe false so QueryUnload
            ‘ cancels the unload.
            DataSafe = False
        End If
    Else
        ‘ The data has not been modified.
        DataSafe = True
    End If  ‘ End if the data has been modified.
End Function

The DataSafe function encapsulates the complicated process of deciding whether the application should continue with a file close, file open, or exit operation. This makes the routines that handle those operations much simpler.

For instance, ExpenseReporter uses the main form’s QueryUnload event to decide when to exit. The QueryUnload event is generated whenever Visual Basic is about to unload the form. This includes when the user selects the Close command from the form’s control box menu, as well as when the program executes an UNLOAD statement for the form. If the application’s Exit command in the File menu ends the program using the UNLOAD statement rather than the End command, the QueryUnload event also occurs. This gives the application a single place to handle all the ways the user might attempt to exit the application.

The QueryUnload event handler has an integer parameter Cancel. If the subroutine sets Cancel to true, Visual Basic cancels the unload operation and the form remains loaded. The following code shows how the QueryUnload event for ExpenseReporter’s main form uses DataSafe to decide whether to allow the user to exit. Because all of the complicated document-saving code is located in the DataSafe function, this subroutine can be quite simple.

Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
    Cancel = (Not _
        DataSafe(“Do you want to save the changes before exiting?”))
End Sub

Loading and Saving Files

Loading or saving a file is simple in itself. ExpenseReporter uses Visual Basic’s INPUT statement to read data from a file and the WRITE statement to write data into a file. The functions FileInput and FileWrite read and write the data for a complete expense report.

It is important that these two functions remain exactly synchronized. If FileWrite saves a group of data items and FileInput attempts to read the items in a different order, FileInput will not read the same values that FileWrite saved. This can be a big problem if the data file formats change between different releases of the application.

One way to protect the applications from this sort of data format mismatch is to place a file type identifier at the beginning of the data files. FileWrite saves a string indicating the data format of the file. When FileInput reads this string, it decides if the format is one it recognizes. If not, it tells the user there is a problem and stops reading from the file before it loads all sorts of confusing half-information.

If an application has a long life span, different releases may require different file formats. In that case, later versions of FileInput can use the file identification string to select one of several different file-reading subroutines to read any of the different formats. FileWrite would save files in only the most recent format. This is similar to the way Visual Basic 4 can read Visual Basic 3 project files but saves them in the newer version 4 format.

The following code shows ExpenseReporter’s FileWrite and FileInput functions. The constant FILE_IDENTIFIER is declared in the form’s declarations section. The RowNotBlank function examines the controls in one expense row and returns true if any of them has a nonblank value.

In addition to loading the data file, the FileInput function performs a couple of other tasks to prepare the newly loaded file for use. It invokes the SortRows subroutine to arrange the expense rows so they are sorted by date. ExpenseReporter also sorts the rows before printing an expense report so the rows are printed in their most natural order. The application, however, does not reorder the rows as they are entered because that might distract and confuse the user.


Previous Table of Contents Next


Products |  Contact Us |  About Us |  Privacy  |  Ad Info  |  Home

Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written permision of EarthWeb is prohibited.