VBA 类模块系列之十一——类代码中的警察

好吧,我承认本篇的标题有点哗众取宠,不过这是我能想到的最佳的类比方式——以你最容易理解的方式——把我想谈的讲清 … 继续阅读“VBA 类模块系列之十一——类代码中的警察”

好吧,我承认本篇的标题有点哗众取宠,不过这是我能想到的最佳的类比方式——以你最容易理解的方式——把我想谈的讲清楚。类代码中的警察就是类代码中的错误处理

我们先来谈谈标准模块或者窗体模块中的错误处理。

作为一个有一定VBA编程经验的你,应该写过错误处理代码。我们来举个例子,在Access中新建一个空白的窗体,然后拖一个按钮到这个窗体上,窗体和按钮的名字都用默认的就好了,保存以后进入到IDE界面,为按钮的单击事件写一段简单的代码如下:

'窗体1中的代码模块
Option Compare Database
Option Explicit

Private Sub Command0_Click()
On Error GoTo ErrHandler
    Dim a As Double
    Dim b As Double
    a = 1
    b = a / 0
ExitProcedure:
    On Error Resume Next
    '退出前的善后工作
Exit Sub
ErrHandler:
    MsgBox "错误代码: " & Err.Number & vbCrLf & _
           "错误描述: " & Err.Description & vbCrLf & _
           "错误来源: " & Err.Source, _
           vbCritical, _
           "Command0_Click 报错"
    Resume ExitProcedure
End Sub

这个子程序除去错误处理代码以后,非常简单,声明了2个变量,给变量a赋值为1,然后用1除以0的值,赋给变量b。大概没有人能写出比这还蠢的代码了。^_^ 之所以要这么干,就是故意让警察抓个现行。

警察在哪呢?第6行代码就是!第6行代码翻译成大白话就是:如果在接下来的代码(从第7行开始)中发现了违法的代码,就铐起来带到名叫“ErrHandler”警察局,“ErrHandler”警察局在哪里?第15行。为什么警察局的名字叫“ErrHandler”?呃,这个名字的意思是“错误处理”,其实取什么名字是你说了算,我一般取这个名字的警察局,你可以换成你喜欢的名字。

第10行代码是一个非常典型的运行时违法代码,或者叫运行时出错代码,计算机无法将0作为除数计算一个结果给你。

  • 为什么我这里要加一个“运行时”?因为第10行代码在编译的时候,不会报错,只有在运行的时候才会。
  • 为什么在编译的时候不会报错?呃,你可以把0想象成一个参数,编译的时候,这个参数的值还没有确定,只有在代码运行的时候,发现这个参数是0,然后作为除数,参与计算,就报错了。
  • 为什么我们不考虑编译时的违法代码?因为如果编译的时候发现了违法代码,比如使用了未定义的变量名,编译器会报错,你不去修改这些错误代码,你连运行都无法运行。
  • 还有别的运行时出错代码吗?呃,有的,多了去了。比如代码去打开一个不存在的文件,数组变量越界访问等等。

好了,关于运行时出错代码的十万个为什么到此结束,假定你都理解了。我们从头来捋一遍。

  • 我们放置了一个警察在第6行代码中,告诉它,如果发现运行时的出错代码,就铐起来带到“ErrHandler”警察局。
  • 当程序运行到第10行的时候,代码运行出错了
  • 所以程序就从第10行跳到了15行,警察局的位置,然后接着往下执行。
  • MsgBox向你检讨错误编号,错误描述,错误来源。
  • 接下来执行第21行代码,Resume ExitProcedure,这句代码的意思翻译过来就是说:好了,警察局问话结束,该交代的都交代了,撤销你的案底(Resume),然后去ExitProcedure报到把。
  • 然后程序跳到第11行接着往下执行
  • 第12行代码与第6行代码很像,也是放置了一个警察,但是这回不是让它铐起来带回警察局了,而是直接撤销案底(Resume),接着往下执行(Next)。然后如果在执行到第14行之前,遇到任何执行错误,通通就地无罪释放。
  • 最后到第14行,结束程序的执行。

我感觉我刚刚写了一篇侦探小说。^_^ 本来只想简单介绍一下背景的,结果一发不可收拾。。。。。。本篇就作为警察故事一吧。

既然想好了写个警察故事二,那在这个警察故事一中,在加点料。

关于错误处理代码,除了刚刚介绍的那些意外,还有一个也很重要的代码:

On Error GoTo 0

如果让人工智能来推断这句代码的意思,应该就是:设置一个警察,一旦发现运行时错误,就把它拷起来带到叫做0的警察局。哈哈,所以说人工智能还是很蠢的。这句代码真正的含义是:从这句代码开始,把警察撤走。

什么?把警察撤走了?那出了运行时错误,谁管?把一个小县城的警察局撤销了,这个小县城的违法犯罪你说归谁管?当然是上一级单位,市警察局管了。这就相当于,你的子程序代码中没有任何错误处理程序,如果运行时出错,就归调用你的子程序的程序(上级单位)的警察管了。

最后再提出一个问题,如果在警察局里面发生了运行时错误,会怎么样?你可以自己写代码验证一下你的直觉。^_^

好吧,希望你对错误处理代码有更深刻的理解,这样在类中的错误处理代码才更容易掌握。

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注