|
Creating a File-Based Application |
|
To create a file-based application, you can use a simple or complex text editor
such as Notepad. The main action from you is to create the list(s) and save
it(them) as text files using either the txt or any extension of your choice.
After creating a list, when necessary, you can open it to access and optionally
change the values. After making the changes, you can save the file. In the same
way, you can print the values and do any type of file-related operation that you
judge necessary.
One of the disadvantages of using a text editor to create a database is that, if
you decide to distribute it, either your users should know as much as necessary
about the file (its location and its content, just to name a few) you must
provide a mechanical means of accessing the file(s). To make your product more
professional and user friendly, you can create a graphical application that the
user would use to access the values in the database. With this approach, you can
create an attractive graphical user interface (GUI) object that display a
functionality the user is familiar with. Using such an aesthetic interface, you
can provide the means of adding, editing, deleting, or changing the values of
the database.
To create a file-based application, you can use the Microsoft
Visual Basic programming environment that, in combination with the .NET Framework,
provides all the tools you would need.
|
Using Windows Controls and Accessories |
|
To create an aesthetically user-friendly application, you can use the various
Windows controls that are implemented in the .NET Framework. The controls are
varied and are meant to accomplish different roles:
- The form is the most fundamental control. As a container, in fact the main
container, it is the primary object that holds the other controls of an
application
- Based on its fundamental role in an application, a form can be equipped
with functional accessories placed on its frame and intended to assist with
file or print operations. These accessories are the menu(s), the toolbar(s),
and the status bar
- A dialog box is a special type of form you create to perform the same
actions as a form but it does not use the accessories and it may show a
different type of border
- On top of the form or the dialog box, there are controls, referred to as
containers, that can be used to carry or hold other controls. These are the
property sheet, the group box, or the panel
- Text-based controls are used to receive or display text. These are the
label, the text box, the masked text box, and the link label
- Some text-based controls can display enhanced or formatted text beyond the
functionality of the traditional text box. Besides the formatting and the
characteristics of their paragraph, they may also display pictures. These
controls are the rich text box and the web browser
- Button-based controls allow the user to perform an action when clicked.
These controls are the command button, the radio button, and the check box
- List-based controls display a list of items to the user. This type
includes the list box, the combo box, the tree view, the list view, and the
domain up/down
- Date and time-based controls are specialized to handle date and time
values. The controls in this category are the calendar and the date/time
picker
- There are other controls used to show a value (the numeric up-down
control) or a progress (the progress bar), etc
|
Practical
Learning: Introducing File-Based Applications
|
|
- Start Microsoft Visual Basic and create a Windows Forms Application named GeorgetownDryCleaner1
- In the Solution Explorer, right-click Form1.vb and click Rename
- Type Central.vb and press Enter
- From the Menus & Toolbars section of the Toolbox, click MenuStrip and
click the form
- While the menu strip is still selected, in the Properties window, click
(Name) and type mnuMain
- Under the Properties window, click Insert Standard Items
- On the form, click Help and press Delete
- Click Tools and press Delete
- Click Edit and press Delete
- Click File, click Save As and press Delete
- Using the Properties window, change the names of the menu items as
follows:
| Text |
New Name |
| &File |
mnuFile |
| &New |
mnuFileNew |
| &Open |
mnuFileOpen |
| &Save |
mnuFileSave |
| &Print |
mnuFilePrint |
| Print Pre&view |
mnuFilePrintPreview |
- Design the form as follows:
 |
| Control |
Name |
Text |
Additional Properties |
| GroupBox |
 |
|
Order Identification |
|
| Label |
 |
|
&Receipt #: |
|
| TextBox |
 |
txtReceiptNumber |
1000 |
TextAlign: Right |
| Label |
 |
|
Customer Name: |
|
| TextBox |
 |
txtCustomerName |
|
|
| Label |
 |
|
Customer Phone: |
|
| TextBox |
 |
txtCustomerPhone |
|
|
| Label |
 |
|
Date Left: |
|
| DateTimePicker |
 |
dtpDateLeft |
|
|
| Label |
 |
|
Time Left: |
|
| DateTimePicker |
 |
dtpTimeLeft |
|
Format: Time |
| Label |
 |
|
Date Expected: |
|
| DateTimePicker |
 |
dtpDateExpected |
|
|
| Label |
 |
|
Time Expected: |
|
| DateTimePicker |
 |
dtpTimeExpected |
|
Format: Time |
| Label |
 |
|
Order &Status: |
|
| ComboBox |
 |
cbxOrderStatus |
|
|
| Label |
 |
|
D&ate Picked Up: |
|
| DateTimePicker |
 |
dtpDatePickedUp |
|
|
| Label |
 |
|
Time Pic&kep Up: |
|
| DateTimePicker |
 |
dtpTimePickedUp |
|
|
| GroupBox |
 |
|
Order Processing |
|
| Label |
 |
|
Item Type |
|
| Label |
 |
|
Unit Price |
|
| Label |
 |
|
Qty |
|
| Label |
 |
|
Sub Total |
|
| Label |
 |
|
Shirts |
|
| TextBox |
 |
txtShirtsUnitPrice |
1.25 |
TextAlign: Right |
| TextBox |
 |
txtShirtsQuantity |
0 |
TextAlign: Right |
| TextBox |
 |
txtShirtsSubTotal |
0.00 |
TextAlign: Right |
| Label |
 |
|
Pants |
|
| TextBox |
 |
txtPantsUnitPrice |
1.95 |
TextAlign: Right |
| TextBox |
 |
txtPantsQuantity |
|
TextAlign: Right |
| TextBox |
 |
txtPantsSubTotal |
0.00 |
TextAlign: Right |
| ComboBox |
 |
cbxItem1 |
None |
Items:
None
Women Suit
Dress
Regular Skirt
Skirt With Hook
Men's Suit 2Pc
Men's Suit 3Pc
Sweaters
Silk Shirt
Tie
Coat
Jacket
Swede |
| TextBox |
 |
txtItem1UnitPrice |
0.00 |
TextAlign: Right |
| TextBox |
 |
txtItem1Quantity |
0 |
TextAlign: Right |
| TextBox |
 |
txtItem1SubTotal |
0.00 |
TextAlign: Right |
| ComboBox |
 |
