发生错误的原因:在我还没敲学生管理系统的时候,就听一些正在敲学生的小伙伴们说我们参照的资料书里有好多错误,而且我就相信了,当然事实也确实如此。所以我就发生了一些比较意外的错误。比如说在修改学籍信息窗体的代码里有一个更改数据的过程,我想当然的把Dim mrcc as ADODB.Recordset当成Dim mrc as ADODB.Rcordset了,我认为这是书里的错误,所以就把这个过程里的所有mrcc写成了mrc。但是我还是用的mrc,而且把它改好了,其中的辛酸我就不说了。
遇到的问题以及解决过程:然后当我点击更新数据的时候,它第一次显示如下的错误。
当我点击调试的时候,代码跳到了mrc.Delete这一句。
当时我具体也不知道什么原因,所以我就想是不是可以删了它。此时我没有修改学号,再次更新的时候结果无法修改,显示学号重复?!
所以我又试了一次,这次我不修改学号还不行吗?我再次更新,随后显示更新成功。可把我给高兴坏了,可是这种高兴连一分钟都没有维持,当我查看更新好的数据的时候,发现有两个学号一样的数据,这我就纳闷了。原来数据没有更新成功,而是重新添加了一条而且学号还能一样,显然这是不符合逻辑的。而且既然是修改学籍信息,那么学号也应该可以修改呀。
我不知道是什么原因,这时候我又重新看了一遍书上的代码,当我把mrc改为mrcc的时候,发现他居然可以修改成功了,而且还没有重复的数据,就是更改了。我好好想了想,终于知道mrcc是什么意思了,原来它是又重新定义了一个新的数据集对象,专门用来查询修改后是否有和数据库里的学号重复的数据。
下面让我捋一捋这个修改学籍信息的过程,它是在窗体加载的时候就执行数据查询,在窗体中显示第一条数据并用书签记下当时的位置,当你点击更改数据按钮的时候,它是先把这条正在更改的数据删除,然后检查更改后的学号是否有重复的,如果没有重复的就执行更改操作,然后回到当初用书签记录的位置。
既然问题解决了,那我想如果我就想用一个mrc数据集对象可不可以呢?可是怎么解决原来出现的错误呢?对于实时错误‘91’,我自己从错误中得到的答案就是要么变量没有定义;如果是数据集对象的错误,就是sql语句写错了;还有一种情况就是控件的名称与代码里的不匹配。所以我回头发现在更改数据的过程里多了一条Dim mrc as ADODB.Recordset语句,那么为什么呢?原因就是我们在一开始加载窗体的时候,就执行了查询语句并把结果赋给了这个mrc数据集对象,所以如果在过程开始的时候用Dim再定义一遍,那么原来赋给它的值就没有了,当你mrc.Delete的时候就会出错,没有数据还怎么删除呢?
弄清这个原因之后就好解决了,当我删除这条语句又出现了新的错误,就是更新完之后点击上一条记录和下一条记录的时候他不能跳转了,失去了作用。为什么呢?当时我想难道这个想法行不通吗?我甚至想过放弃这个方法,可是当我吃了个饭回来之后,就豁然开朗了,原来数据集对象中还是执行查询和输入的学号是否有重复记录的结果,就是下面这条语句
所以,我又在个更改完数据代码之后的地方加了一条语句,
| 'SQL语句 |
txtSQL = "select * fromstudent_info"
'执行查询操作
'Set mrc = ExecuteSQL(txtSQL,MsgText)
移动到第一条记录
然后整个窗体就可以正常的运行了。以下是我改完之后的代码。
Private Sub cmdUpdate_Click()
Dim txtSQL As String
Dim MsgText As String
mybookmark = mrc.Bookmark
'判断是否处于修改状态
If mcclean Then
MsgBox "请先修改学籍信息", vbOKOnly + vbExclamation, "警告"
Exit Sub
End If
'判断学号是否为空
If Not Testtxt(Trim(txtSID.Text)) Then
MsgBox "请输入学号!", vbOKOnly + vbExclamation, "警告"
txtSID.SetFocus
Exit Sub
End If
'判断姓名是否为空
If Not Testtxt(Trim(txtName.Text)) Then
MsgBox "请输入姓名!", vbOKOnly + vbExclamation, "警告"
txtName.SetFocus
Exit Sub
End If
'判断性别是否为空
If Not Testtxt(Trim(comboSex.Text)) Then
MsgBox "请选择性别!", vbOKOnly + vbExclamation, "警告"
comboSex.SetFocus
Exit Sub
End If
'判断出生日期是否为空
If Not Testtxt(Trim(txtBorndate.Text)) Then
MsgBox "请输入出生日期!", vbOKOnly + vbExclamation, "警告"
txtBorndate.SetFocus
Exit Sub
End If
'判断班号是否为空
If Not Testtxt(Trim(comboClassno.Text)) Then
MsgBox "请选择班号!", vbOKOnly + vbExclamation, "警告"
comboClassno.SetFocus
Exit Sub
End If
'判断联系电话是否为空
If Not Testtxt(Trim(txtTel.Text)) Then
MsgBox "请输入联系电话!", vbOKOnly + vbExclamation, "警告"
txtTel.SetFocus
Exit Sub
End If
'判断入校日期是否为空
If Not Testtxt(Trim(txtRudate.Text)) Then
MsgBox "请输入入校日期!", vbOKOnly + vbExclamation, "警告"
txtRudate.SetFocus
Exit Sub
End If
'判断家庭住址是否为空
If Not Testtxt(Trim(txtAddress.Text)) Then
MsgBox "请输入家庭住址!", vbOKOnly + vbExclamation, "警告"
txtAddress.SetFocus
Exit Sub
End If
'判断学号是否为数字
If Not IsNumeric(Trim(txtSID.Text)) Then
MsgBox "学号请输入数字!", vbOKOnly + vbExclamation, "警告"
txtSID.SetFocus
Exit Sub
End If
'判断是否有重复记录
txtSQL = "select * from student_info where student_id = '" & Trim(txtSID.Text) & "'"
Set mrc = ExecuteSQL(txtSQL, MsgText)
If mrc.EOF = False Then
MsgBox "学号重复,请重新输入!", vbOKOnly + vbExclamation, "警告"
txtSID.SetFocus
Else
If Not IsDate(txtBorndate.Text) Then
MsgBox "出生日期应输入日期格式(yyyy-mm-dd)!", vbOKOnly + vbExclamation, "警告"
txtBorndate.SetFocus
Else
'SQL语句
txtSQL = "select * from student_info"
'执行查询操作
Set mrc = ExecuteSQL(txtSQL, MsgText)
mrc.Bookmark = mybookmark
mrc.Delete
txtBorndate.Text = Format(txtBorndate, "yyyy-mm-dd")
If Not IsDate(txtRudate.Text) Then
MsgBox "入校日期应输入日期格式(yyyy-mm-dd)!", vbOKOnly + vbExclamation, "警告"
txtRudate.SetFocus
Else
txtRudate.Text = Format(txtRudate, "yyyy-mm-dd")
mrc.AddNew
mrc.Fields(0) = Trim(txtSID.Text)
mrc.Fields(1) = Trim(txtName.Text)
mrc.Fields(2) = Trim(comboSex.Text)
mrc.Fields(3) = Trim(txtBorndate.Text)
mrc.Fields(4) = Trim(comboClassno.Text)
mrc.Fields(5) = Trim(txtTel.Text)
mrc.Fields(6) = Trim(txtRudate.Text)
mrc.Fields(7) = Trim(txtAddress.Text)
mrc.Fields(8) = Trim(txtComment.Text)
mrc.Update
MsgBox "修改学籍信息成功!", vbOKOnly + vbExclamation, "修改学籍信息"
'SQL语句
txtSQL = "select * from student_info"
'执行查询操作
Set mrc = ExecuteSQL(txtSQL, MsgText)
'移动到第一条记录
mrc.Bookmark = mybookmark
Call viewdata
Frame1.Enabled = True
'使各个按钮有效
cmdFirst.Enabled = True
cmdPrevious.Enabled = True
cmdNext.Enabled = True
cmdLast.Enabled = True
'使各个文本框失效
txtSID.Enabled = False
txtName.Enabled = False
comboSex.Enabled = False
txtBorndate.Enabled = False
comboClassno.Enabled = False
txtRudate.Enabled = False
txtTel.Enabled = False
txtAddress.Enabled = False
txtComment.Enabled = False
mcclean = True
End If
End If
End If
End Sub
通过比较我自己修改的代码和源码,发现还是源码比较简单,直接定义两个数据集对象省下了几条代码,而且还比较容易理解和简单。我的方法就是直接使用一个数据集对象,执行的结果需要转换。虽然看起来我的修改是多此一举,但是通过调试修改,我明白了整个窗体的运行过程。通过这个窗体,我知道了能用两个变量来解决,坚决不要用一个变量,否则的话容易陷在代码里很难跳出来,所以尽量用多个变量解决问题。这次真是一个血的教训。