還記得第一次做機房的時候做組合查詢功能嗎?那時候的我從剛開始的一個一個判斷,到後面的先是讓關系框和後面的條件框不能用,根據條件框的填充情況來決定關系框是否能用。這樣一步步的走過來的……
到了第二次的機房重構,我發現之前好多的代碼都是重複的,做了那麼多的無用功!作為一個優秀的程式員,我們要盡可能的減少自己的代碼量,讓我們的代碼能夠複用。這裡我們要明白複用可不是複制哦!
在機房中,我們的基本學生資訊維護、檢視上機狀态、上機資訊統計和操作員工作記錄四個窗體除了字段名不一樣以外,幾乎一樣的,是以我們在做組合查詢功能的時候用到了窗體的繼承。
窗體的繼承就是在父窗體中寫好公共的部分,不一緻的地方可以寫一個虛方法,然後讓子類們進行重寫這個虛方法。這樣,我們就隻需要一個U層、一個B層、一個接口和一個抽象工廠,一個D層就可以實作四個窗體各自的功能了。
U層主要用來判斷一下各個輸入框和選擇框是否為空,給實體參數和B層方法傳值,定義轉換資料庫字段的虛方法和擷取表名的虛方法。
<span style="font-size:18px;">/*************************************************
'作者:邢玉
'小組:
'說明:組合查詢模闆
'建立日期:2015.8.9
'版本号:
'**********************************************/
Imports System.Windows.Forms
Public Class frmGroupQuery
'定義一個保護類型的變量,子窗體也可以通路,以下是另一種寫法
'Protected groupcheck As JFEntity.GroupEntity = New JFEntity.GroupEntity()
Protected groupcheck As New JFEntity.GroupEntity
Private Sub frmGroupQuery_Load(sender As Object, e As EventArgs) Handles MyBase.Load
'操作符部分,因為操作符不變,是以在父窗體中加載
cmbOperator1.Items.Add(">")
cmbOperator1.Items.Add("<")
cmbOperator1.Items.Add("=")
cmbOperator1.Items.Add("<>")
cmbOperator2.Items.Add(">")
cmbOperator2.Items.Add("<")
cmbOperator2.Items.Add("=")
cmbOperator2.Items.Add("<>")
cmbOperator3.Items.Add(">")
cmbOperator3.Items.Add("<")
cmbOperator3.Items.Add("=")
cmbOperator3.Items.Add("<>")
'關系
cmbRelations1.Items.Add("與")
cmbRelations1.Items.Add("或")
cmbRelations2.Items.Add("與")
cmbRelations2.Items.Add("或")
'當選中datagridview控件就選中行
DataGridView1.SelectionMode = DataGridViewSelectionMode.FullRowSelect
Dim i As Integer
For i = 0 To DataGridView1.Columns.Count - 1
DataGridView1.Columns(i).Width = DataGridViewAutoSizeColumnMode.AllCells
Next
End Sub
''' <summary>
''' 清空查詢條件和結果
''' </summary>
''' <param name="sender"></param>
''' <param name="e"></param>
''' <remarks></remarks>
Private Sub btnclear_Click(sender As Object, e As EventArgs) Handles btnclear.Click
cmbFiled1.Text = ""
cmbFiled2.Text = ""
cmbFiled3.Text = ""
cmbOperator1.Text = ""
cmbOperator2.Text = ""
cmbOperator3.Text = ""
txtContent1.Text = ""
txtContent2.Text = ""
txtContent3.Text = ""
cmbRelations1.Text = ""
cmbRelations2.Text = ""
DataGridView1.DataSource = ""
End Sub
''' <summary>
''' 退出
''' </summary>
''' <param name="sender"></param>
''' <param name="e"></param>
''' <remarks></remarks>
Private Sub btncancel_Click(sender As Object, e As EventArgs) Handles btncancel.Click
Me.Dispose()
End Sub
Private Sub btninquire_Click(sender As Object, e As EventArgs) Handles btninquire.Click
'判斷組合框不為空
If cmbRelations1.Text = "" Then '如果第一個組合關系框為空
If cmbFiled1.Text = "" Or cmbOperator1.Text = "" Or txtContent1.Text = "" Then
MsgBox("第一行查詢條件不能為空!", , "提示")
Exit Sub
End If
End If
If cmbRelations1.Text <> "" Then '如果選擇了第一個組合關系
If cmbFiled2.Text = "" Or cmbOperator2.Text = "" Or txtContent2.Text = "" Then
MsgBox("第二行查詢條件不能為空!", , "提示")
Exit Sub
End If
Else
If cmbRelations2.Text <> "" Then '選擇了第二個組合關系
If cmbFiled1.Text = "" Or cmbOperator1.Text = "" Or txtContent1.Text = "" Or
cmbFiled2.Text = "" Or cmbFiled2.Text = "" Or txtContent2.Text = "" Or
cmbFiled3.Text = "" Or cmbFiled3.Text = "" Or txtContent3.Text = "" Then
MsgBox("第三行查詢條件不能為空", , "提示")
Exit Sub
End If
End If
End If
'給實體指派
groupcheck.GetTable = GetTable()
groupcheck.cmbField1 = GetDBName(cmbFiled1.Text.Trim())
groupcheck.cmbField2 = GetDBName(cmbFiled2.Text.Trim())
groupcheck.cmbField3 = GetDBName(cmbFiled3.Text.Trim())
groupcheck.cmbOperator1 = cmbOperator1.Text.Trim()
groupcheck.cmbOperator2 = cmbOperator2.Text.Trim()
groupcheck.cmbOperator3 = cmbOperator3.Text.Trim()
groupcheck.txtContent1 = txtContent1.Text.Trim()
groupcheck.txtContent2 = txtContent2.Text.Trim()
groupcheck.txtContent3 = txtContent3.Text.Trim()
groupcheck.cmbRelation1 = GetDBName(cmbRelations1.Text.Trim())
groupcheck.cmbRelation2 = GetDBName(cmbRelations2.Text.Trim())
'給外觀層方法傳遞參數
Dim dt As New DataTable
Dim Ugroupcheck As New Facade.GroupCheckFacade
dt = Ugroupcheck.FGroupCheck(groupcheck)
If (dt.Rows.Count = 0) Then
MsgBox("沒有符合條件的記錄!請重新設定查詢條件!", , "提示")
DataGridView1.DataSource = Nothing
Else
'DataGridView1.DataSource = dt
Call Todatagridview()
End If
End Sub
'當第一個組合關系框的内容發生改變時對第二行查詢框是否可用進行判斷
Private Sub cmbRelations1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles cmbRelations1.SelectedIndexChanged
cmbFiled2.Enabled = True
cmbOperator2.Enabled = True
txtContent2.Enabled = True
cmbRelations2.Enabled = True
End Sub
'當第二個組合關系框的内容發生改變時對第二行查詢框是否可用進行判斷
Private Sub cmbRelations2_SelectedIndexChanged(sender As Object, e As EventArgs) Handles cmbRelations2.SelectedIndexChanged
'對控件選擇進行限定
cmbFiled3.Enabled = True
cmbOperator3.Enabled = True
txtContent3.Enabled = True
End Sub
''' <summary>
''' 定義虛函數GetDBName,擷取不同資料庫的字段名
''' </summary>
''' <returns></returns>
''' <remarks></remarks>
Public Overridable Function GetDBName(ByVal control As String) As String
Return ""
End Function
'定義虛函數GetTable,擷取不同資料庫的表名
Protected Overridable Function GetTable() As String
Return ""
End Function
''' <summary>
''' 把表顯示到datagridview中
''' </summary>
''' <remarks></remarks>
Protected Overridable Sub Todatagridview()
DataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnMode.AllCells
End Sub
''' <summary>
''' 調用子產品中的方法,導出Excel表
''' </summary>
''' <param name="sender"></param>
''' <param name="e"></param>
''' <remarks></remarks>
Private Sub GroupBox1_Enter(sender As Object, e As EventArgs)
Call ExportExcel(DataGridView1)
End Sub
Private Sub btnExcel_Click(sender As Object, e As EventArgs) Handles btnExcel.Click
Call ExportExcel(DataGridView1)
End Sub
</span>
B層
<span style="font-size:18px;">'/*****************************************
'類 名 稱:GroupCheckBLLvb
'命名空間:JFBLL
'建立時間:2015/7/27 16:46:57
'作 者:邢玉
'小 組:
'修改時間:
'修 改 人:
'版 本 号:v1.0.0
’******************************************
Imports IDAL
Imports JFEntity
Public Class GroupCheckBLLvb
''' <summary>實作工廠和接口的方法
''' 組合查詢,父窗體
''' </summary>
''' <param name="group"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Function GroupCheck(ByVal group As JFEntity.GroupEntity) As DataTable
Dim Igroupcheck As IDAL.IGroupCheckDAL
Dim table As New DataTable
Igroupcheck = Factory.LoginFactory.GroupCheck
table = Igroupcheck.IGroupCheck(group)
If table.Rows.Count = 0 Then
' Return Nothing
'Else
Return table
End If
Return table
End Function
End Class
</span>
D層:
<span style="font-size:18px;">'/*****************************************
'類 名 稱:SqlGroupCheckDAL
'命名空間:JFDAL
'建立時間:2015/7/27 16:42:43
'作 者:邢玉
'小 組:
'修改時間:
'修 改 人:
'版 本 号:v1.0.0
’******************************************
Imports System.Data.SqlClient
Imports IDAL
Public Class SqlGroupCheckDAL : Implements IGroupCheckDAL
'執行個體化sqlHelper
Private SqlHelper As SQLHelper.sqlHelper = New SQLHelper.sqlHelper()
Public Function IGroupCheck(ByVal groupcheck As JFEntity.GroupEntity) As DataTable Implements IGroupCheckDAL.IGroupCheck
Dim sqlparam As SqlParameter() = {New SqlParameter("@cmbFiled1", groupcheck.cmbField1),
New SqlParameter("@cmbFiled2", groupcheck.cmbField2),
New SqlParameter("@cmbFiled3", groupcheck.cmbField3),
New SqlParameter("@cmbOperator1", groupcheck.cmbOperator1),
New SqlParameter("@cmbOperator2", groupcheck.cmbOperator2),
New SqlParameter("@cmbOperator3", groupcheck.cmbOperator3),
New SqlParameter("@txtContent1", groupcheck.txtContent1),
New SqlParameter("@txtContent2", groupcheck.txtContent2),
New SqlParameter("@txtContent3", groupcheck.txtContent3),
New SqlParameter("@cmbRelation1", groupcheck.cmbRelation1),
New SqlParameter("@cmbRelation2", groupcheck.cmbRelation2),
New SqlParameter("@tableName", groupcheck.GetTable)} '設定參數
Dim strSql As String = "PROC_GroupQuery" '調用存儲過程
table = helper.GetDataTable(strSQL, CommandType.StoredProcedure, prams)
Return table
End Function
End Class</span></span>
存儲過程:
<span style="font-size:18px;">-- =============================================
-- Author: 邢玉
-- Create date: 2015/7/27
-- Description: 組合查詢
-- =============================================
ALTER PROCEDURE [dbo].[PROC_GroupQuery]
-- Add the parameters for the stored procedure here
@cmbFiled1 varchar(10),
@cmbOperator1 varchar(10),
@txtContent1 varchar(10),
@cmbFiled2 varchar(10),
@cmbOperator2 varchar(10),
@txtContent2 varchar(10),
@cmbFiled3 varchar(10),
@cmbOperator3 varchar(10),
@txtContent3 varchar(10),
@cmbRelation1 varchar(10),
@cmbRelation2 varchar(10),
@tableName varchar(20)
AS
declare @TempSql varchar(500)--臨時存放Sql語句
--BEGIN
-- SET @TempSql='SELECT * FROM '[email protected] +'WHERE'[email protected] [email protected] +char(39)[email protected] +char(39)
-- if @cmbRelation1 != ''
-- BEGIN
-- SET @[email protected] [email protected] +CHAR(32)[email protected] [email protected] +CHAR (39)[email protected] +CHAR (39)
-- if @cmbRelation2 != ''
-- BEGIN
-- SET @[email protected] [email protected] +CHAR (32)[email protected] [email protected] +CHAR (39)[email protected] +char(39)
-- end
-- end
-- EXECUTE(@TempSql)
BEGIN
SET @TempSql='SELECT * FROM '[email protected] +' WHERE ' [email protected] [email protected]+char(39) + @txtContent1 + char(39)
if (@cmbRelation1 != '')
BEGIN
SET @[email protected][email protected]+CHAR(32)[email protected] [email protected]+CHAR(39)[email protected]+CHAR(39)
if (@cmbRelation2 is not null )
BEGIN
SET @[email protected][email protected]+CHAR(32)[email protected][email protected]+CHAR(39)[email protected]+CHAR(39)
END
END
EXECUTE(@TempSql)
END
</span>
抽象工廠
<span style="font-size:18px;">'/*****************************************
'類 名 稱:LoginFactory
'命名空間:Factory
'建立時間:2015/6/7 16:18:59
'作 者:邢玉
'小 組:
'修改時間:
'修 改 人:
'版 本 号:v1.0.0
’******************************************
Imports System.Configuration '添加對配置檔案的引用
Imports System.Reflection '添加對反射的應用
Imports IDAL
Imports System.Data
''' <summary>
''' 執行個體化一個JFDAL中的GroupCheck表的類
''' </summary>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Function GroupCheck() As IGroupCheckDAL
Dim className As String = AssemblyName + "." + db + "GroupCheckDAL"
Dim Igroupcheck As IDAL.IGroupCheckDAL
Igroupcheck = CType(Assembly.Load(AssemblyName).CreateInstance(className), IGroupCheckDAL)
Return Igroupcheck
End Function</span>
編輯完父窗體之後就是要添加我們繼承的子窗體了。
第一步:添加繼承窗體:
第二步:選擇被繼承的窗體:
最後在子類中重寫父類的虛方法:
<span style="font-size:18px;">/*************************************************
'作者:邢玉
'小組:
'說明:組合查詢模闆
'建立日期:2015.8.9
'版本号:
'**********************************************/
Public Class frmStuInfo
'重寫轉換成資料庫字段的方法
Public Overrides Function GetDBName(control As String) As String
Select Case (control)
Case "卡号"
Return "cardID"
Case "學号"
Return "studentID"
Case "姓名"
Return "studentName"
Case "性别"
Return "sex"
Case "系别"
Return "department"
Case "年級"
Return "grade"
Case "班級"
Return "class"
Case "與"
Return "and"
Case "或"
Return "or"
Case Else
Return ""
End Select
End Function
'重獲表名的方法
Protected Overrides Function GetTable() As String
groupcheck.GetTable = "Student_Info"
Return groupcheck.GetTable
End Function
Private Sub frmStuInfo_Load(sender As Object, e As EventArgs) Handles MyBase.Load
cmbFiled1.Items.Add("學号")
cmbFiled1.Items.Add("姓名")
cmbFiled1.Items.Add("性别")
cmbFiled1.Items.Add("系别")
cmbFiled1.Items.Add("年級")
cmbFiled1.Items.Add("班級")
cmbFiled2.Items.Add("學号")
cmbFiled2.Items.Add("姓名")
cmbFiled2.Items.Add("性别")
cmbFiled2.Items.Add("系别")
cmbFiled2.Items.Add("年級")
cmbFiled2.Items.Add("班級")
cmbFiled3.Items.Add("學号")
cmbFiled3.Items.Add("姓名")
cmbFiled3.Items.Add("性别")
cmbFiled3.Items.Add("系别")
cmbFiled3.Items.Add("年級")
cmbFiled3.Items.Add("班級")
End Sub
Protected Overrides Sub Todatagridview()
Dim table As New DataTable
Dim frmGroupQuery As New frmGroupQuery
Dim FacadeGroupQuery As New Facade.GroupCheckFacade
Try
table = FacadeGroupQuery.FGroupCheck(groupcheck)
If table.Rows.Count = 0 Then
table.Clear()
DataGridView1.DataSource = Nothing
DataGridView1.Refresh()
Else
DataGridView1.DataSource = table
'DataGridView1.Columns(0).Visible = False
DataGridView1.Columns(0).HeaderText = "學号"
DataGridView1.Columns(1).HeaderText = "姓名"
DataGridView1.Columns(2).HeaderText = "系别"
DataGridView1.Columns(3).HeaderText = "系别"
DataGridView1.Columns(4).HeaderText = "年級"
DataGridView1.Columns(5).HeaderText = "班級"
End If
Catch ex As Exception
MsgBox(ex.Message, vbOKOnly, "提示")
End Try
End Sub
End Class
</span>
我們組合查詢的邏輯就是首先隻讓第一行的條件框可用,關系框和其他的條件框都不可用,隻有當第一行的條件框填滿的時候,第一個關系框才能用,隻有第一個關系框選擇了關系之後,第二行的條件框才能用。以此類推……這樣我們就省了好多次的判斷語句,代碼又少了,而且邏輯也清晰了。
我們的每一次将就就是在阻止自己的進步,隻有不将就才是發現的源動力!