cbxItem2 |
None |
Items:
None
Women Suit
Dress
Regular Skirt
Skirt With Hook
Men's Suit 2Pc
Men's Suit 3Pc
Sweaters
Silk Shirt
Tie
Coat
Jacket
Swede |
| TextBox |
 |
txtItem2UnitPrice |
0.00 |
TextAlign: Right |
| TextBox |
 |
txtItem2Quantity |
0 |
TextAlign: Right |
| TextBox |
 |
txtItem2SubTotal |
0.00 |
TextAlign: Right |
| ComboBox |
 |
cbxItem3 |
None |
Items:
None
Women Suit
Dress
Regular Skirt
Skirt With Hook
Men's Suit 2Pc
Men's Suit 3Pc
Sweaters
Silk Shirt
Tie
Coat
Jacket
Swede |
| TextBox |
 |
txtItem3UnitPrice |
0.00 |
TextAlign: Right |
| TextBox |
 |
txtItem3Quantity |
0 |
TextAlign: Right |
| TextBox |
 |
txtItem3SubTotal |
0.00 |
TextAlign: Right |
| ComboBox |
 |
cbxItem4 |
None |
Items:
None
Women Suit
Dress
Regular Skirt
Skirt With Hook
Men's Suit 2Pc
Men's Suit 3Pc
Sweaters
Silk Shirt
Tie
Coat
Jacket
Swede |
| TextBox |
 |
txtItem4UnitPrice |
0.00 |
TextAlign: Right |
| TextBox |
 |
txtItem4Quantity |
0 |
TextAlign: Right |
| TextBox |
 |
txtItem4SubTotal |
0.00 |
TextAlign: Right |
| GroupBox |
 |
|
Order Summary |
|
| Label |
 |
|
Cleaning Total: |
|
| TextBox |
 |
txtCleaningTotal |
0.00 |
TextAlign: Right |
| Label |
 |
|
Tax Rate: |
|
| TextBox |
 |
txtTaxRate |
7.75 |
TextAlign: Right |
| Label |
 |
|
% |
|
| Label |
 |
|
Tax Amount: |
|
| TextBox |
 |
txtTaxAmount |
0.00 |
TextAlign: Right |
| Label |
 |
|
Net Total: |
|
| TextBox |
 |
