设为首页收藏本站Access中国

Office中国论坛/Access中国论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

12下一页
返回列表 发新帖
查看: 4391|回复: 12
打印 上一主题 下一主题

[Access本身] 灵活运用错误处理

[复制链接]
跳转到指定楼层
1#
发表于 2003-10-10 10:28:00 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
今天在爱赛思看见有讨论如何处理错误的,很有代表性,看来有一些初学者对错误处理不是很清楚。而在两个论坛上,有关错误处理的讨论也不是很多。所以,我就借此机会,说说自己的一些体会,希望能够起到抛砖引玉之效。

在爱赛思,有提问说,
1楼:setwarning 语句不能屏蔽error,有别的办法吗?
2楼回复说
例子
Private Sub 命令6_Click()
On Error GoTo Err_命令6_Click
'////////////////////////////////
Exit_命令6_Click:
  Exit Sub
Err_命令6_Click:
  MsgBox Err.Description
  Resume Exit_命令6_Click   
End Sub

3楼回复说:
我觉得屏蔽error不是一个好注意!

屏蔽错误这个问题,要辩证地看。虽然“错误”这个词看上去蛮可怕的,但这只是人的感觉。有时候只是提醒,甚至是access本身设计不良。
1楼的同学想用setwarning来处理错误,这就对不上号了。setwarning是处理系统信息,不是错误。不要把两个不同的概念弄混了。
2楼的同学摘录了一段代码,如果他把倒数第3条语句MsgBox Err.Description注释掉,就回答了1楼的问题。当然,这样的话,如果错误导致某个纪录不能被修改,用户是不知道的了。显然,这样的屏蔽错误方法不好。所以,重要的是需要知道什么样的错误发生,然后针对某种错误,要做什么。
可以仔细研究一下access的err对象,非常有意思。err.Description是返回错误的内容,而err.number则返回错误的号码。这对编程非常有用。结合err的其他属性,大多数情况下可以知道发生了什么类型的错误,原因在那里,有什么影响。这样,在on error语句捕捉到错误以后,你就可以将err.number等输出,分析不同错误的种类,然后进行处理。

为了更好的说明我的观点,下面我举个例子:
我有一个绑定纪录的窗体,用FORM_beforeUpdate事件来提醒是否修改或者回滚用户(Cancel=true, me.undo)的修改。但是,有一个问题,当用户修改了纪录,没有保存或取消,而是直接点窗体右上角的X来关闭窗体,这时候,FORM_beforeUpdate事件先触发,弹出提醒,如果用户选择不保存记录,系统会产生一个错误,客户被告知更改数据库时出现了一个错误,如果关闭窗体,记录将不会被保存。由于用户确实是选择取消修改的,所以系统的这个错误信息是废话,要屏蔽。在窗体FORM_error事件中,输出错误号,是2169。所以,我就这样改写FORM_error事件:
Private Sub FORM_Error(DataErr As Integer, response As Integer)
Select Case DataErr
  Case 2169
    response = acDataErrContinue
  Case Else
    response = acDataErrDisplay
End Select
End Sub

如果错误号是2169,那么就让代码继续执行,否则(就是其他我们目前还没碰到的错误),就显示错误信息。 这个处理方法,干脆利落,比增加一个关闭按钮外加一大堆判断逻辑要好得多。

那么,大家常碰到的按钮单击事件,如何改写错误代码呢?
首先,还是按照标准的错误处理过程,捕捉任何错误,然后将错误号和描述输出:
Private Sub button1_Click()
On Error GoTo catch
  '这里是按钮处理程序主体
finally:
  '一些清除工作,例如set myRecordSet = Nothing等
  Exit Sub
catch:
  MsgBox Err.Number & "/" & Err.Description
  Resume finally   
End Sub

如果产生了错误,你也就知道了错误号和描述,假定错误号是513,然后你找一找原因。分析完毕后,知道了原因和如何处理之后,改写代码如下:
Private Sub button1_Click()
On Error GoTo catch
  '这里是按钮处理程序主体
finally:
  '一些清除工作,例如set myRecordSet = Nothing等
  Exit Sub
catch:
  if Err.Number = 513 then
     '针对已知错误的处理
  else
             '显示未知错误
    MsgBox Err.Number & "/" & Err.Description
  end if
  Resume finally   
