VBA学习笔记1:错误语句的处理方式

案例分析:现有工作簿A和工作簿B,A中有一些工作表与B中的工作表同名,也有一些工作表B中没有。需要把A和B同名的那些工作表内容从B数值化粘贴到A对应的表里。

此案例看起来比较简单,最重要的一步就是复制粘贴,很容易实现;通过A工作簿里的表名去找B里对应的表也比较容易,把表名设定为变量即可。难点在于A有,B没有的工作表如何处理。

首先设置几个变量,便于后面的引用:

   Dim Nonesht As String  '在B中找不到对应工作表的提示
   Dim shtname As String  '需要复制粘贴的表名
   Dim Desbook As Workbook '目标工作簿A
   Dim Soubook As Workbook '来源工作簿B

因为工作簿名比较长,所以用Desbook和Soubook来表示。用如下语句开启循环,确保A中的每个工作表都能进入循环中。同时为shtnam赋值当前A中工作表的表名,以便后续复制粘贴时可以引用。

For i = 1 To Desbook.Worksheets.Count
Shtname = Desbook.Worksheets(i).Name

如果A中的工作表在B中没有对应,我初步的想法是用goto语句跳转。如何判断shtname是否在B工作簿中呢?我用了is nothing语句

If Soubook.Worksheets(Shtname) Is Nothing Then
      GoTo skip
  Else

但是这个语句会报”下标溢出“的错误,因为如果Shtname不在B里,那表达式Soubook.Worksheets(Shtname)就是错误的。

所以我在前面加上了on error resume next的语句,期望如果报错忽略继续运行,结果依然报错。

这样犯了逻辑上的错误。系统无法判断一个错误的东西是不是不存在!既然Worksheets(Shtname)的语句错误,那后面is nothing根本无从谈起。

改进后如下:

    On Error Resume Next
    shtnam = Soubook.Worksheets(Shtname).Name
        If Err <> 0 Then
            Nonesht = Nonesht & Chr(13) & Shtname
            GoTo skip
     End If

新增一个shtnam的变量,用来存放目前正在循环的表名在B中对应的表的表名。就是说,假设Shtname在B中存在,那么把Shtname的name赋值给shtnam,如果不存在,则获取B中这个表名的动作会出错,程序忽略后进入下一步。

如果上一步的错误代码不等于0,即出现了错误,那么将在Nonesht变量中记录错误表名,并跳转到后面的skip步骤去。这样就解决了判断B中是否存在相对应的表的问题。

别忘了,在进行了以上步骤后,还要加上On Error GoTo 0语句重新开启错误提示,否则后面的复制粘贴步骤如果有错误,那也无从得知。

总结:要想通过错误语句来跳过循环,第一步先要用On error语句跳过下面的”错误陷阱“;第二步则是设定”错误陷阱“,这个”陷阱“必须是程序能够识别的。第三步就可以用if err <>0语句判断”错误陷阱“的存在,进行下一步操作。最后一步是及时开启正常的错误处理,避免后续语句出现问题。

评论