txtNetPrice |
0.00 |
TextAlign: Right |
|
- Double-click the Time Left control and implement its ValueChanged event as
follows:
Private Sub dtpTimeLeft_ValueChanged(ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles dtpTimeLeft.ValueChanged
Dim DateLeft As Date = dtpDateLeft.Value
Dim TimeLeft As Date = dtpTimeLeft.Value
Dim Time9AM As Date = New DateTime(TimeLeft.Year, _
TimeLeft.Month, _
TimeLeft.Day, 9, 0, 0)
' If the customer leaves clothes before 9AM...
If TimeLeft <= Time9AM Then
' ... then they should be ready the same day after 5PM
dtpDateExpected.Value = DateLeft
dtpTimeExpected.Value = New DateTime(DateLeft.Year, _
DateLeft.Month, _
DateLeft.Day, 17, 0, 0)
Else
' If the clothes were left after 9AM,
' then they will be available the following business morning at 8AM
' If the following day is Sunday,
' then they will be ready the following Monday
If DateLeft.DayOfWeek = DayOfWeek.Saturday Then
dtpDateExpected.Value = DateLeft.AddDays(2D)
dtpTimeExpected.Value = New DateTime(DateLeft.Year, _
DateLeft.Month, _
DateLeft.Day + 2, 8, 0, 0)
Else
dtpDateExpected.Value = New DateTime(DateLeft.Year, _
DateLeft.Month, _
DateLeft.Day + 1)
dtpTimeExpected.Value = New DateTime(DateLeft.Year, _
DateLeft.Month, _
DateLeft.Day + 1, 8, 0, 0)
End If
End If
End Sub
|
- Return to the form
|
The Directory of a Database |
|
One of the biggest differences between a database and a
regular application is that, traditionally, although not always, all of the
files of a database are located in the same directory. The directory can be
local and accessed only by one computer. The directory can be located in one
computer and accessed by various users on different computers or a workgroup.
The directory can be located on a server that no user directly uses but that
directory's files can be accessed from one or more computers.
Another particularity of a database is that usually you, the
database developer, create and manage the directory or directories used by the
application.
Another difference of a database as compared to a regular
application is that, while using the database, users do not create files. This
means that there is no actual file processing on the part of the users. For
example, the user does not even open the database in the traditional sense. You,
the database developer, provides a means of accessing the database. Then, the
user adds, edits, or deletes values.
Based on the above discussion of directories, when creating
a file-based application, one the first actions you should perform consists of
setting up the directory where the file(s) of your application would be located.
If you already know (and you should know) where and how the application would be
accessed, you can manually create a folder using Windows Explorer, My Computer,
or any appropriate utility. Otherwise, you can still programmatically create the
directory.
The .NET
Framework supports the creation and management of directories through various
classes. The main class used to deal with directories is called Directory.
Besides the Directory class, the .NET Framework provides
support for folders through a class named DirectoryInfo. To use it, declare a variable of type DirectoryInfo using its constructor
to initialize it.
To actually create a directory using the static Directory
class, you can call its CreateDirectory() method
that is overloaded with two versions. Here is an example:
Imports System.IO
Public Class Exercise
Private Sub btnDirectory_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles btnDirectory.Click
Directory.CreateDirectory("E:\Bethesda Car Rental")
End Sub
End Class
To create a folder using the DirectoryInfo
class, call its Create()
method that comes in two versions. Here is an example:
Private Sub btnDirectory_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles btnDirectory.Click
Dim Folder As DirectoryInfo = New DirectoryInfo("E:\Bethesda Car Rental")
Folder.Create()
End Sub
When you call either the Directory.CreateDirectory()
method or the DirectoryInfo.Create()
method, if the directory does not exist, it would be created. If the directory
exists already, nothing would happen. This implies that the compiler would not
attempt to create a directory if there is already one in the indicated location
and you can safely call any of these methods without the risk of deleting its existing
files, if any.
Before performing any operation on a directory, you should
first make sure it exists. To get this information, you can call the Directory.Exists()
method that returns a Boolean value. This method takes as argument the path to
the directory. Here is an example:
Private Sub btnDirectory_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles btnDirectory.Click
If Directory.Exists("E:\Bethesda Car Rental") Then
MsgBox("The directory exists already")
Else
MsgBox("That directory was not yet created")
End If
End Sub
During the lifetime of your database, at one time, you may
want to change its location, for any reason you judge necessary. Although this
operation is primarily easily supported, it could become complex in some
scenarios. Still, to move a directory and its contents, you can call the Directory.Move()
method. This method takes two arguments: the source and the destination. After
the method has been called, the directory held by the first argument would be
moved, along with its sub-folders and files, to the path specified by the second
argument. To move a directory using the DirectoryInfo class, you can call
its MoveTo() method.
As opposed to creating a directory, if you do not need it
anymore, you can remove it. To support this, the Directory class is equipped
with the Delete() method that is overloaded with two versions. One of the
versions is used to delete a directory that is currently empty while the other
version is used to delete the directory and its content.
|
Practical
Learning: Setting up a Directory
|
|
- In the top section of the file, type Imports System.IO and press Enter to
have it on its own line
- Under the Class Central line, declare three variables as follows:
Imports System.IO
Public Class Central
Private iFilename As Integer
Private IsNewCleaningOrder As Boolean
Private Filename As String
|
- In the Class Name combo box, select mnuFileNew
- In the Method Name combo box, select Click and implement the event as follows:
Private Sub mnuFileNew_Click(ByVal sender As Object, _
ByVal e As System.EventArgs) _
Handles mnuFileNew.Click
' We will store our files in the following folder
Dim FolderName As String = "C:\Georgetown Dry Cleaner\Receipts"
Dim Folder = Directory.CreateDirectory(FolderName)
' Get the list of files, if any, from our directory
Dim ListOfFiles() = Folder.GetFiles()
' If there is no file in the directory,
' then we will use 1000 as the first file name
If ListOfFiles.Length = 0 Then
iFilename = 1000
Else ' If there was at least one file in the directory
' Get a reference to the last file
Dim LastFile As FileInfo = ListOfFiles(ListOfFiles.Length - 1)
' Get the name of the last file without its extension
Dim fwe As String = Path.GetFileNameWithoutExtension(LastFile.FullName)
' Increment the name of the file by 1
Try
iFilename = CInt(fwe) + 1
Catch Exc As FormatException
End Try
End If
' Update our global name of the file
Filename = FolderName & "\" & CStr(iFilename)& ".gcs"
txtReceiptNumber.Text = iFilename.ToString()
txtCustomerName.Text = ""
txtCustomerPhone.Text = ""
dtpDateLeft.Value = DateTime.Today
dtpTimeLeft.Value = DateTime.Today
dtpDateExpected.Value = DateTime.Today
dtpTimeExpected.Value = DateTime.Today
cbxStatus.Text = "Not Yet Ready"
dtpDatePickedUp.Value = DateTime.Today
dtpTimePickedUp.Value = DateTime.Today
txtUnitPriceShirts.Text = "1.25"
txtQuantityShirts.Text = "0"
txtSubTotalShirts.Text = "0.00"
txtUnitPricePants.Text = "1.95"
txtQuantityPants.Text = "0"
txtSubTotalPants.Text = "0.00"
cbxItem1.Text = "None"
txtUnitPriceItem1.Text = "0.00"
txtQuantityItem1.Text = "0"
txtSubTotalItem1.Text = "0.00"
cbxItem2.Text = "None"
txtUnitPriceItem2.Text = "0.00"
txtQuantityItem2.Text = "0"
txtSubTotalItem2.Text = "0.00"
cbxItem3.Text = "None"
txtUnitPriceItem3.Text = "0.00"
txtQuantityItem3.Text = "0"
txtSubTotalItem3.Text = "0.00"
cbxItem4.Text = "None"
txtUnitPriceItem4.Text = "0.00"
txtQuantityItem4.Text = "0"
txtSubTotalItem4.Text = "0.00"
txtCleaningTotal.Text = "0.00"
txtTaxRate.Text = "7.75"
txtTaxAmount.Text = "0.00"
txtCleaningTotal.Text = "0.00"
txtCustomerName.Focus()
End Sub
|
- Return to the form
|
The Files of a File-Based Application |
|
As its name indicates, a file-base application uses one or
more files to hold its information. If you decide to create the application
using the Visual Basic language, you can take advantage of the .NET Framework rich library
and its support for file processing.
In the .NET Framework, file processing is primarily
supported through the System.IO
namespace that is filled with various classes to deal with files and directories
(folders). The most fundamental class of the System.IO namespace and used
to perform file processing is called File. The abstract and sealed File
class contains all necessary methods used to create a file, check the existence
of a file, write information to a file, read information from a file, or
manipulate the system attributes of a file.
Another one of the fundamental file processing classes is
called Stream. This is mainly an abstract class that lays a foundation
for other stream-oriented classes. One of the classes that derives from Stream
is called FileStream.
To create a new file, you can use the File
class, call one of the versions of its Create() method that
takes an argument as the name of, or the path to, the file and returns a FileStream
object.
Besides File, you can use the StreamWriter
class to create a file. To do this, declare a variable of type StreamWriter
and initialize it using one of its constructors.
One of the most routine operations performed on a class
consists of writing information to it. And one of the most useful classes in
this domain is called StreamWriter. The StreamWriter class is
derived from the TextWriter class. To create a file using the StreamWriter
class, you can declare a StreamWriter variable and initialize it using
one of its constructors. After creating the file, you can write information to
it by calling the Write() or the WriteLine() method. Always make sure you close the stream after using it. Also
make sure you use exception handling in your code.
Here is an example:

Imports System.IO
Public Class Exercise
Private Sub txtLastName_Leave(ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles txtLastName.Leave
Dim strInitials As String = txtFirstName.Text.Substring(0, 1) & _
txtLastName.Text.Substring(0, 1)
txtSave.Text = strInitials
End Sub
Private Sub btnSave_Click(ByVal sender As Object, _
ByVal e As System.EventArgs) _
Handles btnSave.Click
Dim stmWrite As StreamWriter = New StreamWriter(txtSave.Text)
stmWrite.WriteLine(txtFirstName.Text)
stmWrite.WriteLine(txtLastName.Text)
stmWrite.WriteLine(dtpDateHired.Value)
stmWrite.WriteLine(cbxGenders.Text)
stmWrite.WriteLine(txtHourlySalary.Text)
stmWrite.Close()
txtFirstName.Text = ""
txtLastName.Text = ""
dtpDateHired.Value = DateTime.Today
cbxGenders.Text = "Unknown"
txtHourlySalary.Text = "0.00"
txtSave.Text = ""
txtOpen.Text = ""
End Sub
End Class
Besides StreamWriter, to create a file and write
information to it, you can use the BinaryWriter class. You start by
declaring a BinaryWriter variable and initialize it using one of its
constructors, passing a Stream-based object.
|
Practical
Learning: Writing to a File
|
|
- Under the previous End Sub line, define a sub procedure as follows:
Private Sub SaveCleaningOrder()
' We will store our files in the following folder
Dim FolderName As String = "C:\Georgetown Dry Cleaner\Receipts"
Dim Folder As DirectoryInfo = Directory.CreateDirectory(FolderName)
' Get the list of files, if any, from our directory
Dim ListOfFiles() As FileInfo = Folder.GetFiles()
' If this is a new cleaning order,
' get ready to create a name for the file
If IsNewCleaningOrder = True Then
' If there is no file in the directory,
' then we will use 1000 as the first file name
If ListOfFiles.Length = 0 Then
iFilename = 1000
Else ' If there was at least one file in the directory
' Get a reference to the last file
Dim LastFile As FileInfo = ListOfFiles(ListOfFiles.Length - 1)
' Get the name of the last file without its extension
Dim fwe As String = Path.GetFileNameWithoutExtension(LastFile.FullName)
' Increment the name of the file by 1
iFilename = CInt(fwe) + 1
End If
' Update our global name of the file
Filename = FolderName & "\" & CStr(iFilename)& ".gcs"
txtReceiptNumber.Text = iFilename.ToString()
IsNewCleaningOrder = False
' If a cleaning order was already opened, we will simply update it
Else
Filename = "C:\Georgetown Dry Cleaner\Receipts\" & _
txtReceiptNumber.Text & ".gcs"
End If
Dim stmGCS As StreamWriter = New StreamWriter(Filename)
Try
stmGCS.WriteLine(txtCustomerName.Text)
stmGCS.WriteLine(txtCustomerPhone.Text)
stmGCS.WriteLine(dtpDateLeft.Value.ToString("D"))
stmGCS.WriteLine(dtpTimeLeft.Value.ToString("t"))
stmGCS.WriteLine(dtpDateExpected.Value.ToString("D"))
stmGCS.WriteLine(dtpTimeExpected.Value.ToString("t"))
stmGCS.WriteLine(cbxStatus.Text)
stmGCS.WriteLine(dtpDatePickedUp.Value.ToString("D"))
stmGCS.WriteLine(dtpTimePickedUp.Value.ToString("t"))
stmGCS.WriteLine(txtUnitPriceShirts.Text)
stmGCS.WriteLine(txtQuantityShirts.Text)
stmGCS.WriteLine(txtSubTotalShirts.Text)
stmGCS.WriteLine(txtUnitPricePants.Text)
stmGCS.WriteLine(txtQuantityPants.Text)
stmGCS.WriteLine(txtSubTotalPants.Text)
stmGCS.WriteLine(cbxItem1.Text)
stmGCS.WriteLine(txtUnitPriceItem1.Text)
stmGCS.WriteLine(txtQuantityItem1.Text)
stmGCS.WriteLine(txtSubTotalItem1.Text)
stmGCS.WriteLine(cbxItem2.Text)
stmGCS.WriteLine(txtUnitPriceItem2.Text)
stmGCS.WriteLine(txtQuantityItem2.Text)
stmGCS.WriteLine(txtSubTotalItem2.Text)
stmGCS.WriteLine(cbxItem3.Text)
stmGCS.WriteLine(txtUnitPriceItem3.Text)
stmGCS.WriteLine(txtQuantityItem3.Text)
stmGCS.WriteLine(txtSubTotalItem3.Text)
stmGCS.WriteLine(cbxItem4.Text)
stmGCS.WriteLine(txtUnitPriceItem4.Text)
stmGCS.WriteLine(txtQuantityItem4.Text)
stmGCS.WriteLine(txtSubTotalItem4.Text)
stmGCS.WriteLine(txtCleaningTotal.Text)
stmGCS.WriteLine(txtTaxRate.Text)
stmGCS.WriteLine(txtTaxAmount.Text)
stmGCS.WriteLine(txtNetPrice.Text)
Finally
stmGCS.Close()
End Try
End Sub
|
- Under the above End Sub line, implement an event as follows:
Private Sub ControlLeave(ByVal Sender As Object, ByVal e As EventArgs) _
Handles txtUnitPriceShirts.Leave, _
txtUnitPricePants.Leave, _
txtUnitPriceItem1.Leave, _
txtUnitPriceItem2.Leave, _
txtUnitPriceItem3.Leave, _
txtUnitPriceItem4.Leave, _
txtQuantityShirts.Leave, _
txtQuantityPants.Leave, _
txtQuantityItem1.Leave, _
txtQuantityItem2.Leave, _
txtQuantityItem3.Leave, _
txtQuantityItem4.Leave, _
txtTaxRate.Leave
Dim UnitPriceShirts As Double
Dim UnitPricePants As Double
Dim UnitPriceItem1 As Double
Dim UnitPriceItem2 As Double
Dim UnitPriceItem3 As Double
Dim UnitPriceItem4 As Double
Dim SubTotalShirts As Double
Dim SubTotalPants As Double
Dim SubTotalItem1 As Double
Dim SubTotalItem2 As Double
Dim SubTotalItem3 As Double
Dim SubTotalItem4 As Double
Dim QuantityShirts As Integer = 1
Dim QuantityPants As Integer = 1
Dim QuantityItem1 As Integer = 1
Dim QuantityItem2 As Integer = 1
Dim QuantityItem3 As Integer = 1
Dim QuantityItem4 As Integer = 4
Dim CleaningTotal As Double
Dim TaxRate As Double
Dim TaxAmount As Double
Dim NetPrice As Double
' Retrieve the unit price of this item
' Just in case the user types an invalid value,
' we are using a try...catch
Try
unitPriceShirts = CDbl(txtUnitPriceShirts.Text)
Catch Exc As FormatException
MsgBox("The value you entered for the price of " & _
"shirts is not valid" & _
vbCrLf & "Please try again")
Exit Sub
End Try
' Retrieve the number of this item
' Just in case the user types an invalid value,
' we are using a try...catch
Try
QuantityShirts = CInt(txtQuantityShirts.Text)
Catch Exc As FormatException
MsgBox("The value you entered for the number of " & _
"shirts is not valid" & _
vbCrLf & "Please try again")
Exit Sub
End Try
Try
UnitPricePants = CDbl(txtUnitPricePants.Text)
Catch Exc As FormatException
MsgBox("The value you entered for the price of " & _
"pants is not valid" & _
vbCrLf & "Please try again")
Exit Sub
End Try
Try
QuantityPants = CInt(txtQuantityPants.Text)
Catch Exc As FormatException
MsgBox("The value you entered for the number of " & _
"pants is not valid" & _
vbCrLf & "Please try again")
Exit Sub
End Try
If (cbxItem1.Text = "None") Or (cbxItem1.Text = "") Then
QuantityItem1 = 0
UnitPriceItem1 = 0.0
Else
Try
UnitPriceItem1 = CDbl(txtUnitPriceItem1.Text)
Catch Exc As FormatException
MsgBox("The value you entered for the price is not valid" & _
vbCrLf & "Please try again")
Exit Sub
End Try
Try
QuantityItem1 = CInt(txtQuantityItem1.Text)
Catch Exc As FormatException
MsgBox("The value you entered is not valid" & _
vbCrLf & "Please try again")
Exit Sub
End Try
End If
If (cbxItem2.Text = "None") Or (cbxItem2.Text = "") Then
QuantityItem2 = 0
UnitPriceItem2 = 0.0
Else
Try
UnitPriceItem2 = CDbl(txtUnitPriceItem2.Text)
Catch Exc As FormatException
MsgBox("The value you entered for " & _
"the price is not valid" & _
vbCrLf & "Please try again")
Exit Sub
End Try
Try
QuantityItem2 = CInt(txtQuantityItem2.Text)
Catch Exc As FormatException
MsgBox("The value you entered is not valid" & _
vbCrLf & "Please try again")
Exit Sub
End Try
End If
If (cbxItem3.Text = "None") Or (cbxItem3.Text = "") Then
QuantityItem3 = 0
UnitPriceItem3 = 0.0
Else
Try
UnitPriceItem3 = CDbl(txtUnitPriceItem3.Text)
Catch Exc As FormatException
MsgBox("The value you entered for the " & _
"price is not valid" & _
vbCrLf & "Please try again")
Exit Sub
End Try
Try
QuantityItem3 = CInt(txtQuantityItem3.Text)
Catch Exc As FormatException
MsgBox("The value you entered is not valid" & _
vbCrLf & "Please try again")
Exit Sub
End Try
End If
If (cbxItem4.Text = "None") Or (cbxItem4.Text = "") Then
QuantityItem4 = 0
UnitPriceItem4 = 0.0
Else
Try
UnitPriceItem4 = CDbl(txtUnitPriceItem4.Text)
Catch Exc As FormatException
MsgBox("The value you entered for the price is not valid" & _
vbcrlf & "Please try again")
Exit Sub
End Try
Try
QuantityItem4 = CInt(txtQuantityItem4.Text)
Catch Exc As FormatException
MsgBox("The value you entered is not valid" & _
vbcrlf & "Please try again")
Exit Sub
End Try
End If
' Calculate the sub-total for this item
SubTotalShirts = QuantityShirts * unitPriceShirts
SubTotalPants = QuantityPants * UnitPricePants
SubTotalItem1 = QuantityItem1 * UnitPriceItem1
SubTotalItem2 = QuantityItem2 * UnitPriceItem2
SubTotalItem3 = QuantityItem3 * UnitPriceItem3
SubTotalItem4 = QuantityItem4 * UnitPriceItem4
' Calculate the total based on sub-totals
CleaningTotal = SubTotalShirts + SubTotalPants + SubTotalItem1 + _
SubTotalItem2 + SubTotalItem3 + SubTotalItem4
TaxRate = CDbl(txtTaxRate.Text)
' Calculate the amount owed for the taxes
TaxAmount = cleaningTotal * TaxRate / 100
' Add the tax amount to the total order
NetPrice = cleaningTotal + TaxAmount
' Display the sub-total in the corresponding text box
txtSubTotalShirts.Text = FormatNumber(SubTotalShirts)
txtSubTotalPants.Text = FormatNumber(SubTotalPants)
txtSubTotalItem1.Text = FormatNumber(SubTotalItem1)
txtSubTotalItem2.Text = FormatNumber(SubTotalItem2)
txtSubTotalItem3.Text = FormatNumber(SubTotalItem3)
txtSubTotalItem4.Text = FormatNumber(SubTotalItem4)
txtCleaningTotal.Text = FormatNumber(CleaningTotal)
txtTaxAmount.Text = FormatNumber(TaxAmount)
txtNetPrice.Text = FormatNumber(NetPrice)
SaveCleaningOrder()
End Sub
|
- In the Class Name combo box, select mnuFileSave
- In the Method Name combo box, select Click and implement the event as follows:
Private Sub mnuFileSave_Click(ByVal sender As Object, _
ByVal e As System.EventArgs) _
Handles mnuFileSave.Click
SaveCleaningOrder()
End Sub
|
- Execute the application
- Create a cleaning order

- Click New and create a few more cleaning orders

- Close the form and return to your programming environment
Before exploring the contents of a file, you must first
open. To open a file using the File class, you can call its Open
method that is overloaded with three versions. If the information in the file is
raw text, you can call the OpenText() method. After opening a file, you
can read its content.
To support the ability to read from a file, you can use the StreamReader
class. The StreamReader class is derived from the TextReader class.
When using it, you can start by opening the file. To do this, declare a variable
of type StreamReader and use one of its constructor to specify the name of, or
the path to, the file. To read information from the file, you can call its Read()
or its ReadLine() method. Here is an example:
Private Sub btnOpen_Click(ByVal sender As Object, _
ByVal e As System.EventArgs) _
Handles btnOpen.Click
Dim stmReader As StreamReader = New StreamReader(txtOpen.Text)
txtFirstName.Text = stmReader.ReadLine()
txtLastName.Text = stmReader.ReadLine()
dtpDateHired.Value = DateTime.Parse(stmReader.ReadLine())
cbxGenders.Text = stmReader.ReadLine()
txtHourlySalary.Text = stmReader.ReadLine()
stmReader.Close()
End Sub
Instead of StreamReader, you can use the BinaryReader
class to read information from a file.
|
Practical
Learning: Reading From a File
|
|
- In the Class Name combo box, select mnuFileOpen
- In the Method Name combo box, select Click and implement the event as follows:
Private Sub mnuFileOpen_Click(ByVal sender As Object, _
ByVal e As System.EventArgs) _
Handles mnuFileOpen.Click
If txtReceiptNumber.Text = "" Then
Exit Sub
Else
Try
IsNewCleaningOrder = False
Filename = "C:\Georgetown Dry Cleaner\Receipts\" & _
txtReceiptNumber.Text & ".gcs"
Dim rdrGCS As StreamReader = New StreamReader(Filename)
Try
txtCustomerName.Text = rdrGCS.ReadLine()
txtCustomerPhone.Text = rdrGCS.ReadLine()
dtpDateLeft.Value = DateTime.Parse(rdrGCS.ReadLine())
dtpTimeLeft.Value = DateTime.Parse(rdrGCS.ReadLine())
dtpDateExpected.Value = DateTime.Parse(rdrGCS.ReadLine())
dtpTimeExpected.Value = DateTime.Parse(rdrGCS.ReadLine())
cbxStatus.Text = rdrGCS.ReadLine()
dtpDatePickedUp.Value = DateTime.Parse(rdrGCS.ReadLine())
dtpTimePickedUp.Value = DateTime.Parse(rdrGCS.ReadLine())
txtUnitPriceShirts.Text = rdrGCS.ReadLine()
txtQuantityShirts.Text = rdrGCS.ReadLine()
txtSubTotalShirts.Text = rdrGCS.ReadLine()
txtUnitPricePants.Text = rdrGCS.ReadLine()
txtQuantityPants.Text = rdrGCS.ReadLine()
txtSubTotalPants.Text = rdrGCS.ReadLine()
cbxItem1.Text = rdrGCS.ReadLine()
txtUnitPriceItem1.Text = rdrGCS.ReadLine()
txtQuantityItem1.Text = rdrGCS.ReadLine()
txtSubTotalItem1.Text = rdrGCS.ReadLine()
cbxItem2.Text = rdrGCS.ReadLine()
txtUnitPriceItem2.Text = rdrGCS.ReadLine()
txtQuantityItem2.Text = rdrGCS.ReadLine()
txtSubTotalItem2.Text = rdrGCS.ReadLine()
cbxItem3.Text = rdrGCS.ReadLine()
txtUnitPriceItem3.Text = rdrGCS.ReadLine()
txtQuantityItem3.Text = rdrGCS.ReadLine()
txtSubTotalItem3.Text = rdrGCS.ReadLine()
cbxItem4.Text = rdrGCS.ReadLine()
txtUnitPriceItem4.Text = rdrGCS.ReadLine()
txtQuantityItem4.Text = rdrGCS.ReadLine()
txtSubTotalItem4.Text = rdrGCS.ReadLine()
txtCleaningTotal.Text = rdrGCS.ReadLine()
txtTaxRate.Text = rdrGCS.ReadLine()
txtTaxAmount.Text = rdrGCS.ReadLine()
txtNetPrice.Text = rdrGCS.ReadLine()
Finally
rdrGCS.Close()
End Try
Catch Exc As FileNotFoundException
MsgBox("There is no cleaning order with that receipt number")
End Try
End If
End Sub
|
- Execute the application
- Type 1001 for the receipt number and, on the main menu of the form, click
File -> Open
- Close the form and return to your programming environment
We have mentioned that, on a typical database, the user is
not aware of opening or saving files. In the same way, the user can be spared
with deciding when to save and when not to save data. Whenever possible, most
operations should be performed behind-the-scenes with little to no intervention
from the user. To make this possible, you are in charge of creating the file(s),
receiving data from the user, and then adding that data to the file.
|
Practical
Learning: Opening and Saving Data
|
|
- In the Class Name combo box, select (Central Events)
- In the Method Name combo box, select Load and implement the event as follows:
Private Sub Central_Load(ByVal sender As Object, _
ByVal e As System.EventArgs) _
Handles Me.Load
mnuFileNew_Click(sender, e)
End Sub
|
- Save all
Data input, also referred to as data entry, consists of
entering the values into the application. The user does it mainly using the
keyboard and the mouse. As we reviewed the Windows controls, there are various
types of objects you can use to assist the user. One of the suggestions you
should follow is that you should make the user's job as easy as you can. Because
users of a database are not expected to do any heavy word processing. This means
that typing speed is not among their strongest points. Instead, when choosing
the Windows controls for your application, you should select the most
appropriate one for a particular piece of information.
Data output consists of retrieving information from a
database. Besides opening the objects, such as the forms, that hold the
information of a database, users also regular want to print. In fact, in some
businesses, the customers require to have a printed copy of their transaction.
Therefore, if you are in the habit of neglecting to configuring printing in your
Windows applications, for a database, you should (strongly) loose the habit and
provide your users with the ability to print the data of your application.
If you are creating a file-based application, you can use
the various printing classes of the .NET Framework. Unfortunately, there is no
environment inside the Microsoft Visual Studio 2005 that can assist you to
visually design a report. You must manually draw everything.
|
Practical
Learning: Printing
|
|
- From the Printing section of the Toolbox, click PrintDocument and click
the form
- While the new control is still selected, in the Properties window, click
the Properties button, click (Name), type docPrint and press Enter
- Under the form, double-click docPrint and implement its event as follows:
Private Sub docPrint_PrintPage(ByVal sender As Object, _
ByVal e As System.Drawing.Printing.PrintPageEventArgs) _
Handles docPrint.PrintPage
e.Graphics.DrawLine(New Pen(Color.Black, 2), 60, 90, 720, 90)
e.Graphics.DrawLine(New Pen(Color.Black, 1), 60, 93, 720, 93)
Dim strDisplay As String = "Georgetown Dry Cleaning Services"
Dim fntString As System.Drawing.Font = New Font("Times New Roman", _
28, FontStyle.Bold)
e.Graphics.DrawString(strDisplay, fntString, _
Brushes.Black, 80, 100)
strDisplay = "Customer Cleaning Order"
fntString = New System.Drawing.Font("Times New Roman", 18, _
FontStyle.Bold)
e.Graphics.DrawString(strDisplay, fntString, _
Brushes.Black, 220, 150)
e.Graphics.DrawLine(New Pen(Color.Black, 1), 60, 184, 720, 184)
e.Graphics.DrawLine(New Pen(Color.Black, 2), 60, 188, 720, 188)
fntString = New System.Drawing.Font("Times New Roman", 12, _
FontStyle.Bold)
e.Graphics.DrawString("", fntString, _
Brushes.Black, 80, 200)
fntString = New System.Drawing.Font("Times New Roman", 12, _
FontStyle.Bold)
e.Graphics.DrawString("Customer Identification: ", fntString, _
Brushes.Black, 100, 220)
fntString = New System.Drawing.Font("Times New Roman", 12, _
FontStyle.Regular)
e.Graphics.DrawString(txtCustomerName.Text & " - " & _
txtCustomerPhone.Text, fntString, _
Brushes.Black, 300, 220)
e.Graphics.DrawLine(New Pen(Color.Black, 1), 100, 240, 700, 240)
fntString = New Font("Times New Roman", 12, FontStyle.Bold)
e.Graphics.DrawString("Date Left: ", fntString, _
Brushes.Black, 100, 260)
fntString = New Font("Times New Roman", 12, FontStyle.Regular)
e.Graphics.DrawString(dtpDateLeft.Value.ToString("D"), fntString, _
Brushes.Black, 300, 260)
e.Graphics.DrawLine(New Pen(Color.Black, 1), 100, 280, 700, 280)
fntString = New Font("Times New Roman", 12, FontStyle.Bold)
e.Graphics.DrawString("Time Left: ", fntString, _
Brushes.Black, 500, 260)
fntString = New Font("Times New Roman", 12, FontStyle.Regular)
e.Graphics.DrawString(dtpTimeLeft.Value.ToString("t"), fntString, _
Brushes.Black, 620, 260)
fntString = New System.Drawing.Font("Times New Roman", _
12, FontStyle.Bold)
e.Graphics.DrawString("Date Expected: ", fntString, _
Brushes.Black, 100, 300)
fntString = New Font("Times New Roman", 12, FontStyle.Regular)
e.Graphics.DrawString(dtpDateExpected.Value.ToString("D"), _
fntString, Brushes.Black, 300, 300)
fntString = New Font("Times New Roman", 12, FontStyle.Bold)
e.Graphics.DrawString("Time Expected: ", fntString, _
Brushes.Black, 500, 300)
fntString = New Font("Times New Roman", 12, FontStyle.Regular)
e.Graphics.DrawString(dtpTimeExpected.Value.ToString("t"), _
fntString, Brushes.Black, 620, 300)
e.Graphics.DrawLine(New Pen(Color.Black, 2), 100, 320, 700, 320)
fntString = New Font("Times New Roman", 12, FontStyle.Bold)
e.Graphics.DrawString("Item Type", _
fntString, Brushes.Black, 140, 350)
e.Graphics.DrawString("Unit Price", _
fntString, Brushes.Black, 300, 350)
e.Graphics.DrawString("Quantity", _
fntString, Brushes.Black, 405, 350)
e.Graphics.DrawString("Sub-Total", _
fntString, Brushes.Black, 500, 350)
e.Graphics.DrawLine(New Pen(Color.Black, 2), 140, 370, 640, 370)
Dim fmtString As StringFormat = New StringFormat
fmtString.Alignment = StringAlignment.Far
e.Graphics.DrawString("Shirts", _
fntString, Brushes.Black, 150, 380)
fntString = New Font("Times New Roman", 12, FontStyle.Regular)
e.Graphics.DrawString(txtUnitPriceShirts.Text, fntString, _
Brushes.Black, 350, 380, fmtString)
e.Graphics.DrawString(txtQuantityShirts.Text, fntString, _
Brushes.Black, 440, 380, fmtString)
e.Graphics.DrawString(txtSubTotalShirts.Text, fntString, _
Brushes.Black, 550, 380, fmtString)
e.Graphics.DrawLine(New Pen(Color.Black, 1), 140, 400, 640, 400)
fntString = New Font("Times New Roman", 12, FontStyle.Bold)
e.Graphics.DrawString("Pants", _
fntString, Brushes.Black, 150, 410)
fntString = New Font("Times New Roman", 12, FontStyle.Regular)
e.Graphics.DrawString(txtUnitPricePants.Text, fntString, _
Brushes.Black, 350, 410, fmtString)
e.Graphics.DrawString(txtQuantityPants.Text, fntString, _
Brushes.Black, 440, 410, fmtString)
e.Graphics.DrawString(txtSubTotalPants.Text, fntString, _
Brushes.Black, 550, 410, fmtString)
e.Graphics.DrawLine(New Pen(Color.Black, 1), 140, 430, 640, 430)
fntString = New Font("Times New Roman", 12, FontStyle.Bold)
e.Graphics.DrawString(cbxItem1.Text, _
fntString, Brushes.Black, 150, 440)
fntString = New Font("Times New Roman", 12, FontStyle.Regular)
e.Graphics.DrawString(txtUnitPriceItem1.Text, fntString, _
Brushes.Black, 350, 440, fmtString)
e.Graphics.DrawString(txtQuantityItem1.Text, fntString, _
Brushes.Black, 440, 440, fmtString)
e.Graphics.DrawString(txtSubTotalItem1.Text, fntString, _
Brushes.Black, 550, 440, fmtString)
e.Graphics.DrawLine(New Pen(Color.Black, 1), 140, 460, 640, 460)
fntString = New Font("Times New Roman", 12, FontStyle.Bold)
e.Graphics.DrawString(cbxItem2.Text, _
fntString, Brushes.Black, 150, 470)
fntString = New Font("Times New Roman", 12, FontStyle.Regular)
e.Graphics.DrawString(txtUnitPriceItem2.Text, fntString, _
Brushes.Black, 350, 470, fmtString)
e.Graphics.DrawString(txtQuantityItem2.Text, fntString, _
Brushes.Black, 440, 470, fmtString)
e.Graphics.DrawString(txtSubTotalItem2.Text, fntString, _
Brushes.Black, 550, 470, fmtString)
e.Graphics.DrawLine(New Pen(Color.Black, 1), 140, 490, 640, 490)
fntString = New Font("Times New Roman", 12, FontStyle.Bold)
e.Graphics.DrawString(cbxItem3.Text, _
fntString, Brushes.Black, 150, 500)
fntString = New Font("Times New Roman", 12, FontStyle.Regular)
e.Graphics.DrawString(txtUnitPriceItem3.Text, fntString, _
Brushes.Black, 350, 500, fmtString)
e.Graphics.DrawString(txtQuantityItem3.Text, fntString, _
Brushes.Black, 440, 500, fmtString)
e.Graphics.DrawString(txtSubTotalItem3.Text, fntString, _
Brushes.Black, 550, 500, fmtString)
e.Graphics.DrawLine(New Pen(Color.Black, 1), 140, 520, 640, 520)
fntString = New Font("Times New Roman", 12, FontStyle.Bold)
e.Graphics.DrawString(cbxItem4.Text, _
fntString, Brushes.Black, 150, 530)
fntString = New Font("Times New Roman", 12, FontStyle.Regular)
e.Graphics.DrawString(txtUnitPriceItem4.Text, fntString, _
Brushes.Black, 350, 530, fmtString)
e.Graphics.DrawString(txtQuantityItem4.Text, fntString, _
Brushes.Black, 440, 530, fmtString)
e.Graphics.DrawString(txtSubTotalItem4.Text, fntString, _
Brushes.Black, 550, 530, fmtString)
e.Graphics.DrawLine(New Pen(Color.Black, 2), 140, 550, 640, 550)
fntString = New System.Drawing.Font("Times New Roman", 12, _
FontStyle.Bold)
e.Graphics.DrawString("Order Summary", fntString, _
Brushes.Black, 260, 600)
e.Graphics.DrawLine(New Pen(Color.Black, 2), 220, 620, 560, 620)
fntString = New System.Drawing.Font("Times New Roman", _
10, FontStyle.Bold)
e.Graphics.DrawString("Cleaning Total:", fntString, _
Brushes.Black, 260, 630)
fntString = New System.Drawing.Font("Times New Roman", _
10, FontStyle.Regular)
e.Graphics.DrawString(txtCleaningTotal.Text, fntString, _
Brushes.Black, 440, 630, fmtString)
e.Graphics.DrawLine(New Pen(Color.Black, 1), _
220, 650, 520, 650)
fntString = New System.Drawing.Font("Times New Roman", _
10, FontStyle.Bold)
e.Graphics.DrawString("Tax Rate:", fntString, _
Brushes.Black, 260, 660)
fntString = New System.Drawing.Font("Times New Roman", _
10, FontStyle.Regular)
e.Graphics.DrawString(txtTaxRate.Text, fntString, _
Brushes.Black, 440, 660, fmtString)
e.Graphics.DrawLine(New Pen(Color.Black, 1), _
220, 680, 520, 680)
fntString = New System.Drawing.Font("Times New Roman", _
10, FontStyle.Bold)
e.Graphics.DrawString("Tax Amount:", fntString, _
Brushes.Black, 260, 690)
fntString = New System.Drawing.Font("Times New Roman", _
10, FontStyle.Regular)
e.Graphics.DrawString(txtTaxAmount.Text, fntString, _
Brushes.Black, 440, 690, fmtString)
e.Graphics.DrawLine(New Pen(Color.Black, 1), _
220, 710, 520, 710)
fntString = New System.Drawing.Font("Times New Roman", _
10, FontStyle.Bold)
e.Graphics.DrawString("Net Price:", fntString, _
Brushes.Black, 260, 720)
fntString = New System.Drawing.Font("Times New Roman", _
10, FontStyle.Regular)
e.Graphics.DrawString(txtNetPrice.Text, fntString, _
Brushes.Black, 440, 720, fmtString)
e.Graphics.DrawLine(New Pen(Color.Black, 2), _
200, 740, 560, 740)
End Sub
|
- Return to the form
- From the Printing section of the Toolbox, click PrintDialog and click the
form
- In the Properties window, change its Name to dlgPrint
- Still in the Properties windows, set its Document property to docPrint
- On the main menu of the form, click File and double-click Print
- Implement the event as follows:
Private Sub mnuFilePrint_Click(ByVal sender As Object, _
ByVal e As System.EventArgs) _
Handles mnuFilePrint.Click
If dlgPrint.ShowDialog() = DialogResult.OK Then
docPrint.Print()
End If
End Sub
|
- Return to the form
- From the Printing section of the Toolbox, click PrintPreviewDialog and
click the form
- In the Properties window, change its Name to dlgPrintPreview
- Still in the Properties windows, set its Document property to docPrint
- On the main menu of the form, click File and double-click Print Preview
- Implement the event as follows:
Private Sub mnuFilePrintPreview_Click(ByVal sender As Object, _
ByVal e As System.EventArgs) _
Handles mnuFilePrintPreview.Click
dlgPrintPreview.ShowDialog()
End Sub
|
- In the Class Name combo box, select mnuFileExit
- In the Method Name combo box, select Click and implement the event as follows:
Private Sub mnuFileExit_Click(ByVal sender As Object, _
ByVal e As System.EventArgs) _
Handles mnuFileExit.Click
End
End Sub
|
- Execute the application
- Open an existing cleaning order and print preview it

- Close the form and return to your programming environment
- Open the Georgetown Dry Cleaner database from this lesson
- Configure the main form so that, when the user wants to start a new
cleaning order, the compiler would check if the value of any control on the
form has been changed since the order was started, since the order was
opened, or since the last time the order was saved. If any value was
changed, a message box should display to let the user know that the cleaning
order has been modified and ask whether the user wants to save the cleaning
order. If the user answers:
- No: The cleaning order would be kept "as is" and a
new cleaning order would be started
- Yes
- If the user was working on a new order, the current new
one would be saved with a new receipt number
- If the user was working on an order that was previous
opened (for example if the customer was coming to pick up a cleaning
order and the user had updated the order status), simply save the
current cleaning order with its own receipt number
- If the user had previously saved the current cleaning
order, simply save it again with the same receipt number
|
|