1
All Powder Board and Ski
SQL Server WorkbookChapter 6: Forms, Reports, and ApplicationsJerry PostCopyright © 2003
2
Form Types
Style Style Description CategoryCustomer
Last NameFirst NamePhoneAddressCity
Ski Board Style
Sale
Customer Salesperson
ItemID Description Price Quantity Value
Main
Grid
Main and
Subform
3
Customer Main Form
Record navigation
Text box
Label
4
Action
ActionRight-click the project, Add/Add New Item.Choose the Data Form Wizard.Enter the name Customer.vbCreate a new connection if necessary.Move the Customer table to the right.Make sure all Columns are checked.Select option to display a single record.Fix the page layout.Add a button to the main form to open the Customer form with code.Test! If necessary, add password to the connection string.
5
Main Form Wizard
Select table
Add/Add New ItemData Form Wizard
6
Display Style
Main form
7
Design View
Properties
Database connectionToolbox
8
Visual Studio Form Structure
Form
Dataset:
Customer
Order
LastName
FirstName
OrderID
OrderDate
Database
Data Adapter (Order)
Fill/Load
Update
Data Adapter (Customer)
Fill/Load
Update
9
Action
Action
Double-click the Load button.
Copy the code inside the subroutine.
At the top of the code page, expand the region created by the designer.
Find the New subroutine at the top.
Find the comment ‘Add any initialization
Paste the code after that comment.
Save and test the form.
Delete the Load button and its code.
10
Form Triggers
Paste the code from the Load event
Start button
11
Action
ActionDelete the text box for Gender.Drag a combo box from the ToolBox.Expand the Property window.Name it cboGender.Delete any entry in the Text property.In Items, enter Male, Female, Unidentified.Expand the DataBindings property.For Text and SelectedValue, expand and pick objdsCustomer – Gender.Save and test the form.Set the Tab Index for all controls.
12
Combo Box and Data Binding
Combo Box
Data Binding
13
Initial Grid Form
14
Action
ActionAdd a new form with Add/Add New and the Data Form Wizard.Create a new dataset (dsSkiBoardStyle).Use the existing connection.Select the Grid layout.Add the password to the ConnectionString.Copy the code from the Load button to the New event.Add a new button to the Main form.Add the code to open the new form.Save everything and test the form.
15
Create the Grid Form
Grid Form
16
Private Sub SetGridStyles() ' To control the grid layout and format you need a DataGridTableStyle Dim tableStyle As New DataGridTableStyle tableStyle.MappingName = "SkiBoardStyle" ' The table name
' Create a DataGridColumnStyle for each column Dim colStyle As New DataGridTextBoxColumn colStyle.MappingName = "Style" colStyle.HeaderText = "Style" colStyle.Width = 135 tableStyle.GridColumnStyles.Add(colStyle) ‘ Put the StyleDescription Column here
Dim colStyleCategory As New DataGridTextBoxColumn colStyleCategory.MappingName = "Category" colStyleCategory.HeaderText = "Category" colStyleDescription.Width = 100 tableStyle.GridColumnStyles.Add(colStyleCategory) ' Add the tableStyle to the grid Me.grdSkiBoardStyle.TableStyles.Add(tableStyle) End Sub
Grid Column Layouts
Define the style for each column in the order you want displayed
Create the style
Add the style to the grid
17
Action
ActionOpen the code behind the form and create a new subroutine.Copy the code from the example to create a table style and each column style.In the form’s New event under initialization, call the new subroutine.Test the code and debug it.
18
Add a Data Adapter for Lookup List
SQL Data Adapter
Create query
Advanced options
19
Properties for Lookup Data Grid
Name grdCategory
DataSource dsProductCategory1
DataMember ProductCategory
CaptionVisible False
ColumnHeadersVisible False
PreferredColumnWidth 75
RowHeaderWidth 0
ReadOnly True
Locked True
Visible False
20
Code for Lookup List: Startup
#Region " Windows Form Designer generated code " Public Sub New() MyBase.New() 'This call is required by the Windows Form Designer. InitializeComponent() 'Add any initialization after the InitializeComponent() call Try 'Attempt to load the dataset. Me.LoadDataSet() Me.SqlDataAdapter1.Fill(Me.DsProductCategory1) grdCategory.Visible = False Catch eLoad As System.Exception 'Add your error handling code here. 'Display error message, if any. System.Windows.Forms.MessageBox.Show(eLoad.Message) End Try SetGridStyles() End Sub
21
Lookup Code: Main GridConst iColCategory = 2 ' Column for drop down listPrivate row As IntegerPrivate col As IntegerPrivate Sub grdSkiBoardStyle_CurrentCellChanged( _
ByVal sender As Object, ByVal e As System.EventArgs) _ Handles grdSkiBoardStyle.CurrentCellChanged
Dim cell As DataGridCell = grdSkiBoardStyle.CurrentCellIf (cell.ColumnNumber <> iColCategory) Then
grdCategory.Visible = FalseExit Sub ' Only care about last column
End Ifrow = grdSkiBoardStyle.CurrentRowIndexcol = cell.ColumnNumberDim rect As Rectangle = grdSkiBoardStyle.GetCellBounds(row, col)Dim tb As DataGridTextBox = grdSkiBoardStyle.Controls(2)tb.BackColor = System.Drawing.Color.BluegrdCategory.Left = rect.Left + grdSkiBoardStyle.LeftgrdCategory.Top = rect.Bottom + grdSkiBoardStyle.TopgrdCategory.Visible = True
End Sub
22
Lookup Code: Category Grid
Private Sub grdCategory_Click( _ByVal sender As Object, ByVal e As System.EventArgs) _Handles grdCategory.Click
Dim tb As DataGridTextBox = grdCategory.Controls(2)Me.objdsSkiBoardStyle.Tables("SkiBoardStyle"). _
Rows(row)(iColCategory) = tb.TextgrdCategory.Visible = False
End Sub
23
Action
ActionAdd a SQLDataAdapter to the form.Retrieve the data from the ProductCategory table and uncheck the UPDATE option.Right-click the adapter to create a new dataset: dsProductCategory.Add a new data grid to the form and size it.Set the data grid properties. Add initialization code to load the dataset.Add subroutine to display the lookup list.Add subroutine to transfer data from the lookup list to the main dataset.
24
Grid with Lookup
User clicks left of row to select.
25
Main/Subform by Sale
The Data Form Wizard uses relationships to handle Parent and Child tables.
26
Action
ActionCreate a new form with the Data Form Wizard.Add a new dataset with the existing connection.Choose the Sale and SaleItem tables.Create a parent child relationship with the SaleID column.Choose all columns except the SaleID in the SaleItem table.Select the single row option for the main form.Add the password to the ConnectionString.Move the Load button code to the New sub.Save and test the form.
27
Initial Form Design
Sale form
SaleItem grid
28
Dataset Designer to Add Column
Add the Value column as an Element with the decimal data type
29
Action
ActionOpen the dsSale.xsd dataset.Add an Element called Value with a decimal data type.Add the new column to the data grid with the TableStyles and GridColumnStyles properties.Name: objColumnStylegrdSaleItemValueAlignment: RightFormat: 0.00MappingName: ValueReadOnly: TrueAdd the expression code.Call the expression code from the New subroutine.
30
Subform Value Column in Grid
Open the TableStyles
Open the columns
Add a column
Set the properties
31
Expression Code
Public Sub CreateValueExpression()Dim tbl As DataTable = Me.objdsSale.Tables("SaleItem")Dim col As DataColumn = tbl.Columns("Value")col.Expression = "SalePrice*QuantitySold"
End Sub
Public Sub New()Try
'Attempt to load the dataset. Me.LoadDataSet() CreateValueExpression() Catch eLoad As System.Exception 'Add your error handling code here.End Try Me.objdsSale_PositionChanged() End Sub
32
Action
Action
Copy and paste the SalePrice column in the subform to create a Value column
Assign properties so that it multiplies SalePrice by QuantitySold
Copy and paste this new column to create a subtotal column
Assign properties to make it a Summary calculation for Sum of the Value field
Add subtotal and total fields to the Sale data block to display the subtotal and add the sales tax
33
Subform Subtotal Column
Public Sub ComputeSaleTotal()Dim dr As DataRowDim sum As Decimal = 0Dim iSale As Integer = _
Me.BindingContext(objdsSale, "Sale").PositionFor Each dr In Me.objdsSale.Tables("Sale"). _
Rows(iSale).GetChildRows("SaleSaleItem")sum += dr("Value")
NexteditSubtotal.Text = sum.ToString("0.00")Dim dTax As Decimal = 0If (Not IsNothing(editSalesTax.Text)) _
AndAlso (editSalesTax.Text.Trim <> "") _Then dTax = CType(editSalesTax.Text, Decimal)editTotalDue.Text = (sum + dTax).ToString("0.00")
End Sub
34
Calls to Compute Totals
Private Sub objdsSale_PositionChanged()Me.lblNavLocation.Text = …ComputeSaleTotal()
End Sub
Private Sub grdSaleItem_Leave(ByVal sender As Object, _ByVal e As System.EventArgs) _Handles grdSaleItem.Leave
ComputeSaleTotal()End Sub
Private Sub editSalesTax_Leave(ByVal sender As Object, _ByVal e As System.EventArgs) _Handles editSalesTax.Leave
ComputeSaleTotal()End Sub
New Sale
Leave grid
Change tax
35
Action
Action
Add the routine to compute the subtotal.
Add the three calls to perform the calculation.
Modify the UpdateDataSource code to compensate for the Expression bug in Microsoft’s update code.
36
Code Changes for Update Bug
Public Sub UpdateDataSource…if (Not (ChangedRows) Is Nothing) Then
'Open the connection.Me.OleDbConnection1.Open()'Attempt to update the data source.OleDbDataAdapter1.Update(ChangedRows)Dim tbl As DataTable = Me.objdsSale.Tables("SaleItem")Dim exp As String = tbl.Columns("Value").Expressiontbl.Columns("Value").Expression = String.Emptytbl = tbl.Copy()OleDbDataAdapter2.Update(tbl)Me.objdsSale.Tables("SaleItem").Columns("Value").Expression = exp‘@OleDbDataAdapter2.Update(ChangedRows)
End If
Find this routine
Comment this line out
Insert 6 lines
37
Sale Form
38
Action
ActionAdd a data adapter for CustomerList, creating a query for full name and phone.Add the fill command to the New sub.Add a combo box and assign the DataSource, DisplayMember, ValueMember and DataBindings: Selected Value.Create a similar data adapter and combo box for Payment Method.
39
Customer Query
SELECT CustomerID, LastName + N', ' + FirstName + N' ('
+ Phone + N')' AS CustomerName
FROM powder.Customer
ORDER BY LastName, FirstName, Phone
Combo Boxes only support two columns: Key Value and Display
Remember to deselect the Advanced options to Insert/Delete/Update
40
Customer Combo Box Properties
Dataset
Display column
Key column
Bind to Form
Be sure to add the Fill command in the New subroutine
41
Action
ActionAdd a data adapter for the Item List lookup using the Inventory and Item tables.Create the dataset and add the fill command in the New sub.Add the data grid for the lookup list and set its properties.Add a new TableStyles entry and create entries for the ColumnStyles to set the display widths.Add the two sets of code to open the lookup list and transfer the selection to the dataset.
42
Code for SubGrid Lookup List
Const iColCategory = 0 ' Column for drop down listPrivate row As IntegerPrivate col As IntegerPrivate Sub grdSaleItem_CurrentCellChanged( _
ByVal sender As Object, ByVal e As System.EventArgs) _Handles grdSaleItem.CurrentCellChangedDim cell As DataGridCell = grdSaleItem.CurrentCellIf (cell.ColumnNumber <> iColCategory) Then
grdItems.Visible = FalseExit Sub ' Only care about last column
End Ifrow = grdSaleItem.CurrentRowIndexcol = cell.ColumnNumberDim rect As Rectangle = grdSaleItem.GetCellBounds(row, col)Dim tb As DataGridTextBox = grdSaleItem.Controls(2)tb.BackColor = System.Drawing.Color.BluegrdItems.Left = rect.Left + grdSaleItem.LeftgrdItems.Top = rect.Bottom + grdSaleItem.TopgrdItems.Visible = True
End Sub
43
Code for Data Transfer List
Private Sub grdItems_Click(ByVal sender As Object, _ByVal e As System.EventArgs) Handles grdItems.Click
Dim tb As DataGridTextBox = grdItems.Controls(2)' The next line index must be +1 because the ‘ subform grid has SaleID as a hidden column #0Me.objdsSale.Tables("SaleItem"). Rows(row)(iColCategory + 1) = tb.TextgrdItems.Visible = False
End Sub
This is the main difference when using a subform
44
Final Sale Form
45
SQL Server Report Structure
Page header
Page footer
Body
Customer Group Customer header
Sale Group Sale header
Item Detail
Customer footer
Sale footer
46
Action
ActionCreate a new report project with SQL Reports Service.Add a new Shared Data Source to the Powder database.Add a new report—without using the Wizard.Create a query using Customer + Sale + SaleItem.Add the alias: QuantitySold*SalePrice As Value.In the layout tab, add a Report Header and a title test box.Drag a List box onto the report.Name: GroupCustomer.Grouping: =Fields!CustomerID.ValueDrag customer fields onto the List and add labels.Preview the report.
47
Customer Sales Report Query
Query Designer
Right-click to add tables
Create a new dataset
Shared Data Source
New report
48
Query: Calculated Value Column
SELECT Customer.CustomerID, Customer.LastName,Customer.FirstName, Customer.Phone, Customer.EMail, Sale.SaleID, Sale.SaleDate, Sale.ShipCity, Sale.ShipState, Sale.PaymentMethod, SaleItem.SKU,SaleItem.QuantitySold, SaleItem.SalePrice,SaleItem.QuantitySold * SaleItem.SalePrice AS Value
FROM Customer INNER JOINSale ON Customer.CustomerID = Sale.CustomerID
INNER JOIN SaleItem ON Sale.SaleID = SaleItem.SaleIDORDER BY Customer.CustomerID, Sale.SaleDate, SaleItem.SKU
49
Customer List Layout
Toolbox or Fields List for
Customer group
Customer Fields/data
Text box label
Report headerLayout tab
50
Initial Preview
Report header
Data for one customer
51
Action
ActionAdd a list for the Sale Group.Set Grouping: =Fields!SaleID.Value.Place Sale header items into list.Add a small list for SaleItem as the Detail, with no Grouping.Add the SaleItem boxes to Detail.Format Price and Value to 0.00.Add column heading text boxes in the Sale group, above the Detail list.Preview the report, clean up the layout, add separator lines.
52
Sales and SaleItem Groups
Detail list has no Grouping property
Column headings in GroupSale list
Lines as separators
53
SaleItem Preview
Customer header
Sale header
Detail
Format: 0.00
54
Action
ActionAdjust the Customer and Sale list boxes to leave one row at the bottom of each.Drag the Value field into those spaces.Align it with the SaleItem Value to show the total.Set the format to $ #,##0.00.Add a Page Footer: Report/Footer.Add a text box and use an Expression to enter =Globals!PageNumber.Preview and adjust the report.
55
Final Layout
Sale Footer
Customer Footer
Expression builder for page number
Customer list
Sale list
56
Final Report
57
Creating a Switchboard Form
Add image with PictureBox
Open forms and submenus with buttons
Add report link with LinkLabel
58
Action
Action
Add an image or logo to the menu form (try clip art).
Arrange the form buttons.
Add a LinkLabel to open a report.
Add the VisitLink subroutine to your code.
Enter the code to call the VisitLink with the appropriate URL to open the desired form.
Compile and test the links.
59
Open SQL Reports from Forms
Sub VisitLink(ByVal lnk As LinkLabel, ByVal sURL As String)' Change the color of the link textlnk.LinkVisited = True' Call the Process.Start method to open the default browser System.Diagnostics.Process.Start(sURL)
End Sub
Private Sub lnkCustomerSalesReport_LinkClicked( _ByVal sender As System.Object, _ByVal e As System.Windows.Forms.LinkLabelLinkClickedEventArgs) _Handles lnkCustomerSalesReport.LinkClicked
TryVisitLink(sender, _"http://localhost/Reports/Pages/Report.aspx?ItemPath=/Reports06/CustomerSales")
Catch ex As ExceptionMessageBox.Show("Unable to open the report.")
End TryEnd Sub
60
Action
Action
In the object navigator create a new entry in the Menus section and rename it (CustomerMenu)
In the newly created Menus subsection, create a new entry and rename it Customers
In the object navigator, in the same Menus sublist, add a new item and rename it CustomerSub
Double click the icon to open the Menu Editor
Add entries for AAMain, Customers, Close, and Help
61
Creating Menus
Enter top-level options
Add menu Right-click options
Sub menu
Rename each item
62
Action
ActionDrag a MainMenu onto the menu form.Add top-level links for at least Customers, Close, and Help.Under Customers, add the Customer and Sale forms, and the two reports.Rename each menu item.Double-click the Customer and Sale entries and add the code to open the forms.Add the code to open the two reports.Save, compile, and test everything.
63
Custom Menu
Me.Close
System.Diagnostics.Process.Start(sURL)
64
HTML Help
Form
Help File
AllPowder.chm
HTML Topic
HTML Topic
HTML Topic
HTML Topic
HTML Topic
HTML Topic
Properties:
Help File: AllPowder.chm
Help Context ID: 1
1 Topic A2 Topic B3 Topic C4 Topic D5 Topic E6 Topic F
compile
65
Action
ActionCreate at least three HTML help files for the All Powder forms using an HTML editor or Wordpad.If necessary, download and install the HTML Help workshop.Create a new project in the workshop.Add the HTML files.Edit the HTML files to add keywords.Create the mapping file with a text editor and add it to the project.Set project options to build the TOC and index files.Compile and test the help file.
66
HTML Help Files<Object type="application/x-oleobject" classid="clsid:1e2a7bd0-dab9-11d0-b93a-00c04fc99f9e"> <PARAM name="Keyword" value="Contents"> <PARAM name="Keyword" value="Introduction"> <PARAM name="Keyword" value="Start"> <PARAM name="Keyword" value="Management"></OBJECT><HTML><HEAD><TITLE>All Powder Board and Ski Shop</TITLE><LINK rel="stylesheet" type="text/css" href="Styles.css"></HEAD><BODY><H1>Introduction to the All Powder Board and Ski Shop</H1><TABLE><TR><TD><IMG SRC='BoardLogo1.gif' border='0'></TD><TD>All Powder Board and Ski Shop sells and rents snowboards and skis for all levels of riders and skiers.</TD></TR></TABLE><H2>The Board and Ski Shop</H2><UL><LI><A HREF=’Customers.html'>Customers</A></LI><LI><A HREF=’Sales.html'>Sales </A></LI></UL></BODY></HTML>
67
Topics Map File
#define AllPowder 100
#define Customers 10000
#define Sales 20000
Not required for SQL Server, but create it anyway so that you can use the same help file with other applications if necessary.
68
Help Compiler and File
69
Action
ActionAdd a HelpProvider object to the main form.Set its HelpNamespace property to AllPowder.chm.Select the Form object, set the HelpNavigator property to TableOfContentsFor the Customer button, set the HelpKeyword to Customer and HelpNavigator to KeywordIndex.Write the code for the Help menu item.Compile and test everything.
70
Help File on Visual Basic Form
HelpKeyword: Customer
Keyword IndexHelpProvider
HelpNamespace: AllPowder.chm
71
Help Menu Code
Private Sub mnuHelp_Click(ByVal sender As System.Object, _ByVal e As System.EventArgs) Handles mnuHelp.Click
' Tell the Help system to open the Table of ContentsHelp.ShowHelp(Me.btnCustomer, "AllPowder.chm", _
HelpNavigator.TableOfContents, 0) End Sub
Could also use HelpNavigator.KeywordIndex, “MainMenu”
72
Help In Action