前言
最近敲机房敲到了组合查询,我发现有好几个窗体都涉及到了组合查询,我敲的是学生上机统计信息这个窗体,下面我说说我的想法。
窗体逻辑
首先,怎么确定窗体的运行过程呢?我的办法就是通过盲人摸象的方法一个一个按钮试出它的功能,当然我们知道的一些简单的操作就不用说了,比如说哪里没有填肯定要提醒的。当我填完第一行的时候,点击查询很自然就显示出结果了;当我填完第一行,又选择了组合关系,点击查询提示请选择字段,说明如果选择了第一个组合关系必须也填满第二行,同理如果选择了第二个组合关系,那么三行都得填满。
这是大体的功能,当然还要仔细的试一试,接下来挨个字段试,选择姓名或者备注,那么操作符只有“=”和“<>”,如果选择了上机日期、上机时间等,则每次都会弹出提示框,提示让我们填入正确的格式。好了,整体功能了解的差不多了,但是可以看出它也有需要改进的地方,我们可以暂时记住,方便以后优化。
总体来说,窗体的逻辑就是:1.先判断信息是否都填写完整。如果选择了第一个关系,前两行必须要填写完整, 如果选择了第二个关系,则三行信息都必须填写完整。2.注意细节。比如当我们选择了不同的字段,情况也不一样。
实现过程
当我们明白了窗体的逻辑,就可以依靠自己的力量去解决它了。下面我说一下我的实现过程:
1.首先就要把comboBox中的汉字转换为数据库中的“字段名”。我运用的是控件数组,同时用了一个循环,这样看起来比较麻烦,因为看巨人的博客,用一个自定义函数就行了,也不必用循环,但是我觉得这样理解起来比较容易。
'strField(i)是我定义的一个数组变量
For i = 0 To 2
Select Case cboField(i).Text
Case "卡号"
strField(i) = "cardno"
Case "姓名"
strField(i) = "studentName"
Case "上机日期"
strField(i) = "ondate"
Case "上机时间"
strField(i) = "ontime"
Case "下机日期"
strField(i) = "offdate"
Case "下机时间"
strField(i) = "offtime"
Case "消费金额"
strField(i) = "consume"
Case "余额"
strField(i) = "cash"
Case "备注"
strField(i) = "status"
End Select
Next
2.当我们选择不同字段的时候,对应的操作符也不同。
而且,前面已经说到,有些地方我们可以自己优化。所以我就想了想,每次选择上机日期等字段的时候,都要弹出一个提示框,还会在没有选择操作符的情况下,按正常人的思维,应该先选择操作符,再填写要查询的内容,用户可能在这段时间忘记正确的格式,而且每次都弹出一个框,确实让人有点儿烦(我是这么想的)。那么有什么办法呢?我想到了日期控件,当我们选择这些字段的时候,可以将文本框变成选择日期,岂不是大大的方便了用户呢。下面是我的代码实现:
先说一下,也不是把文本框变成日期控件,我就是让日期控件覆盖文本框,窗体加载的时候让日期控件不可见,当点击这些字段的时候才让它可见。同样用了一个循环,根据点击的字段不同,对应的情况也就不同。
Private Sub cboField_Click(Index As Integer)
For i = 0 To 2
If Not Testtxt(Trim(cboOperaChar(i).Text)) Then
Select Case cboField(i).Text
Case "姓名"
'必须要每次清空一下操作符中的内容,否则它会一直添加,会有重复
cboOperaChar(i).Clear
cboOperaChar(i).AddItem "="
cboOperaChar(i).AddItem "<>"
Case "备注"
cboOperaChar(i).Clear
cboOperaChar(i).AddItem "="
cboOperaChar(i).AddItem "<>"
Case "上机日期","下机日期"
'当点击上机日期、下机日期时,让日期控件显示,text文本框不能用或隐藏。
DTPicker1(i).Visible = True
txtContent(i).Enabled = False
cboOperaChar(i).Clear
cboOperaChar(i).AddItem "="
cboOperaChar(i).AddItem "<"
cboOperaChar(i).AddItem ">"
cboOperaChar(i).AddItem "<>"
Case "上机时间","下机时间"
'改变日期控件的样式,让它变成选择时间的样式
DTPicker1(i).Format = dtpTime
DTPicker1(i).Visible = True
txtContent(i).Enabled = False
cboOperaChar(i).Clear
cboOperaChar(i).AddItem "="
cboOperaChar(i).AddItem "<"
cboOperaChar(i).AddItem ">"
cboOperaChar(i).AddItem "<>"
Case Else
cboOperaChar(i).Clear
cboOperaChar(i).AddItem "="
cboOperaChar(i).AddItem "<"
cboOperaChar(i).AddItem ">"
cboOperaChar(i).AddItem "<>"
End Select
End If
Next
End Sub
日期控件小扩展
刚开始的时候只知道有日期控件,但是没有深入的了解它,以为它只可以选择日期,不能用来当做时间选择控件。所以一开始一直在纠结如果用户输入的时间格式不正确,怎么判断是否合法,怎么提醒用户。后来通过上网查才知道原来日期控件还有别的样式。
其实DTPicker日期控件有一个Format属性,一般默认是1。
Format属性:0-dtpLongDate ‘显示系统的长日期格式:2017年X月X日
1-dtpShortDate ‘显示短日期格式
2-dtpTime ‘显示时间格式:比如,HH:MM:SS
3-dtpCustom ‘可以自定义格式
当选择格式为3的时候,然后将CustomFormat 设置即可(Format不为3时,该属性不可用)
dtpicker1.Format=dtpCustom
dtpicker1.CustomFormat=Format("你需要的日期或时间格式")
select语句
Select Case <指示变量或表达式> Case <情形1> <语句组1> Case <情形2> <语句组2> .... Case Else <默认语句组,以上语句组都因情形不符合实际时执行> End Select
其中,表述情形的关键字,有IS和TO。Is和To用来比较大小。多个情形要并列在一起时,使用逗号(英文)连接。
在“<指示变量或表达式>”不是True或False关键字时,逻辑运算(And、Or、Not)会没有意义。在“<指示变量或表达式>”是True或False关键字时,Is、To关键字没有意义。
Select Case true(也可以是False) Case <逻辑运算表达式1> <语句组1> Case <逻辑运算表达式2> <语句组2> .... Case Else <默认语句组,当以上任何逻辑运算都为False时执行> End Select
自己的一些小想法
由于一开始自己一直在纠结怎么判断填写的日期是否合法,浪费了我一些时间,在网上找判断时间的函数没有找到,所以只能自己琢磨了。后来知道了日期控件,就不用这种方法了,不过我自己也思考了一下。
1.规定文本框的最大输入长度是8位,并且只能输入数字、退格和标点符号。如果用户按下其他的键,就提醒用户用正确的日期格式填写。
2.写一个判断是否是正确的时间格式的函数。
'判断输入的内容是否是合法时间
Public Function IsTime(str As String) As Boolean
If ((Left(str,2) > 24) Or (Mid(str,4,2) > 60) Or (Right(str,2) > 60)) Then
IsTime = False
Else
IsTime = True
End If
End Function
3.如果字段选择了上机时间和下机时间,就调用函数,判断一下是否是正确的时间格式。
If 格式不对 then
清空内容
获得焦点
退出过程
else
format(txtcontent.text,"HH:MM:SS") '转格式
(PS:只是自己的一些小思考,并没有试验过,如果有不对的地方还请各位多多包涵!请帮我指出)
代码
Private Sub cmdSelect_Click()
Dim txtsql As String
Dim msgtext As String
Dim mrc As ADODB.Recordset
Dim strField(3) As String
If Not Testtxt(Trim(cboField(0).Text)) Then
MsgBox "请输入字段名!",vbOKOnly + vbExclamation,"警告"
cboField(0).SetFocus
Exit Sub
End If
If Not Testtxt(Trim(cboOperaChar(0).Text)) Then
MsgBox "请输入操作符!","警告"
cboOperaChar(0).SetFocus
Exit Sub
End If
If (cboField(0).Text = "上机日期" Or cboField(0).Text = "下机日期" Or cboField(0).Text = "上机时间" Or cboField(0).Text = "下机时间") Then
txtContent(0).Text = DTPicker1(0).Value
Else
If Not Testtxt(Trim(txtContent(0).Text)) Then
MsgBox "请输入要查询的内容!","警告"
txtContent(0).SetFocus
Exit Sub
End If
End If
For i = 0 To 2
Select Case cboField(i).Text
Case "卡号"
strField(i) = "cardno"
Case "姓名"
strField(i) = "studentName"
Case "上机日期"
strField(i) = "ondate"
Case "上机时间"
strField(i) = "ontime"
Case "下机日期"
strField(i) = "offdate"
Case "下机时间"
strField(i) = "offtime"
Case "消费金额"
strField(i) = "consume"
Case "余额"
strField(i) = "cash"
Case "备注"
strField(i) = "status"
End Select
Next
Select Case cboRelation1.Text
Case "与"
relation1 = "and"
Case "或"
relation1 = "or"
End Select
Select Case cboRelation2.Text
Case "与"
relation2 = "and"
Case "或"
relation2 = "or"
End Select
txtsql = "select * from Line_Info where " & strField(0) & " " & cboOperaChar(0).Text & " '" & txtContent(0).Text & "'"
If Not Testtxt(Trim(cboRelation1.Text)) Then
GoTo result
Else
If Not Testtxt(Trim(cboField(1).Text)) Then
MsgBox "请输入字段名!","警告"
cboField(1).SetFocus
Exit Sub
End If
If Not Testtxt(Trim(cboOperaChar(1).Text)) Then
MsgBox "请输入操作符!","警告"
cboOperaChar(1).SetFocus
Exit Sub
End If
If (cboField(1).Text = "上机日期" Or cboField(1).Text = "下机日期" Or cboField(1).Text = "上机时间" Or cboField(1).Text = "下机时间") Then
txtContent(1).Text = DTPicker1(1).Value
Else
If Not Testtxt(Trim(txtContent(1).Text)) Then
MsgBox "请输入要查询的内容!","警告"
txtContent(1).SetFocus
Exit Sub
End If
End If
txtsql = txtsql & " " & relation1 & " " & strField(1) & " " & cboOperaChar(1).Text & " '" & txtContent(1).Text & "'"
If Not Testtxt(Trim(cboRelation2.Text)) Then
GoTo result
Else
If Not Testtxt(Trim(cboField(2).Text)) Then
MsgBox "请输入字段名!","警告"
cboField(2).SetFocus
Exit Sub
End If
If Not Testtxt(Trim(cboOperaChar(2).Text)) Then
MsgBox "请输入操作符!","警告"
cboOperaChar(2).SetFocus
Exit Sub
End If
If (cboField(2).Text = "上机日期" Or cboField(2).Text = "下机日期" Or cboField(2).Text = "上机时间" Or cboField(2).Text = "下机时间") Then
txtContent(2).Text = DTPicker1(2).Value
Else
If Not Testtxt(Trim(txtContent(2).Text)) Then
MsgBox "请输入要查询的内容!","警告"
txtContent(2).SetFocus
Exit Sub
End If
End If
txtsql = txtsql & " " & relation2 & " " & strField(2) & " " & cboOperaChar(2).Text & " '" & txtContent(2).Text & "'"
End If
End If
result:
Set mrc = Executesql(txtsql,msgtext)
If mrc.EOF = True Then
MsgBox "该条件的数据不存在!","警告"
Else
On Error Resume Next
With MSFlexGrid1
.Rows = 1
.ColWidth(-1) = 1800
.ColAlignment(-1) = 4
.TextMatrix(0,0) = "卡号"
.TextMatrix(0,1) = "姓名"
.TextMatrix(0,2) = "上机日期"
.TextMatrix(0,3) = "上机时间"
.TextMatrix(0,4) = "下机日期"
.TextMatrix(0,5) = "下机时间"
.TextMatrix(0,6) = "消费金额"
.TextMatrix(0,7) = "余额"
.TextMatrix(0,8) = "备注"
Do While Not mrc.EOF
.Rows = .Rows + 1
.TextMatrix(.Rows - 1,0) = Trim(mrc.Fields(1))
.TextMatrix(.Rows - 1,1) = Trim(mrc.Fields(3))
.TextMatrix(.Rows - 1,2) = Trim(mrc.Fields(6))
.TextMatrix(.Rows - 1,3) = Trim(mrc.Fields(7))
.TextMatrix(.Rows - 1,4) = Trim(mrc.Fields(8))
.TextMatrix(.Rows - 1,5) = Trim(mrc.Fields(9))
.TextMatrix(.Rows - 1,6) = Trim(mrc.Fields(11))
.TextMatrix(.Rows - 1,7) = Trim(mrc.Fields(12))
.TextMatrix(.Rows - 1,8) = Trim(mrc.Fields(13))
mrc.MoveNext
Loop
End With
End If
mrc.Close
End Sub