VB.NET版机房收费之模板方法实现组合查询

组合查询算是机房中比较复杂的一块,思路很容易,就是将多个查询条件放在一起限制查询结果,但工作量确实很大,而且在机房中有四个这样的窗体,学习完设计模式后的感触就是每次代码有重复出现的就想着自己用一用那个模式,但自己真正实践时还真有挑战,策略模式看着别人博客也没有实现,组合查询也是参考着他们博客实现的,这个阶段模仿着学吧。

模板方法定义了一个操作的算法的骨架,把具体的实现延迟到子类中,就是说把重复的代码上升到父类,子类去继承并重写父类中的方法,所以父类中放的也都是一些抽象的行为(虚方法),这样很好的实现代码复用。

一:窗体的继承

1.这是组合查询的父窗体(添加时和普通窗体没什么区别):


2.这是子窗体创建时的不同:(以学生上机记录查询为例)


添加继承的窗体


选择要继承的窗体,这样就将学生上机记录的组合查询子窗体建好,创建好的子窗体中控件都是带小锁形状的,不能编辑,只有在form_load中重写父类方法


接着看一下代码部分子类是如何继承父类

二:代码的继承

1.父类

U层主要是窗体加载和一些虚方法

Imports Charge.BLL
Public Class frmGroupInquire
    Protected enGroup As New ChargeEntity.GroupInquireEntity  '实例化实体

    Private Sub frmGroupInquire_Load(sender As Object,e As EventArgs) Handles MyBase.Load
        Label1.Text = "输入查" + Chr(10) + "询条件"

        '窗体加载时给操作符和组合关系赋值
        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("<>")

        cmbRelation1.Items.Add("与")
        cmbRelation1.Items.Add("或")

        cmbRelation2.Items.Add("与")
        cmbRelation2.Items.Add("或")

        '窗体加载后,后两行文本框不能用
        cmbField2.Enabled = False
        cmbOperator2.Enabled = False
        txtContent2.Enabled = False

        cmbField3.Enabled = False
        cmbOperator3.Enabled = False
        txtContent3.Enabled = False

    End Sub

    Private Sub btnInquire_Click(sender As Object,e As EventArgs) Handles btnInquire.Click
        DataGridView1.DataSource = nothing '清空DataGridView1内容
        '第一个组合关系为空,第一行不能为空
        If cmbRelation1.Text = "" Then
            Dim arrayControl() As Control
            ReDim Preserve arrayControl(2)

            arrayControl(0) = cmbField1
            arrayControl(1) = cmbOperator1
            arrayControl(2) = txtContent1

            If Verdict.IsSomeEmptyText(arrayControl) Then  '调用模块判断是否为空
                Exit Sub
            End If
        End If
        '第一个组合关系不为空,前两行不能为空
        If cmbRelation1.Text <> "" Then
            Dim arrayControl() As Control
            ReDim Preserve arrayControl(5)

            arrayControl(0) = cmbField1
            arrayControl(1) = cmbOperator1
            arrayControl(2) = txtContent1
            arrayControl(3) = cmbField2
            arrayControl(4) = cmbOperator2
            arrayControl(5) = txtContent2

            If Verdict.IsSomeEmptyText(arrayControl) Then  '调用模块判断是否为空
                Exit Sub
            End If
        End If
        '第二个组合关系不为空,都不能为空
        If cmbRelation2.Text <> "" Then
            Dim arrayControl() As Control
            ReDim Preserve arrayControl(8)

            arrayControl(0) = cmbField1
            arrayControl(1) = cmbOperator1
            arrayControl(2) = txtContent1
            arrayControl(3) = cmbField2
            arrayControl(4) = cmbOperator2
            arrayControl(5) = txtContent2
            arrayControl(6) = cmbField3
            arrayControl(7) = cmbOperator3
            arrayControl(8) = txtContent3

            If Verdict.IsSomeEmptyText(arrayControl) Then  '调用模块判断是否为空
                Exit Sub
            End If
        End If
        '给实体赋值
        enGroup.cmbField1 = Getdbname(cmbField1.Text.Trim())
        enGroup.cmbField2 = Getdbname(cmbField2.Text.Trim())
        enGroup.cmbField3 = Getdbname(cmbField3.Text.Trim())
        enGroup.cmbOperator1 = cmbOperator1.Text.Trim()
        enGroup.cmbOperator2 = cmbOperator2.Text.Trim()
        enGroup.cmbOperator3 = cmbOperator3.Text.Trim()
        enGroup.txtContect1 = txtContent1.Text.Trim()
        enGroup.txtContect2 = txtContent2.Text.Trim()
        enGroup.txtContect3 = txtContent3.Text.Trim()
        enGroup.cmbRelation1 = Getdbname(cmbRelation1.Text.Trim())
        enGroup.cmbRelation2 = Getdbname(cmbRelation2.Text.Trim())
        enGroup.listName = GetList()

        Dim groupinquirebll As New GroupInquireBLL '实例化B层
        Dim dt As New DataTable
        Call Dview()
    End Sub
    Protected Overridable Function Getdbname(ByVal control As String) As String '定义虚函数Getdbname,或许不同数据库的字段名
        Return ""
    End Function
    Protected Overridable Function GetList() As String '定义虚函数GetList,或许不同数据库的表名
        Return ""
    End Function
    Protected Overridable Sub Dview() '定义虚函数Dview,将数据显示在控件中

    End Sub

    Private Sub cmbRelation1_SelectedindexChanged(sender As Object,e As EventArgs) Handles cmbRelation1.SelectedindexChanged
        If cmbRelation1.Text <> "" Then  '组合关系1是否为空,影响到第2组条件的行操作
            cmbField2.Enabled = True
            cmbOperator2.Enabled = True
            txtContent2.Enabled = True
        End If
    End Sub

    Private Sub cmbRelation2_SelectedindexChanged(sender As Object,e As EventArgs) Handles cmbRelation2.SelectedindexChanged
        If cmbRelation2.Text <> "" Then   '组合关系2是否为空,影响到第3组条件的行操作
            cmbField3.Enabled = True
            cmbOperator3.Enabled = True
            txtContent3.Enabled = True
        End If
    End Sub

    Private Sub btnExit_Click(sender As Object,e As EventArgs) Handles btnExit.Click
        Me.Close()
        frmMain.Panel1.Visible = True
        frmMain.Panel2.Visible = True
    End Sub

    Private Sub btnToExcel_Click(sender As Object,e As EventArgs) Handles btnToExcel.Click
        ToExcel.ToExcel(DataGridView1) '调用导出excel表格公共方法
    End Sub
