2017-08-02 71 views
0

我有一个宏,并且代码的一部分与: 1)检测列是否包含空单元格 - 如果是的话用一些值填充它们 2)检测列包含单元格包含错误(如N/A),如果这样填充它们的某些值VBA在代码执行期间更改错误处理方法

现在,如果该列中没有错误/空单元格,找到它们的行会给出“运行时错误1004否细胞被发现“。

我使用错误处理来跳过这与GoTo。

下面是代码 - 第一个错误处理GoTo完美工作,第二个错误处理预期错误,虽然有错误处理GoTo集合,但似乎不起作用。代码注释:

On Error GoTo EErrorOne 


'depending on file I get, below line will generate error and code successfully skips to ErrorOne label 

Workbooks(nazwawb).Sheets(szitnr).Columns(ktorepole).SpecialCells (xlCellTypeBlanks) 

' code to be skipped 

    Workbooks(nazwawb).Sheets(szitnr).Columns(ktorepole).Select 
    Selection.SpecialCells(xlCellTypeBlanks).Select 
    Selection.Value = "Some Value" 

' end of code to be skipped 

EErrorOne: 

' successfully skipped error line by now. Below line should set a new Error handling procedure. 

On Error GoTo EErrorTwo 



Workbooks(nazwawb).Sheets(szitnr).Columns(ktorepole).Select 

' Below line generates an error but does not skip to EErrorTwo label as detailed in the current Error handling procedure 

Selection.SpecialCells(xlCellTypeFormulas, 16).Select 

' code to be skipped 


Selection.SpecialCells(xlCellTypeFormulas, 16).Select 
    Selection.Value = "Some Value" 

' end of code to be skipped 


EErrorTwo: 



' Below line should reset error handling procedure to normal for subsequent handling of other errors: 
On Error GoTo 0 

看来,错误处理程序(转到特定的标签)被忽略,相反,错误消息显示为,如果错误处理被重置为0转到如何跳过第二错误?

+0

最好是创建不依赖错误处理程序来运行的代码。请检查导致错误的情况,并跳过您知道会导致错误的代码。 – braX

+2

你的代码做了太多事情。每个过程一个处理器。您在处理错误时无法处理新的错误,您需要*首先处理第一个错误*。 Error Error在错误处理程序中没用,*你已经处于错误状态*,你期望发生什么? FWIW将很快成为[Rubberduck](http://rubberduckvba.com)的检查。 –

+0

braX,我试着将相关的单元格分配给一个范围,然后设置是否不是rangename,但它仍然评估为错误消息。 Mat's Mug,我不是这方面的专家,虽然我怀疑我需要在重新开始之前退出错误处理,但我认为On Error GoTo 0会重置错误处理 - 事实证明它应该已经On Error GoTo -1,正如我接受的问题所回答的那样。无论如何,我没有重置错误处理,我应该有,这是我的问题的解决方案。谢谢大家 – FilipB

回答

2

内部错误处理例程,它好像定义新的错误处理程序将无法正常工作,除非你清除以前设置错误例程(https://excelmacromastery.com/vba-error-handling/):

'... 
EErrorOne: 
On Error GoTo -1 'Clears error trap flag 
On Error GoTo EErrorTwo 'Reset error handling 
'... 

编辑接受后:
正如所讨论的在评论中,On Error GoTo -1清除错误陷阱标记,而Err.Clear仅清除错误。
下面的代码通过创建两个错误并试图捕获它们来说明这一点。

On Error Goto -1允许第二个错误被On Error GoTo NextLabel行捕获,并且错误发生时代码跳转到标签。
Err.Clear将第一个错误保持为活动状态,因此当发生第二个错误时,会显示错误消息而不是跳转到标签的代码。

Sub ClearErr() 

    Dim x As Long 
    Dim y As Worksheet 

    'Jump to label when "Division by 0" occurs. 
    On Error GoTo ErrorLabel 

    x = 1/0 
    Debug.Print x 

ErrorLabel: 

    'On Error GoTo -1 'Next error is trapped. 
    Err.Clear 'Untrapped error on y=Worksheets(1) 

    'Jump to label when "Object Variable not set" occurs. 
    On Error GoTo NextLabel 

    y = Worksheets(1) 
    Debug.Print y.Name 

NextLabel: 

End Sub 
+0

'Err.Clear'也清除错误。 –

+0

@ DarrenBartrup-Cook'Err.Clear'清除错误,但不清除错误陷阱标志!试试看。 –

+1

它不?我得看看那个。我仍然建议跳出主要过程来处理任何错误并使用'RESUME'。 –

5

你不会在发生错误时清除你的错误,只是想跳过它们,代码想知道错误是怎么回事。

随着芯片皮尔森说,他的网站:

当提出的第一个错误,执行转移到线 以下ERR1:。错误处理程序仍处于活动状态时,会发生第二 错误,因此第二个错误是不是由在 错误陈述

被困,并与

简历语句指示VBA恢复继续执行在代码中指定的 点。只能在处理 块的错误中使用Resume;任何其他用途都会导致错误。此外,恢复是唯一的方式,除了退出程序,摆脱错误处理 块。不要使用Goto语句将错误处理块的代码执行从 中指出。这样做会导致错误处理程序 奇怪的问题。 http://www.cpearson.com/excel/errorhandling.htm

理想的方法是避免在首位的错误 - 检查工作簿存在打开它之前,检查工作簿中的纸张存在试图引用它之前,并且如果发生错误跳出的例程的主体,处理错误,然后再跳回来。

举个例子:

Sub Test() 

    On Error GoTo ERR_HANDLE 

    '.... code .... 

FAST_EXIT: 
    'Code to tidy up, clear references etc before finishing. 

Exit Sub 

ERR_HANDLE: 
    Select Case Err.Number 
     Case 1004 
      'Code to resolve error 
      '. 
      '. 
      'Resume - clear error, jump back to line that caused it. 
      'Resume Next - clear error, jump to line after the one that caused error. 
      'Resume FAST_EXIT - clear error and go to line label. 

     Case 92 'Do something else to resolve error. 

     Case Else 
    End Select 

End Sub 
+2

为了进一步澄清Darren的回答,错误处理程序一直处于激活状态,直到代码被明确告知。标准错误处理使用'On Error GoTo SomeLineLabel:错误处理后的代码:恢复或继续下一步'。最终的说法实质上是清除错误。 –

+0

@Brandon说的。正试图通过_clear错误来解决这个问题,并跳回到导致它的行._。需要更明确的是_clear error_在每种情况下都很重要。 –