Figure 10.11 The vacation planning page, with error.The Employee Information Form Most of your employees will typically want to make sure you have the right tion or occasionally to edit
Trang 1Dim conn As New SqlConnection(CONNSTR) Dim sSQL As String
' Make sure we are using a valid date.
If calStart.SelectedDate() < Now Then lblResult.ForeColor = System.Drawing.Color.Red lblResult.Text = "You must select a date equal to or " & _
"later than today."
Exit Sub End If
' Prepare our INSERT statement that will save the request sSQL = "INSERT INTO VacationRequest (EmpID, StartDate, " & _
"Hours, Approved) " & _
"VALUES (" & eID & ", '" & _ calStart.SelectedDate.ToString() & "', " & _ CInt(tbHours.Text) & ", 0)"
' Attemp the INSERT.
Dim cmd As New SqlCommand(sSQL, conn) Try
conn.Open() cmd.ExecuteNonQuery() conn.Close()
lblResult.ForeColor = System.Drawing.Color.RoyalBlue lblResult.Text = "Vacation request was successfully " & _
"submitted (" & calStart.SelectedDate() & ", " & _
"tbHours.Text & " hours)."
Catch ex As SqlException conn.Close()
lblResult.ForeColor = System.Drawing.Color.Red lblResult.Text = "There was a database error: " & ex.Message() End Try
End Sub
' If the user changes the selection on the calendar, we want
' to make sure it is today or later If not, tell the user.
Private Sub calStart_SelectionChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles calStart.SelectionChanged
' Make sure we are using a valid date.
If calStart.SelectedDate() < Now.Date Then lblResult.ForeColor = System.Drawing.Color.Red lblResult.Text = "You must select a date equal to or " & _
"later than today."
Trang 2Else lblResult.Text = ""
as well as the employee ID once we load it from the database
Then we handle the page load event We start it out by retrieving some employeeinformation from the database, including the employee ID, the first and last names,and the amount of vacation the employee is allotted for the year We’ll use these shortlybecause we need them before we can get any work done We use standard SQL andADO.NET to get the information back Once we get the data back, we fill in the username and total vacation hours on the form
Next we must load all the vacation request records for the user for several reasons.First, we need to iterate through them all, totaling the amount of vacation used thisyear Second, we will hook the list of records up to the DataGrid so that users can seethe history of all their requests We retrieve the vacation date, hours used, andapproval state for all the records that match the employee ID
Once all the records are loaded, we iterate through them using a For Each loop ing the amount of vacation used This is stored in the iUsed class variable After theloop completes, we calculate the amount of vacation remaining and store that Thosevalues are then filled into the form
total-The amount of vacation used is calculated in this application based only on approved hours Any stored requests that are not approved yet
do not count toward the used total This may not suit your needs, and
it is very easy to change Simply remove the condition in the For Each loop that checks the approval status.
If the total amount of vacation used or remaining looks wrong, it’s probably because the unapproved requests were not counted.
The last thing we do in the page load handler is to configure the validator controls
We wait until now because we don’t know the maximum value that should be alloweduntil we calculate the amount of vacation remaining for the employee Once we do, wecan set the MaximumValue property and the error messages, all of which reference thetotal remaining vacation hours
Our next function handles the Submit Request button that indicates that the user issaving a new vacation request We first check to make sure that the date the user hasselected in the calendar is equal to or later than today’s date It does not make sense
to retroactively request vacation If the date is invalid, we tell the user and exit theProcedure
Team-Fly®
Trang 3We handle errors in this application in one of two ways You’ve already seen the validator controls that check input as the user enters it.
However, what do you do if you have an error in the code? You can’t display a message box because you are running on the server I decided to
create a label control called lblResult that initially has no text value and is thus invisible If we encounter an error in the code during a Try Catch construct, we set the text of the label to describe the error and change its color to red
We also use the same label to report that a requested operation succeeded If everything goes well, we set the text to indicate this and change the color to a friendlier blue You can use the same technique anywhere, and we do for each form in the application.
As long as the start date is okay and we have a valid number of hours requested, we
go ahead and attempt to INSERT the request data into the database If all goes well, wetell the user If something goes wrong, we also tell the user And that’s it for saving therequest
Figure 10.10 The vacation planning page in the browser.
Trang 4Figure 10.11 The vacation planning page, with error.
The Employee Information Form
Most of your employees will typically want to make sure you have the right tion or occasionally to edit the information It can save time when employees need toverify their salary or emergency contact if they can do it themselves without having tobother your other staff to get the information So we created this page to allow the user
<meta content="Microsoft Visual Studio.NET 7.0" name="GENERATOR">
<meta content="Visual Basic 7.0" name="CODE_LANGUAGE">
<meta content="JavaScript" name="vs_defaultClientScript">
<meta content="http://schemas.microsoft.com/intellisense/ie5"
name="vs_targetSchema">
Trang 5<LINK href="http://localhost/prj10/Styles.css" type="text/css" rel="stylesheet">
</HEAD>
<body style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0px;
MARGIN: 0px; PADDING-TOP: 0px">
<form id="frmStatus" method="post" runat="server">
<table cellSpacing="5" cellPadding="0" width="700" border="0">
<table style="PADDING-LEFT: 10px" cellSpacing="0"
cellPadding="10" width="700" border="0">
Trang 6<td class="Content" vAlign="middle" align="right"
Trang 8<IMG src="images/bullet1.gif"><A href="default.aspx">
Back to Main Page</A>
<asp:Button id="btnSubmit" runat="server"
Trang 9Table 10.4 The Employee Information Controls
CONTROL NAME PROPERTIES
Button btnSubmit Text=”Save Changes”
Image Image1 ImageURL=”images/EmployeeInfoHdr.jpg”Label lblFirstName Text=””, Font-Bold=True
Label lblLastName Text=””, Font-Bold=True
Label lblSalary Text=””, Font-Bold=True
Label lblTitle Text=””, Font-Bold=True
Label lblDept Text=””, Font-Bold=True
Label lblLogin Text=””, Font-Bold=True
Label lblGender Text=””, Font-Bold=True
Label lblStreet1 Text=””, Font-Bold=True
Label lblStreet2 Text=””, Font-Bold=True
Label lblExt Text=””, Font-Bold=True
Label lblCityStateZip Text=””, Font-Bold=True
Label lblResult Text=””, Font-Bold=True
Label lblHours Text=””, Font-Bold=True
TextBox tbPwd Text=””, Font-Bold=True, TextMode=PasswordTextBox tbContact Text=””, Font-Bold=True
TextBox tbHomePhone Text=””, Font-Bold=True
Trang 10Figure 10.12 The employee information form in the Designer.
We begin the code in our usual fashion, with a database connection string and anyclass data we might need In this case, we need something to keep track of theemployee ID and the password, once we pull them out of the database:
#Region "Class Data and Types "
Private Const CONNSTR As String = "PERSIST SECURITY INFO=False; " & _
"DATA SOURCE=tony; INITIAL CATALOG=prj10; UID=sa; PWD=;"
Private eID As Int32 = 0
Private sPwd As String = ""
#End Region
The Page Load event takes care of loading the employee information and filling itinto the labels on the form Here’s the code:
Private Sub Page_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles MyBase.Load
Dim conn As SqlConnection = New SqlConnection(CONNSTR)
Dim sSQL As String
Dim s As String
Trang 11' The SQL for retrieving the Employee ID based on ' the login ID from the Session.
sSQL = "SELECT Employee.EmpID FROM Employee " & _
"WHERE Employee.LoginID = '" & Session("UserID") & "'"
' Get our data objects ready for retrieval.
Dim da As SqlDataAdapter = New SqlDataAdapter(sSQL, conn) Dim ds As DataSet = New DataSet()
Dim ds2 As New DataSet() Dim theRow As DataRow
' Load the employee ID.
Try conn.Open() da.Fill(ds, "employee") theRow = ds.Tables(0).Rows(0) eID = theRow("EmpID")
Catch ex As SqlException conn.Close()
lblResult.ForeColor = System.Drawing.Color.Red lblResult.Text = "There was a database error: " & ex.message() Exit Sub
End Try
' Load the initial employee information we'll need on this page ' A little complex, but it works.
sSQL = "SELECT Employee.EmpID, Employee.FirstName, " & _
"Employee.LastName, Employee.Title, " & _
"Department.DeptName, Employee.Gender, " & _
"Address.Street1, Address.Street2, Address.City, " & _
"Address.State, Address.Zip, Employee.HomePhone, " & _
"Employee.Extension, Employee.SalaryAnnual, " & _
"Employee.VacationHoursAnnual, " & _
"Employee.EmergencyContact, Employee.Password " & _
"FROM Employee INNER JOIN " & _
"Department ON Employee.DeptID = Department.DeptID " & _
"INNER JOIN " & _
"Address ON Employee.AddressID = Address.AddressID " & _
"WHERE (Employee.LoginID = '" & Session("UserID") & "')"
da.SelectCommand.CommandText = sSQL
' Load the employee data.
If Not (Page.IsPostBack) Then
Try da.Fill(ds2, "employeeinfo") conn.Close()
Catch ex As SqlException conn.Close()
lblResult.ForeColor = System.Drawing.Color.Red lblResult.Text = "There was a database error: " & _ ex.message()
Exit Sub End Try
Trang 12' Fill in the fields on the form.
Dim aRow As DataRow
If ds2.Tables(0).Rows.Count > 0 Then ' First column
aRow = ds2.Tables(0).Rows(0) lblFirstName.Text = aRow("FirstName") lblLastName.Text = aRow("LastName") lblTitle.Text = aRow("Title") lblDept.Text = aRow("DeptName") lblGender.Text = aRow("Gender") lblHomePhone.Text = aRow("HomePhone") lblExt.Text = aRow("Extension") ' Second column
lblSalary.Text = CStr(aRow("SalaryAnnual")) lblHours.Text = CStr(aRow("VacationHoursAnnual")) lblContact.Text = aRow("EmergencyContact")
lblLogin.Text = Session("UserID") lblStreet1.Text = aRow("Street1")
If Not (aRow("Street2") Is System.DBNull.Value) Then lblStreet2.Text = aRow("Street2")
End If lblCityStateZip.Text = aRow("City") & ", " & _ aRow("State") & " " & aRow("Zip")
sPwd = aRow("Password") Else
lblResult.ForeColor = System.Drawing.Color.Red lblResult.Text = "No information was found for " & _
"login ID" & Session("UserID") & "."
End If Else conn.Close() End If
End Sub
We go through the usual routine of loading the employee ID from the database tobegin with We’ll need it for other database operations later So we get it and save it in
a class variable, eID
Next we load the employee data This pulls back a large number of columns fromthree different tables and results in a large and complex-looking SQL SELECT state-ment The only complex parts are the two INNER JOINs we use to pull out actual val-ues from the Department and Address tables Without the JOINs, we would have onlymeaningless IDs to display for the employee Beyond that, the loading of the data isperfectly normal
We’re all used to checking for null values returned from the database.
We do it the way VB taught us to However, this is a little different
in Visual Basic NET We need to make use of a class in the NET framework called DBNull and one of its properties, Value To check a value for null, do it like this:
If Row("Street2") Is System.DBNull.Value Then
Team-Fly®
Trang 13Once we have the data, we need to stuff it into the form Each column of data in thereturned row is used to populate a label control on the form That’s all there is to thePage Load event However, we also allow users to make changes to three of the fields
on the form We need to make sure that there are valid values there and to actually savethe changes to the database using a SQL UPDATE statement Here is the code we’ll bereferring to:
' Handle a click on the Save Changes button.
Private Sub btnSubmit_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles btnSubmit.Click
Dim conn As New SqlConnection(CONNSTR) Dim sSQL As String
Dim s As String
' Make sure that something actually exists in the ' the three edit fields.
If Len(tbHomePhone.Text) = 0 Then lblResult.ForeColor = System.Drawing.Color.Red lblResult.Text = "You must enter a value for Home Phone." Exit Sub
End If
If Len(tbPwd.Text) = 0 Then lblResult.ForeColor = System.Drawing.Color.Red lblResult.Text = "You must enter a value for Password." Exit Sub
End If
If Len(tbContact.Text) = 0 Then lblResult.ForeColor = System.Drawing.Color.Red lblResult.Text = "You must enter a value for " & _
"Emergency Contact."
Exit Sub End If
' Take care of any single quotes in the contact text field.
s = tbContact.Text.Replace("'", "''")
' Prepare our UPDATE statement to save the data.
sSQL = "UPDATE Employee SET HomePhone='" & _ tbHomePhone.Text & "', " & _
"EmergencyContact = '" & tbContact.Text & "', " & _
"Password = '" & tbPwd.Text & "' " & _
"WHERE EmpID = " & CStr(eID)
' Attempt the update.
Dim cmd As New SqlCommand(sSQL, conn) Try
conn.Open() cmd.ExecuteNonQuery() conn.Close()
Trang 14lblResult.ForeColor = System.Drawing.Color.RoyalBlue lblResult.Text = "Employee information was " & _
"successfully updated."
Catch ex As SqlException
conn.Close() lblResult.ForeColor = System.Drawing.Color.Red lblResult.Text = "There was a database error: " & ex.Message() End Try
End Sub
The first part of the button click handler makes sure that we have values of somesort in each of the text boxes If those all pass, we attempt to save the changes using anUPDATE Whatever the results, success or failure, we tell the user how it went Thisform was not complicated; it just looks that way due to the amount of data on the page
Try It Out
Run the application and access the employee information page Once the page is played, verify that the correct data is being loaded for the particular user you areimpersonating Try out the update for a field or two to make sure it works The form isshown executing in the browser in Figure 10.13
dis-Figure 10.13 The employee information form in the browser.
Trang 15Figure 10.14 The status report form in the Designer.
The Status Report Form
The status report form is probably the simplest in the application It has a couple textfields to accept and display status report information, and a button to save it That’s it!Take a look at Figure 10.14 to see what it looks like sitting in the Designer The controlsare listed in Table 10.5
Table 10.5 The Status Report Controls
CONTROL NAME PROPERTIES
Button btnSubmit Text=”Submit Report”
Image Image1 ImageURL=”images/StatusRptHdr.jpg”
Label lblResult Text=””, ForeColor=RoyalBlue
TextBox tbNew Text=””, Width=340px, Height=250px,
MaxLength=4096, Rows=1, TextMode=MultiLineTextBox tbOld Text=””, Width=340px, Height=250px,
MaxLength=4096, Rows=1, TextMode=MultiLine
Trang 16Even the HTML is much shorter than the other pages we’ve dealt with in this cation Again, this is due to the smaller number of controls and a layout that is not ascomplex Take a look at it and you’ll see what I mean:
appli-<%@ Page Language="vb" AutoEventWireup="false"
Codebehind="prj10status.aspx.vb" Inherits="prj10.prj10status"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<title>Vulture Corp - Status Reports</title>
<meta name="GENERATOR" content="Microsoft Visual Studio.NET 7.0">
<meta name="CODE_LANGUAGE" content="Visual Basic 7.0">
<meta name="vs_defaultClientScript" content="JavaScript">
<form id="frmStatus" method="post" runat="server">
<table cellSpacing="5" cellPadding="0" width="700" border="0"
Enter a new status report here if your department requires
it You can also review previous status reports.
<asp:TextBox id="tbNew" runat="server" Width="337px"
Height="250px" MaxLength="4096" Rows="1"
Trang 17<img src="images/bullet1.gif"><a href="default.aspx">
Back to Main Page</a>
<asp:TextBox id="tbOld" runat="server" Width="340px"
Height="250px" Rows="1" TextMode="MultiLine"></asp:TextBox>
#Region "Class Data and Types "
Private Const CONNSTR As String = "PERSIST SECURITY INFO=False; " & _
"DATA SOURCE=tony; INITIAL CATALOG=prj10; UID=sa; PWD=;"
Private eID As Int32 = 0
#End Region
Our Page Load event does its usual job: load the employee ID and the data to tially display on the page We have to actually build the contents of the existing statusreports Take a look at the code:
ini-Private Sub Page_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles MyBase.Load
Dim conn As SqlConnection = New SqlConnection(CONNSTR) Dim sSQL As String
Dim s As String
' Load the initial employee information we'll need on this page sSQL = "SELECT EmpID FROM Employee WHERE LoginID='" & _
"Session("UserID") & "'"
Trang 18' Get our data objects ready for retrieval.
Dim da As SqlDataAdapter = New SqlDataAdapter(sSQL, conn)
Dim ds As DataSet = New DataSet()
Dim ds2 As New DataSet()
Dim theRow As DataRow
' Load the employee ID.
If Not (Page.IsPostBack) Then
' Now load the matching status report records.
sSQL = "SELECT RptDate, StatusText FROM StatusReport " & _
"WHERE EmpID=" & CStr(eID) & " ORDER BY RptDate DESC" da.SelectCommand.CommandText = sSQL
' Loop through each record and build the string
' for display in the textbox.
Dim aRow As DataRow
If ds2.Tables(0).Rows.Count > 0 Then
For Each aRow In ds2.Tables(0).Rows
s &= "Date: " & aRow("RptDate") & vbCrLf & _
Trang 19Once all of the status reports have been loaded into a DataSet, we iterate throughthem and build a single string that can be displayed in the large text box We do a littleformatting along the way to make the whole thing more readable Once this is done theform is displayed.
The only other thing our page (and at this point, our application) needs to do is save
a new status report Users can enter any text they like in the left text box and click theSubmit Report button to save it The code that handles this follows:
' This button click handler will save any new status report
' text in the database.
Private Sub btnSubmit_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles btnSubmit.Click
Dim conn As New SqlConnection(CONNSTR) Dim sSQL As String
Dim s As String
' Make sure there's something in the text box to save.
If Len(tbNew.Text) = 0 Then lblResult.ForeColor = System.Drawing.Color.Red lblResult.Text = "You must enter something before your " & _
"report can be submitted."
Exit Sub End If
' Make sure any single quotes are properly handled.
s = tbNew.Text.Replace("'", "''")
' Prepare our INSERT statement using data from the UI.
sSQL = "INSERT INTO StatusReport (EmpID, RptDate, StatusText)" & _
" VALUES (" & eID & ", '" & Now.ToString() & "', '" & _
s & "')"
' Attempt to save the data.
Dim cmd As New SqlCommand(sSQL, conn) Try
conn.Open() cmd.ExecuteNonQuery() conn.Close()
lblResult.ForeColor = System.Drawing.Color.RoyalBlue lblResult.Text = "Status report was successfully " & _
"submitted (" & Now & ")."
Catch ex As SqlException conn.Close()
Trang 20lblResult.ForeColor = System.Drawing.Color.Red lblResult.Text = "There was a database error: " & ex.Message() End Try
End Sub
We check to make sure that there is actually something in the text box control, and ifthere is, we try to insert it into the database We let the user know how it went byupdating the results label on the form
Try It Out
Take this form for a test drive Log in as someone who has a few reports and see thatthey are returned properly, newest to oldest, as dictated by the ORDER BY clause weused Enter a new status report and save it The next time you come back to the form,the new one will be reported on the right Figure 10.15 shows the form running in thebrowser
Figure 10.15 The status report form in the browser.
Trang 21Enhancing the Project
This project illustrated how to pull several NET technologies together to create a world application You could use similar techniques to build any application thatstrikes you as interesting
real-Although this is a sizeable project, there are plenty of things you could do beyondjust adding new features for your employees to use:
Site and data management. Add a page or two to help you manage the site tents For example, you will want to be able to manage the information in thedatabase that employees have no access to, such as adding new employees anddepartments
con-Approval of vacation. Vacation requests can be submitted, but how do they getapproved? You could start by adding manager information to the database andassociating employees with that manager Then create a page that would allowmanagers to approve vacation requests for the employees associated with them.You could do this with a fairly simple Web form
Review status reports. Like vacation requests, status reports must be reviewed
by managers Create a page that would allow managers to look at the statusreports for all the employees associated with them You could optionally create aspecial page that managers use to create their status reports It would show allthe reports of the employees associated with them so that they could reviewtheir department status as they write their own reports Or is this making lifetoo easy for managers?
Edit addresses. Change the employee information page to allow editing of users’addresses This would be handy for employees but was left out of the projectdue to space considerations The update SQL would have to be changed quite abit, though, to handle the related table
THAT’S IT
I hope that you see incredible success and fun in the world of NET and Visual Basic NET!
I know I had a blast writing all these programs and learning about all the new goodies along the way .NET is very powerful, and my number one priority is to get my company to move to it This initiative has purely selfish motivations, however I will find it very
difficult to go back to VB6 after all this.
Thanks for coming, and have a wonderful time with NET!
Trang 22The CD-ROM that accompanies this book contains all the source code for all the jects It also contains any supporting files you might need, including images, solutionfiles, image files, and sample databases Whenever possible, the structure of the direc-tories and files for the project have been maintained as needed so that they may beloaded directly into Visual Studio
pro-The disc is organized by project pro-The main directory is called Projects, and each ect is contained underneath the main directory For example, the code for project 5 isstored in a directory structure like this:
proj-Projects\Project 5
Using the CD-ROM
The CD-ROM has a Web browser interface that allows you to view information aboutthe projects, access the code, and see what else is on there It should start automaticallywhen you insert the CD-ROM into the drive If it does not, simply open the file
index.htm in the root directory.
A Free Utility?
There is a small utility on the CD-ROM in the root called autorunit.exe It allows you to
pass a command line document to it which it will then launch We use it to implement
What’s on the CD-ROM?
A P P E N D I X
Team-Fly®