End Class

其他层代码和普通查询基本一致,在这里也用了存储过程

-- =============================================
-- Author:		李立平
-- Create date: 2014-09-05
-- Description:	GroupInquire
-- =============================================
ALTER PROCEDURE [dbo].[PROC_GroupInquire]
	-- Add the parameters for the stored procedure here
	@cmbField1 varchar(10),@cmbField2 varchar(10),@cmbField3 varchar(10),@cmbOperator1 varchar(10),@cmbOperator2 varchar(10),@cmbOperator3 varchar(10),@txtContect1 varchar(10),@txtContect2 varchar(10),@txtContect3 varchar(10),@cmbRelation1 varchar(10),@cmbRelation2 varchar(10),@listName varchar (20)  --获取表的名称
AS
     declare @Tempsql varchar(500) --临时存放sql语句
--char(32)空格,char(39)单引号
BEGIN
	
	SET @Tempsql ='select * from '+@listName+' where '+@cmbField1+@cmbOperator1+char(39)+@txtContect1+char(39)
    if @cmbRelation1 !=''  --第一个组合关系不为空
    begin
       set  @Tempsql=@Tempsql+@cmbRelation1+char(32)+@cmbField2 +@cmbOperator2 +char(39) +@txtContect2 +char(39)
          if @cmbRelation2 !='' --第二个组合关系不为空
          begin
               set @Tempsql =@Tempsql +@cmbRelation2 +char(32)+@cmbField3  +@cmbOperator3 +char(39) +@txtContect3 +char(39)
	      END
END
EXECUTE(@Tempsql)
END

因为涉及到不止一个sql语句,所以组合查询单独建立了一个实体类属性就是窗体上使用到的控件),在D层用存储过程代替sql语句(在这里想说的是自己返回的datatable,用返回集合实现不了,还不知道为什么?)

2、子类

子类相对来说更容易了,就是对父类U方法的重写(还是以查询上机记录为例)

