你好,欢迎来到电脑编程技巧与维护杂志社! 杂志社简介广告服务读者反馈编程社区  
合订本订阅
 
 
您的位置:技术专栏 / Linux开发
基于关系数据库的VB通用查询编程技巧
 

马艳红

摘要  本文作者经过多年的软件项目开发,总结了一种基于关系数据库的通用查询编程技巧。从程序的界面设计到源代码,每一处都作了详细的说明,编程者可以直接根据本文的内容做出自己的通用查询程序,并可以应用到其它的软件项目中,不会产生任何影响,使用方便灵活,使编程更具魅力!
关键词 VB,查询,数据库
一、通用查询功能的重要性
    基于数据库的信息管理系统,最核心的功能是将数据存储到数据库中,并可以对数据进行增加、修改、删除、查询等功能。其中查询功能更是用户经常使用的功能,一个可改变条件的灵活、快捷、准确的查询会给用户带来极大的方便,也给软件本身带来了更大的价值。
二、通用查询的设计
    1.对象的添加
    在VB6.0环境中,建立一个标准的EXE工程,在工程的部件中添加ADO、MSHFlexGrid两个控件,然后在窗体中添加两个MSHFlexGrid对象,分别改名为Grid1和Grid2,添加三个Command按钮Command1,做成控件数组,添加两个Command按钮,分别改名为Cmd_confirm、Cmd_cancel,最后添加四个Combo控件Combo1,做成控件数组。
    2.各控件的功能
Grid1:查询条件输入区,初始值设为2行,5列。
Grid2:查询结果显示区,可根据查询结果,自动调整行列,并显示记录。
Command1(0): Caption属性为“增加行”,具有为Grid1增加行数的功能。
Command1(1): Caption属性为“删除行”,具有为Grid1删除行数的功能。
Command1(2): Caption属性为“清除条件”,具有清除查询条件的功能。
Cmd_confirm:根据Grid1中的查询条件,查询数据的功能。
Cmd_cancel:退出查询功能。
Combo1(0):用于提供连接条件“And”和“or”。
Combo1(1):提供查询的内容(表或视图中字段对用的汉字别名)。
Combo1(2):提供查询的关系条件(“=”、“>”等)。
Combo1(3):提供Combo1(4)对应的查询字段的值。
Combo1(4):与Combo1(1)同步,提供查询的内容(表或视图中的字段名)。
    3.设计后的界面
    通用查询界面如下图所示:
 



图 通用查询界面
三、代码实现
    1.自定义的对象及变量
Option Explicit
Public cn As ADODB.Connection         '数据库的连接对象
Public rs As ADODB.Recordset          '数据库的记录集对象
Public strsumdemand As String         '通用查询求和语句
Public strcondition As String         '通用查询条件
'-------------------------需要编程者根据要查询的表或视图来改变的条件
Public constr As String               '数据库连接字符串
Public strsql As String               '传递查询条件(字段无汉字别名)
Public strtable As String             '传递查询表名
Public strdemand As String             '通用查询语句(字段具有汉字别名)
'-------------------------------------------------------
    2.用户自定义过程
    (1)完成对数据库连接对象cn的赋值,并打开,以备使用。
Public Sub opencn()   '打开连接
Set cn = New ADODB.Connection
' constr字符串,用于编程者根据所使用的数据库不同(如Access、SQL Server),来修改成不同的连接字符串。本例中以cx.mdb为例。
    constr = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & App.Path & "\cx.mdb;Persist Security Info=False"
    cn.Open constr
End Sub
    (2)完成对数据库连接对象cn关闭,及置空功能。
Public Sub closecn()
    cn.Close
    Set cn = Nothing
End Sub
    (3)完成对数据库记录集对象rs的设置,并根据查询条件,对数据库进行查询,返回结果集。
Public Sub openrs(sqlstr As String)
    Set rs = New ADODB.Recordset
    With rs
       .ActiveConnection = cn
       .CursorLocation = adUseClient
       .CursorType = adOpenStatic
       .LockType = adLockBatchOptimistic
       .Source = sqlstr
       .Open
       Set .ActiveConnection = Nothing
    End With
End Sub
    (4)完成对数据库连接记录集对象rs关闭,及置空功能。
Public Sub closers()
    rs.Close
    Set rs = Nothing
End Sub
    (5)根据查询结果,将符合条件的记录添加到Grid2中,并显示。
Public Sub fillgrid()
    Dim j As Integer
    Dim i As Integer
    Dim m As Integer     '记录集行值
    Dim n As Integer     '记录集列值
    Dim rssum As ADODB.Recordset
   
