Excel VBA:On Error Goto语句不能在For循环中工作

我试图在excel中循环表格。 这个表格的前三列有文字标题,其余的有标题的date。 我想将这些date顺序地分配给Datetypes的variables,然后根据date执行一些操作

为此,我在myTable.ListColumns上使用了一个foreach循环。 由于前三列没有date标题,我试图设置循环,所以如果在将日志typesvariables赋值为标题string时出现错误,循环会直接进入下一列

这似乎适用于第一列。 但是,当第二列的头被“分配”到datetypesvariables时,macros即使在error handling块内也会遇到错误

Dim myCol As ListColumn For Each myCol In myTable.ListColumns On Error GoTo NextCol Dim myDate As Date myDate = CDate(myCol.Name) On Error GoTo 0 'MORE CODE HERE NextCol: On Error GoTo 0 Next myCol 

重申一下,这个错误是在循环的第二轮,在声明中引发的

 myDate = CDate(myCol.Name) 

任何人都可以解释为什么On Error语句停止工作?

使用所示的代码,当您执行next语句时,您实际上仍被认为处于error handling例程中。

这意味着后续error handling程序是不允许的,直到你从当前的error handling程序恢复。

更好的架构将是:

  Dim myCol As ListColumn For Each myCol In myTable.ListColumns On Error GoTo ErrCol Dim myDate As Date myDate = CDate(myCol.Name) On Error GoTo 0 ' MORE CODE HERE ' NextCol: Next myCol Exit Sub ' or something ' ErrCol: Resume NextCol 

这清楚地描述了来自常规代码的error handling,并确保当前正在执行的error handling程序完成,然后再尝试设置另一个处理程序。

这个网站有一个很好的问题描述:


error handling块和错误转到

error handling块(也称为error handling程序)是通过On Error Goto <label>:语句将执行转移到的一段代码。 这个代码应该被devise成解决问题并且在主代码块中恢复执行或者终止程序的执行。 您不能使用On Error Goto <label>:语句跳过行。 例如,下面的代码将无法正常工作:

  On Error GoTo Err1: Debug.Print 1 / 0 ' more code Err1: On Error GoTo Err2: Debug.Print 1 / 0 ' more code Err2: 

当第一个错误发生时,执行转移到Err1:的行。 发生第二个错误时,error handling程序仍处于活动状态,因此第二个错误不会由On Error语句捕获。

您需要在error handling代码中添加某种types的resume ,以表明error handling已经结束。 否则,第一个error handling程序仍处于活动状态,并且您永远不会“解决”。

请参阅http://www.cpearson.com/excel/errorhandling.htm (具体标题为“error handling块和错误转到”以及下一节)

paxdiablo接受的答案的后续行动。 这是可能的,允许两个错误陷阱在同一个子,一个接一个:

 Public Sub test() On Error GoTo Err1: Debug.Print 1 / 0 ' more code Err1: On Error GoTo -1 ' clears the active error handler On Error GoTo Err2: ' .. so we can set up another Debug.Print 1 / 0 ' more code Err2: MsgBox "Got here safely" End Sub 

使用On Error GoTo -1取消激活的error handling程序,并允许另一个设置(而err.clear不这样做!)。 这是不是一个好主意,只是作为一个读者的练习,但它的作品!

清除Err对象的所有属性设置与重置error handling程序不同。

尝试这个:

 Sub TestErr() Dim i As Integer Dim x As Double On Error GoTo NextLoop For i = 1 To 2 10: x = i / 0 NextLoop: If Err <> 0 Then Err.Clear Debug.Print "Cleared i=" & i End If Next End Sub 

你会注意到就像OP一样,当i =1时它会正确地捕捉到错误,但是当i = 2时它会在第10行失败,尽pipe我们使用了Err.Clear

其实,如果你想声明错误已经结束,你应该使用Err.Clear


简历试图带你到下一行,所以如果你的意思是跳过整段代码,并在其他地方继续因为错误,你会发现简历是一个痛苦。 对于你们中的一些人来说,不要把On Error看作只是为了捕捉实际的编程问题,而应该把它看作是一个像VB.Net一样的TryCatch。

对于那些不知道的人,当你写“ On Error ”时,你可以通过inputErr。来获得错误属性,从那里你将得到如下的列表…

在这里输入图像说明