Imports System.Collections '引入哈希表
Public Class frmlinestatisticsgi
    Private Shared fLS As frmlinestatisticsgi   '声明一个静态类变量,类似C#中static
    Private Sub New()   '初始化为私有,外部代码不能直接new来实例化该窗体
        ' 此调用是设计器所必需的。
        InitializeComponent()
        ' 在 InitializeComponent() 调用之后添加任何初始化。
    End Sub
    Public Shared Function GetInstance() As frmlinestatisticsgi  '得到该窗体实例的方法
        If fLS Is nothing OrElse fLS.Isdisposed Then  '当窗体关闭或者被处理过就实例化该窗体,因为关闭后不会将变量设置为nothing,只是将窗体dispose掉
            fLS = New frmlinestatisticsgi
            fLS.MdiParent = frmMain
        End If
        Return fLS  '如果已经实例化则返回窗体本身
    End Function
    Private Sub frmlinestatistics_Load(sender As Object,e As EventArgs) Handles MyBase.Load
        Me.Text = "上机统计信息查询" '表名
        Dim haField As New Hashtable '定义处理字符串转换的hashtable
        Dim FieldName() As String
        Dim FieldValue() As String  '使用哈希表将数据库字段进行转换
        '数据库中字段对应相应英文
        FieldName = {"卡号","学号","上机日期","上机时间","下机日期","下机时间","消费金额","余额","备注"}
        FieldValue = {"cardNo","studentNo","onDate","onTime","offDate","offTime","comsumeCash","presentCash","status"}
        '放到Field字段中
        cmbField1.Items.AddRange(FieldName)
        cmbField2.Items.AddRange(FieldName)
        cmbField3.Items.AddRange(FieldName)

        '中文关键字,英文value添加到hashtable
        For i As Integer = 0 To FieldName.Count - 1
            haField.Add(FieldName(i),FieldValue(i))
        Next
    End Sub
    '重写获得表名方法
    Protected Overrides Function GetList() As String
        Return "T_Line"
    End Function
    '重写转换成数据库字段方法
    Protected Overrides Function Getdbname(control As String) As String
        Select Case control
            Case "卡号"
                Return "cardNo"
            Case "学号"
                Return "studentNo"
            Case "上机日期"
                Return "onDate"
            Case "上机时间"
                Return "onTime"
            Case "下机日期"
                Return "offDate"
            Case "下机时间"
                Return "offTime"
            Case "消费金额"
                Return "consumeCash"
            Case "余额"
                Return "presentCash"
            Case "备注"
                Return "status"
            Case "与"
                Return "and"
            Case "或"
                Return "or"
            Case Else
                Return ""
        End Select
    End Function
    '重写返回数据到datagridview方法
    Protected Overrides Sub Dview()
        DataGridView1.DataSource = nothing '清空控件内容
        Dim groupinquirebll As New Charge.BLL.GroupInquireBLL
        Dim dt As New DataTable

        dt = groupinquirebll.GroupInquire(enGroup)
        If dt.Rows.Count = 0 Then
            MsgBox("没有记录!")
        Else
            DataGridView1.DataSource = nothing
            DataGridView1.DataSource = dt
            DataGridView1.Columns(0).HeaderText = "卡号"
            DataGridView1.Columns(1).HeaderText = "学号"
            DataGridView1.Columns(2).HeaderText = "上机日期"
            DataGridView1.Columns(3).HeaderText = "上机时间"
            DataGridView1.Columns(4).HeaderText = "下机日期"
            DataGridView1.Columns(5).HeaderText = "下机时间"
            DataGridView1.Columns(6).HeaderText = "消费金额"
            DataGridView1.Columns(6).HeaderText = "余额"
            DataGridView1.Columns(6).HeaderText = "备注"
        End If
    End Sub
End Class

三:总结

