2017-03-03 77 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