End Sub

如果要处理数个错误,当然用select case...语句,注意要把最常发生的错误放在前面,这样可以提高程序的运行效率。

更进一步,可以创造错误,让其他程序去处理。例如,你有一个模块,是处理用户登陆的,这个模块被数个其它窗体调用。如果用户登陆过程当中有什么不对,那么最好的办法就是让这个模块产生错误,然后让调用它的程序根据这个错误决定采取什么样的对策。

模块程序
Public sub login(byVal userName As String, byVal pwd As String)
   '处理用户登陆,例如核对用户名、密码、取得权限等
   If '用户名不存在 then Err.Raise 513, "userLogin", "用户不存在"
   If '密码不对 then Err.Raise 514, "userLogin", "错误的密码"
   If '没能获取权限 then Err.Raise 515, "userLogin", "没有使用权限"
end sub

某个窗体调用时,代码看起来是这样的
Private sub btnOk_click()
On Error Goto catch
    Call login(txtName, txtPwd)
    '进入应用程序,关闭本窗体
finally:
    exit sub
catch:
    MsgBox Err.D
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享分享 分享淘帖 订阅订阅
2#
 楼主| 发表于 2003-10-10 10:35:00 | 只看该作者
错误信息真的不是敌人,它是程序员的好朋友。
3#
发表于 2003-10-10 16:01:00 | 只看该作者
很好!非常值的学习!
4#
发表于 2003-10-10 16:13:00 | 只看该作者
其實利用錯誤捕捉也就相當于
if,或select case 處理一樣的
只是換一了種判斷方式而已
另類一點
5#
发表于 2003-10-14 03:11:00 | 只看该作者
提示: 作者被禁止或删除 内容自动屏蔽
6#
发表于 2006-1-1 05:56:00 | 只看该作者
谢谢 又学到东西了

呵呵

7#
发表于 2006-1-2 05:41:00 | 只看该作者
错误信息是程序员的最好朋友。
8#
发表于 2006-1-4 04:26:00 | 只看该作者
我利用出错处理,解决了链接后台数据库的问题。

以前没有这样做时,如果变动了放数据库的盘符,老是出错,叫你调试。

现在好了,利用出错处理,如果未链接,就会打开“链接”窗体。

如果一经链接,就不会叫你打开“链接”窗体了。

这样做对否,请高手指导。



Private Sub cmdLogin_Click()
   On Error GoTo Err_cmdLogin_Click
       Dim intA As Integer
      
       i = i + 1
         
     If DLookup("[密码]", "用户", "[用户名]= """ & com用户 & """") = txt密码 Then
        msg = MsgBox("密码正确,欢迎进入!")
        DoCmd.close
        
    DoCmd.close acForm, "登陆背景", acSaveYes
   
    Dim stdocname As String
    Dim stLinkCriteria As String
    stdocname = ChrW(20027) & ChrW(25511) & ChrW(-26782) & ChrW(26495)
    DoCmd.OpenForm stdocname, , , stLinkCriteria
   
    Else
        If i < 3 Then
            MsgBox "密码错,请重新输入!"
            txt密码.Value = ""
            txt密码.SetFocus
        Else
            MsgBox "密码错,禁止进入!"
            Application.Quit
        End If
   
    End If
   
Exit_cmdLogin_Click:
    Exit Sub

Err_cmdLogin_Click:
   'MsgBox "未链接后台数据库!" & Chr(10) & Chr(10) & "请链接后台数据库。", vbExclamation + vbOKOnly, "提示信息"
   DoCmd.OpenForm "链接后台数据库", acNormal, "", "", , acNormal
   
    Resume Exit_cmdLogin_Click
End Sub

点击这里给我发消息

9#
发表于 2006-1-4 05:20:00 | 只看该作者
不错的贴子,很有代表性
10#
发表于 2007-1-12 21:30:00 | 只看该作者
有些帖子虽然老,但是很经典。希望大家多多学习提高!
您需要登录后才可以回帖 登录 | 注册

本版积分规则

QQ|站长邮箱|小黑屋|手机版|Office中国/Access中国 ( 粤ICP备10043721号-1 )  

GMT+8, 2024-4-29 19:27 , Processed in 0.098824 second(s), 33 queries .

Powered by Discuz! X3.3

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表