Opencn               '调用子过程Opencn,打开数据库连接
'调用子过程Openrs,并传参数—查询的内容
    openrs strdemand & strcondition  
closecn             '调用子过程closecn,关闭数据库连接
Grid2.Clear         '清空表格Grid2
    Grid2.FormatString = ""
    '判断记录集中是否有记录,无记录跳出程序段   
If rs.RecordCount <= 0 Then Exit Sub 
    m = rs.RecordCount      'm变量用来记录记录集rs中的记录总数
    n = rs.Fields.Count     'n变量用来记录记录集rs的字段的总数
rs.MoveFirst
'---设置Grid2的0至n-1列的对齐方式和文本内容
    For i = 0 To n - 1
   Grid2.FormatString = Grid2.FormatString & " |<  " & rs.Fields(i).Name
Next
'-------------------------------------------------------
    Grid2.Rows = m + 1   '设置Grid2的总行数
Grid2.Cols = n + 1   '设置Grid2的总列数
'---将查询到的记录添加到Grid2中
For i = 1 To m     '------------------------------行循环
        For j = 1 To n     '=====================列循环
            Grid2.TextMatrix(i, j) = rs.Fields(j - 1).Value & ""
            If m <= 100 Then
                If i Mod 2 = 0 Then
                    Grid2.Col = j
                    Grid2.Row = i
                    Grid2.CellBackColor = &HFEFBDE
                End If
            End If
        Next j      '=================================
        rs.MoveNext
Next i         '------------------------------------
'---------------向Grid2中添加查询到的记录
    If strsumdemand <> "" Then
        opencn
        Grid2.Rows = Grid2.Rows + 1
        Grid2.TextMatrix(Grid2.Rows - 1, 1) = "合计"
        Set rssum = New ADODB.Recordset
        rssum.Open strsumdemand & strcondition, cn, adOpenKeyset, adLockReadOnly
        For j = 1 To n
            For i = 0 To rssum.Fields.Count - 1
                If Grid2.TextMatrix(0, j) = rssum.Fields(i).Name Then
                    Grid2.TextMatrix(Grid2.Rows - 1, j) = _
& rssum.Fields(i).Value & ""
                End If
            Next i
        Next j
        closecn
    End If
    Grid2.MergeCells = flexMergeRestrictColumns
    Grid2.MergeCol(1) = True
Me.Caption = Mid(Me.Caption, 1, InStr(Me.Caption, "表")) & "(共有" & Grid2.Rows - 1 & "条记录)"
'-----------------------------------------------------------
End Sub
    (6)根据参数com和rs,向combobox中添加值
Public Sub fillcom1(com As ComboBox, rs As ADODB.Recordset)'填充combobox
    com.Clear
    If rs.RecordCount <= 0 Then Exit Sub
    rs.MoveFirst
    Do Until rs.EOF
        com.AddItem (rs.Fields(0).Value) & ""
        rs.MoveNext
    Loop
    rs.MoveFirst
End Sub
    3.窗体的加载事件
Private Sub Form_Load()
  
' 给strsql变量赋值,值为SELECT语句,参考格式如下,只有字段名,字段无别名,这是为了与界面用户操作的查询字段同步,给编程者提供的字段名称
strsql = "SELECT STUDENT_TBL.STUID, STUDENT_TBL.STUname, STUDENT_TBL.STUsorce, STUDENT_TBL.STUchive FROM STUDENT_TBL"
' 给strdemand变量赋值,值为SELECT语句,参考格式如下,给字段取别名是为了在选择条件的界面给用户提供汉字的参考
strdemand = "SELECT STUDENT_TBL.STUID as 学号, STUDENT_TBL.STUname as 姓名, STUDENT_TBL.STUsorce as 课程, STUDENT_TBL.STUchive as 成绩 FROM STUDENT_TBL"
' 给strtable变量赋值,值为要查询的表名或视图名
    strtable = "STUDENT_TBL"
    strsumdemand = ""
 
    Dim i As Integer
    ' --------------给Grid1初始化,设置列宽、单元格对齐方式
  Grid1.FormatString = " 逻辑符|^ 列     名  |^  运算符   |^ 数据值 |"
    Grid1.ColWidth(4) = 0
    Grid1.ColWidth(3) = 2500
    Grid1.ColWidth(2) = 1000
    Grid1.ColWidth(1) = 1850
    Grid1.ColWidth(0) = 1000
    For i = 0 To 3
        Grid1.Row = 0
        Grid1.Col = i
        Grid1.CellAlignment = 4
