2017-03-03 194 views
2

因此,有几个SO问题和Google结果出现在“On Error GoTo一次执行”之下,几乎在每种情况下推荐的解决方案是添加Err.ClearResume的某个论坛来清除错误。 VBA错误一次只能处理一个,所以需要清除它们。VBA:Err.Clear,Resume,Resume Next不会阻止On Error GoTo从只执行一次

已经实现了这些,正如你可能已经猜到的,我遇到了这个问题,其中On Error GoTo只执行一次,我不明白为什么。

下面是我的循环。我确实在顶部留下了一些代码,因为它有相当一部分,并且不相关。大多数用户提示和制作数组。为了解释一下发生了什么,conos()是一个包含特定列值的数组。根据文件名的一部分,它会搜索数组中的代码,以获取其对应于该行的索引。

如果没有Match它会触发该错误。这只是说有一个文件,但没有联系发送给。它应该跳到NoContact并创建这些文件的列表。

因此,对于我的文件,第一个有联系人并生成电子邮件,第二个不跳到NoContact并将该文件添加到列表中。另外五个联系人运行,然后转到另一个应该转到NoContact,但Unable to get the Match property of the WorksheetFunction class出现。

看来错误没有从第一个清除。不知道为什么。

For Each objFile In objFolder.Files 

    wbName = objFile.Name 

    ' Get the cono along with handling for different extensions 
    wbName = Replace(wbName, ".xlsx", "") 
    wbName = Replace(wbName, ".xlsm", "") 
    wbName = Replace(wbName, ".xls", "") 

    ' Split to get just the cono 
    fileName() = Split(wbName, "_") 
    cono = fileName(2) 

    ' Create the cell look up 
    c = Cells(1, WorksheetFunction.Match("Cono", cols(), 0)).Column 

    ' ******************** ISSUE IS HERE *************************** 
    On Error GoTo NoContact 
    r = Cells(WorksheetFunction.Match(cono, conos(), 0), c).Row 
    Cells(r, c).Select 

    ' Fill the variables 
    email = Cells(r, c).Offset(0, 1).Value 
    firstName = Cells(r, c).Offset(0, 3).Value 
    lastName = Cells(r, c).Offset(0, 4).Value 
    account = Cells(r, c).Offset(0, -2).Value 
    username = Cells(r, c).Offset(0, 6).Value 
    password = Cells(r, c).Offset(0, 7).Value 
    fPassword = Cells(r, c).Offset(0, 8).Value 

    ' Mark as completed 
    Cells(r, c).Offset(0, 9).Value = "X" 

    ' Set the object variables 
    Set OutApp = CreateObject("Outlook.Application") 
    Set OutMail = OutApp.CreateItem(0) 

    ' Body of the email 
    str = "Hi " & firstName & "," & vbNewLine & vbNewLine & _ 
      "This is line 1" & vbNewLine & _ 
      "This is line 2" & vbNewLine & _ 
      "This is line 3" & vbNewLine & _ 
      "This is line 4" 

    ' Parameters of the email 
    On Error Resume Next 
    With OutMail 
     .To = email 
     .CC = "" 
     .BCC = "" 
     .Subject = "This is the Subject line" 
     .Body = str 
     'You can add a file like this 
     '.Attachments.Add ("C:\test.txt") 
    End With 
    On Error GoTo 0 

    ' Based on the user prompts, whether or not the emails will be sent without checking them first 
    If finalCheck = vbYes Then 
     OutMail.Send 
    Else 
     OutMail.Display 
    End If 

NoContact: 

    ' Determiine which files don't have a corresponding email and add to list 
    If email = Empty Then 
     If conoB <> "" Then 
      conoB = conoB & ", " & cono 
     Else 
      conoB = cono 
     End If 
    End If 

    Err.Clear 

    ' Clear variables for next use 
    Set OutMail = Nothing 
    Set OutApp = Nothing 
    cono = Empty 
    email = Empty 
    firstName = Empty 
    lastName = Empty 
    account = Empty 
    username = Empty 
    password = Empty 
    fPassword = Empty 

Next: 
+3

没有解决您的错误处理问题,但可以使用'Application.Match()'而不是'WorksheetFunction.Match()'来避免整个问题。如果找不到匹配项,后者会抛出运行时错误,而前者会返回一个错误值,您可以使用IsError()进行测试 - 管理该错误值比捕获运行时错误要容易得多。 –

+0

YowE3K在回答你为什么仍然遇到问题的时候很有用。只需要指出在错误处理块上方的代码中添加了'Exit Sub',而您的代码没有这个。如果没有Exit Sub,即使这里没有错误,代码也会在最后运行错误处理程序。这可能会导致它自己的错误。 –

+0

@BrandonBarney - OP在'NoContact'标签之前不能有'Exit Sub',因为他们希望在执行下一次迭代之前执行其余的代码。 – YowE3K

回答

4

Err.Clear只是清除关于从Err对象的最后一个错误的信息 - 它不退出的错误处理方式了。

如果检测到错误,您的On Error GoTo NoContact被调用时,你的代码就会下降到NoContact标签,最后发现它的方式回到你的For Each objFile In objFolder.Files循环的开始,同时仍然在错误处理模式

如果在仍处于错误处理模式时发生其他错误,VBA将抛出错误,因为它不能再陷入错误。

你应该组织你的代码一起的

For Each objFile In objFolder.Files 
     '... 
     On Error GoTo NoContactError 
     '... 
NoContact: 
     '... 
    Next 
    '... 
    Exit Sub 

NoContactError: 
    'Error handling goes here if you want it 
    Resume NoContact 
End Sub 

线但是,正如蒂姆·威廉姆斯,评论 - 这是更好的避免需要On Error错误处理尽可能的情况。

+0

这确实奏效,但在我测试完这个之后选择了Tim Williams的建议。 – sockpuppet

+0

@sockpuppet - 我很高兴你和Tim的建议一起使用 - 这是我为避免首先使用'On Error'而做的。 – YowE3K