在机房中有很多类似的窗体,比如查询充值记录和上机记录,充值金额查询和退还金额查询,有种相见恨晚的感觉,模板方法最大的好处就是实现代码复用,减少工作量,还有就是设计模式是一种思想,只有在应用中解决问题后才发挥出它们的价值,多多思考!

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Format[$] ( expr [ , fmt ] ) format 返回变体型 format$ 强制返回为文本 -------------------------------- 数字类型的格式化 --------------------------------     固定格式参数:     General Number 普通数字,如可以用来去掉千位分隔号     format$("100,1
VB6或者ASP 格式化时间为 MM/dd/yyyy 格式,竟然没有好的办法, Format 或者FormatDateTime 竟然结果和系统设置的区域语言的日期和时间格式相关。意思是尽管你用诸如 Format(Now, "MM/dd/yyyy"),如果系统的设置格式区域语言的日期和时间格式分隔符是"-",那他还会显示为 MM-dd-yyyy     只有拼凑: <%response.write
在项目中添加如下代码:新建窗口来显示异常信息。 Namespace My ‘全局错误处理,新的解决方案直接添加本ApplicationEvents.vb 到工程即可 ‘添加后还需要一个From用来显示错误。如果到这步还不会则需要先打好基础啦 ‘======================================================== ‘以下事件
转了这一篇文章,原来一直想用C#做k3的插件开发,vb没有C#用的爽呀,这篇文章写与2011年,看来我以前没有认真去找这个方法呀。 https://blog.csdn.net/chzjxgd/article/details/6176325 金蝶K3 BOS的插件官方是用VB6编写的,如果  能用.Net下的语言工具开发BOS插件是一件很愉快的事情,其中缘由不言而喻,而本文则是个人首创,实现在了用V
Sub 分列() ‘以空格为分隔符,连续空格只算1个。对所选中的单元格进行处理 Dim m As Range, tmpStr As String, s As String Dim x As Integer, y As Integer, subStr As String If MsgBox("确定要分列处理吗?请确定分列的数据会覆盖它后面的单元格!", _
  窗体代码 1 Private Sub Text1_OLEDragDrop(Data As DataObject, Effect As Long, Button As Integer, Shift As Integer, X As Single, Y As Single) 2 Dim path As String, hash As String 3 For Each fil
  Imports MySql.Data.MySqlClient Public Class Form1 ‘ GLOBAL DECLARATIONS Dim conString As String = "Server=localhost;Database=net2;Uid=root;Pwd=123456;" Dim con As New MySqlConnection
‘導入命名空間 Imports ADODB Imports Microsoft.Office.Interop   Private Sub A1() Dim Sql As String Dim Cnn As New ADODB.Connection Dim Rs As New ADODB.Recordset Dim S As String   S = "Provider=OraOLEDB.Oracl
Imports System.IO Imports System.Threading Imports System.Diagnostics Public Class Form1 Dim A(254) As String    Function ping(ByVal IP As Integer) As String Dim IPAddress As String IPAddress = "10.0.
VB运行EXE程序,并等待其运行结束 参考:https://blog.csdn.net/useway/article/details/5494084 Private Declare Function WaitForSingleObject Lib "kernel32" (ByVal hHandle As Long, ByVal dwMilliseconds As Long) As Long Pr
今天碰到一个问题,登陆的时候,如果不需要验证手机号为空,则不去验证手机号 因为登陆的时候所有的验证信息都存放在一个数组里 Dim CheckUserInfo() As String ={UserBirthday, SecEmail, UserMob, UserSex, RealNameFirst, RealName, CheckCardID, CheckCardType, Contactemail
在VB6.0中,数据访问接口有三种: 1、ActiveX数据对象(ADO) 2、远程数据对象(RDO) 3、数据访问对象(DAO) 1.使用ADO(ActiveX Data Objec,ActiveX数据对象)连接SQL Server 1)使用ADO控件连接 使用ADO控件的ConnectionString属性就可以连接SQL Server,该属性包含一个由分号分隔的argument=value语
注:大家如果没有VB6.0的安装文件,可自行百度一下下载,一般文件大小在200M左右的均为完整版的软件,可以使用。   特别提示:安装此软件的时候最好退出360杀毒软件(包括360安全卫士,电脑管家等,如果电脑上有这些软件的话),因为现如今的360杀毒软件直接会对VB6.0软件误报,这样的话就可能会在安装过程中被误报阻止而导致安装失败,或者是安装后缺乏很多必须的组件(其它的杀毒软件或安全卫士之类的
Private Sub Form_Load() Call conndb End Sub Private Function conndb() Dim cn As New ADODB.Connection Dim rs As New ADODB.Recordset Dim strCn, sql As String Dim db_host As String Dim db_user As String
  PPSM06S70:  Add  moddate  EDITSPRINTJOB:  MAX(TO_CHAR(ETRN.MODDATE, ‘yyyy/mm/dd/HH24:MI AM‘)) ACTUAL_SHIPDATE   4.Test Scenario (1) :Query SQL Test DN:8016578337 SELECT CTRN.TKCTID TRUCK_ID,        
  沒有出現CrystalReportViewer時,須安裝CRforVS_13_0. 新增1個數據集,新增1個數據表,添加二列,列名要和資料庫名一樣. 修改目標Framework 修改app.config, <startup >改成<startup useLegacyV2RuntimeActivationPolicy ="true">  CrystalReport1.rpt增加數據庫專家 在表單
Imports System.Threading Imports System Public Class Form1 Dim th1, th2 As Thread Public Sub Method1() Dim i As Integer For i = 1 To 100 If Me.Label1.BackColor =
Friend Const PROCESS_ALL_ACCESS = &H1F0FFF = 2035711 Friend Const PROCESS_VM_READ = &H10 Friend Const PROCESS_VM_WRITE = &H20 Friend Const PAGE_READONLY = &H2 Friend Const PAGE_READWRITE = &H4 Friend
以下代码随手写的 并没有大量测试 效率也有待提升 如果需要C#的请自行转换 Function SplitBytes(Data As Byte(), Delimiter As Byte()) As List(Of Byte()) Dim i = 0 Dim List As New List(Of Byte()) Dim bytes As New
Imports System.Data.SqlClient Public Class Form1 REM Public conn1 As SqlConnection = New SqlConnection("server=.; Integrated Security=False;Initial Catalog= mydatabase1; User ID= sa;password")