Next i
' -----------------------------------------------------
Opencn                   '调用子过程Opencn,打开数据库连接
openrs strdemand  '调用子过程Openrs,并传参数—查询的内容
' --------------------向Combo1(1)中添加strdemand字符串中字段别名
    For i = 0 To rs.Fields.Count - 1
        Combo1(1).AddItem rs.Fields(i).Name
Next i
' --------------------向Combo1(4)中添加strsql字符串中字段名
openrs strsql
    For i = 0 To rs.Fields.Count - 1
        Combo1(4).AddItem rs.Fields(i).Name
    Next i
    closers
closecn
' ----------------------初始化Combo1(2)
    With Combo1(2)
        .AddItem " = "
        .AddItem " > "
        .AddItem " < "
        .AddItem " >= "
        .AddItem " <= "
        .AddItem " <> "
        .AddItem " like "
End With
' -----设置Combo1的0--3各元素与Grid1的0--3各列的宽度相同
    Combo1(0).Width = 1000
    Combo1(1).Width = 1850
    Combo1(2).Width = 1000
    Combo1(3).Width = 2500
End Sub
    4.取消按钮的单击事件
Private Sub Cmd_cancel_Click()
    Unload Me
End Sub
    5.确定按钮的单击事件
Private Sub Cmd_confirm_Click()
   Dim i As Integer
' -----根据Combo1(3)的特殊值,修改Grid1当前单元的文本
    If Combo1(3).Visible = True Then
        If Combo1(3).Text = "True" Then
            Grid1.TextMatrix(Grid1.Row, 3) = "1"
        ElseIf Combo1(3).Text = "Flase" Then
            Grid1.TextMatrix(Grid1.Row, 3) = "0"
        Else
            Grid1.TextMatrix(Grid1.Row, 3) = Combo1(3).Text
        End If
    End If
    strcondition = ""
 ' -----根据不同的关系运算,给strcondition变量赋值
    If Grid1.Rows >= 2 And Grid1.TextMatrix(1, 1) <> "" Then
        If Grid1.TextMatrix(1, 2) = " like " Then
            strcondition = " where " & Grid1.TextMatrix(1, 4) & " like " & "'%" & Grid1.TextMatrix(1, 3) & "%'"
        Else
            strcondition = " where " & Grid1.TextMatrix(1, 4) & Grid1.TextMatrix(1, 2) & "'" & Grid1.TextMatrix(1, 3) & "'"
        End If
        For i = 2 To Grid1.Rows - 1
            If Grid1.TextMatrix(i, 2) = " like " Then
                strcondition = strcondition & Grid1.TextMatrix(i, 0) & Grid1.TextMatrix(i, 4) & " like " & "'%" & Grid1.TextMatrix(i, 3) & "%'"
            Else
                strcondition = strcondition & Grid1.TextMatrix(i, 0) & Grid1.TextMatrix(i, 4) & Grid1.TextMatrix(i, 2) & "'" & Grid1.TextMatrix(i, 3) & "'"
            End If
        Next i
End If
' -----调用过程Fillgrid,向Grid2中添加查询到的记录
   Fillgrid  

End Sub
    6.Combo1的单击事件
Private Sub Combo1_Click(Index As Integer)
' ----控制Combo1(4)与Combo1(1)同步,并根据Combo1(1)中选的字段不同,向Combo1(3)中添加这一字段下的所有不重复的值
    Dim tempsql As String
   
    If Index = 1 Then
        Combo1(4).ListIndex = Combo1(1).ListIndex
        Grid1.TextMatrix(Grid1.Row, 4) = Combo1(4).Text
        tempsql = "SELECT DISTINCT " & Combo1(4).Text & " from " & strtable
        opencn
        openrs tempsql
        closecn
        fillcom1 Combo1(3), rs
    End If
    Grid1.TextMatrix(Grid1.Row, Index) = Combo1(Index).Text
    If Grid1.Text = "True" Then
        Grid1.Text = "1"
    ElseIf Grid1.Text = "False" Then
        Grid1.Text = "0"
    End If
End Sub
    7.Command1的单击事件
Private Sub Command1_Click(Index As Integer)
    Dim i As Integer
    Select Case Index
        Case 0             '清除条件
            Grid1.Rows = 2
            For i = 0 To 4
                Grid1.TextMatrix(1, i) = ""
            Next i
        Case 1            '增加行
            Grid1.Rows = Grid1.Rows + 1
        Case 2            '删除行
            If Grid1.Rows > 2 Then
                Grid1.Rows = Grid1.Rows - 1
            Else
                For i = 0 To 4
                    Grid1.TextMatrix(1, i) = ""
                Next i
            End If
    End Select
End Sub
    8.Grid1的EnterCell事件,控制Combo1在Grid1中出现的位置
Private Sub Grid1_EnterCell()
    Combo1(Grid1.Col).Visible = True
    Combo1(Grid1.Col).Left = Grid1.Left + Grid1.CellLeft
    Combo1(Grid1.Col).Top = Grid1.Top + Grid1.CellTop
    Combo1(Grid1.Col).ZOrder 0
End Sub
    9.Grid1的LeaveCell事件
    实现将Combo1中的文本内容添加到Grid1相应的单元格中。
Private Sub Grid1_LeaveCell()
    If Grid1.Row > 0 Then
        Grid1.Text = Combo1(Grid1.Col).Text
        If Grid1.Text = "True" Then
            Grid1.Text = "1"
        ElseIf Grid1.Text = "False" Then
            Grid1.Text = "0"
        End If
        Combo1(Grid1.Col).Visible = False
    End If
End Sub
四、通用查询功能的验证
    为验证以上程序功能,建立一个实验数据库CX.mdb,在此数据库中添加一个表STUDENT_TBL,结构如表1所示:
表1 STUDENT_TBL表结构

字段名

字段数据类型

主键

说明

STUID

Varchar(12)

Yes

学生编号

STUname

Varchar(50)

 

学生姓名

STUsorce

Varchar(20)

 

课程

STUchive

Varchar(50)

 

成绩

然后向表中输入几条合理的数据,如表2所示:
表2 数据录入

学生编号

学生姓名

课程

成绩

200201050401

刘强

VB

80.5

200201050402

李飞

VB

95

200201050403

刘立

VC++

65

    注意,在验证程序功能时,除了以上内容外,还要在代码中更改constr、strsql、strdemand、strtable的值。实现代码如下:
constr字符串,用于编程者根据所使用的数据库不同(如Access、SQL Server),来修改成不同的连接字符串,本例中以cx.mdb为例:
    constr = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & App.Path & "\cx.mdb;Persist Security Info=False"

strsql变量赋值,给编程者提供的字段名称:
strsql = "SELECT STUDENT_TBL.STUID, STUDENT_TBL.STUname, STUDENT_TBL.STUsorce, STUDENT_TBL.STUchive FROM STUDENT_TBL"
strdemand变量赋值,给用户提供汉字参考:
strdemand = "SELECT STUDENT_TBL.STUID as 学号, STUDENT_TBL.STUname as 姓名, STUDENT_TBL.STUsorce as 课程, STUDENT_TBL.STUchive as 成绩 FROM STUDENT_TBL"
strtable变量赋值,值为要查询的表名或视图名:
    strtable = "STUDENT_TBL"
    修改以上代码后,将工程及子文件保存,然后运行程序,就会得到想要的功能。
五、结语
    综上所述,利用以上代码,只需程序员根据程序要访问的数据库不同,改变连接字符串变量constr,就可以访问SQL Server、Access等类型的数据库,再根据要访问的表或试图的结构,写成SELECT语句的形式,对strsql、strdemand、strtable三个变量赋值,即可完成复杂的自由查询功能。同时这个功能代码,不会影响项目中其它程序功能,可作为单独的功能附加到程序中,从而增强程序的健壮性。可以说利用以上代码实现自由查询功能,既为程序员减轻了编程的压力,同时又获得了用户对开发者的认可,这也正是本文作者的意图,让程序员的编程更轻松,让软件为用户提供更灵活而强大的功能!
    参考文献:
[1] Microsoft Corporation著  微软[中国]有限公司 译.中文Visual Basic 6.0程序员指南 ,北京希望出版社1998.6.
[2] 马艳红郑建伟等开发 国电电力物资信息管理系统.大连益友电脑有限公司,2002.3.

  推荐精品文章

·2024年12月目录 
·2024年11月目录 
·2024年10月目录 
·2024年9月目录 
·2024年8月目录 
·2024年7月目录 
·2024年6月目录 
·2024年5月目录 
·2024年4月目录 
·2024年3月目录 
·2024年2月目录 
·2024年1月目录
·2023年12月目录
·2023年11月目录

  联系方式
TEL:010-82561037
Fax: 010-82561614
QQ: 100164630
Mail:gaojian@comprg.com.cn

  友情链接
 
Copyright 2001-2010, www.comprg.com.cn, All Rights Reserved
京ICP备14022230号-1,电话/传真:010-82561037 82561614 ,Mail:gaojian@comprg.com.cn
地址:北京市海淀区远大路20号宝蓝大厦E座704,邮编:100089