2015-05-28 58 views
0

我試圖建立一個如下所示的結構。 其中我有一個循環,有時一個循環步驟可以返回錯誤,但我想跳過它並繼續循環直到結束。VBA錯誤句柄 - 恢復和打印錯誤

但是,如果任何循環執行有錯誤,我想知道它打印在單元格中的東西像「缺少負載:(1,20,36)」這個數字是唯一的值,我的循環變量之一接收。

所以我認爲每次我的循環執行返回錯誤時,我需要建立一個這個變量值的列表,並在循環過程結束時使用這個列表來返回這個錯誤消息。

UPDATE:

對於下面我想知道的任何最終的名單「sProdId」的價值,這是在SQL查詢聞其失敗的任何錯誤執行。通常它會嘗試在數字SQL字段中插入#Value。

Sub SavetoSQL() 

     Dim conn As New ADODB.Connection 
     Dim iRowNo As Integer 

     Dim Ddate 
     Ddate = Range("refdate") 

     Dim RngRefdate As Date 
     RngRefdate = DateSerial(Year(Ddate), Month(Ddate), Day(Ddate)) 



With Sheets("Hist Prods temp") 

    'Open a connection to SQL Server 
      conn.Open "Provider=SQLOLEDB;Data Source=XXXXX;Initial Catalog=XXXXXX;User Id=XXXX;Password=XXXXXXX;" 

      'Skip the header row 
      iRowNo = 2 

      'Loop until empty cell in sRefDate 
      Do Until .Cells(iRowNo, 1) = "" 
       sRefDate = .Cells(iRowNo, 1) 
       sProdId = .Cells(iRowNo, 2) 
       sPrice = .Cells(iRowNo, 3) 
       sValue = .Cells(iRowNo, 4) 
       sDV01 = .Cells(iRowNo, 5) 
       sDelta1 = .Cells(iRowNo, 6) 
       sDeltaPct = .Cells(iRowNo, 7) 
       sGamma = .Cells(iRowNo, 8) 
       sVega = .Cells(iRowNo, 9) 
       sTheta = .Cells(iRowNo, 10) 
       sDelta2 = .Cells(iRowNo, 11) 
       sIVol = .Cells(iRowNo, 12) 

'Generate and execute sql statement to import the excel rows to SQL Server table 

conn.Execute "INSERT INTO [dbo].[Prices] ([Date],[Id_Product],[Price],[Value],[DV01],[Delta1$],[Delta%],[Gamma$],[Vega$],[Theta$],[Delta2$],[Ivol],[Last_Update]) values ('" & sRefDate & "', '" & sProdId & "'," & sPrice & "," & sValue & "," & sDV01 & "," & sDelta1 & "," & sDeltaPct & "," & sGamma & "," & sVega & "," & sTheta & "," & sDelta2 & "," & sIVol & ",GETDATE())" 


iRowNo = iRowNo + 1 

Loop 

conn.Close 
Set conn = Nothing 

End With 

End Sub 
+0

將我的答案與Paul的比較,我現在稍微不確定是否(在錯誤之後)您希望在當前循環迭代(Paul)中執行剩餘操作或跳轉到下一個循環迭代(me)。我可以通過將'GoTo CurrRecFail'改爲'Resume Next'來成爲前者。 –

+0

只需100%清除...如果sProdId#25的循環在任何時候都拋出錯誤,那麼您已完成#25並繼續前進到下一個記錄?其次,如果sProdId#25,#32和#45在第8和第10列中出現了#VALUE錯誤,你是否希望看到''缺少加載:(25,32,45)'**或**'「失蹤負荷:(25,25,32,32,45,45)**或**'「失負荷:25(8),25(10),32(8),32(10),45(8) ),45(10)'? –

+0

是的,如果我有任何錯誤,一行無法插入到SQL中,我會跳過它並移動到我的工作表的下一行,我不需要看看列導致什麼錯誤只是想看看什麼sProdId我有錯誤,所以只是「缺少負載:(25,32,45)」。 – Flib

回答

0

那麼你是一個有點困惑錯誤VBA處理,看看成片的網站上予以適當Error Handling in VBA

你的代碼應該是這樣的,

Sub MyMacro() 
On Error GoTo Errhandler 
    Dim errLog As String 
    Do Until 
     ' My loop code 
     'Save variable X value in a list of error values. 
    Loop 
ExitErrHandler: 
    If Len(errLog) > 0 Then 
     Range("M2") = "Missing loads: (" & Left(errLog, Len(errLog) - 2) & ")" 
    End If 
    Exit Sub 

Errhandler: 
    'Make a Note of the Error Number and substitute it with 1234 
    If Err.Number = 1234 Then 
     ' If an error occurs, display a message in a cell with all X values on the list. 
     errLog = errLog & yourUniqueValue & ", " 
     Resume Next 
    Else 
     MsgBox "Another Error occurred." & vbCrLf & vbCrLf & Err.Number & " - " & Err.Description 
     Resume ExitErrHandler 
    End If 
End Sub 
+0

我的理解是,OP正在記錄哪些記錄ID失敗。如果循環的單個迭代中有多行會引發錯誤,則代碼將在錯誤字符串中多次打印該索引。 –

+0

@MarkBalhoff - 同意,但基於OP發佈的僞代碼,這是一個解決方案。你的也許是正確的,但如果沒有正確/實際的代碼,很難判斷。 – PaulFrancis

+0

嗨,我的循環執行單行命令,在特定的表中逐行循環,每行中我有很多列值,我作爲SQL插入字符串命令的參數傳遞。有些時候期望參數從excel接收#va​​lue,並且會拋出一個異常停止我的整個循環。我不想要它,我希望繼續執行其他行的循環。在子執行結束時,我希望在單元格中看到哪些行有錯誤,我在循環中用作參數的第一個變量是唯一的ID,因此對於所有這些人,我將使用此值附加在我的列表中。 – Flib

0

您的代碼是沒有意義的,因爲你關閉錯誤處理(On Error GoTo 0)之前,你有機會到循環代碼,將拋出錯誤。

這是一種方法。我在循環中有我的錯誤處理程序。它將x值附加到一個字符串。由於x = x + 1位於錯誤處理程序中,所以在出現錯誤時不必擔心x不會增加。如果您只關心某些Err.Number值,則更改我的錯誤處理程序中的if語句。在代碼結束時,當且僅當錯誤消息字符串至少有一個值時,纔將錯誤消息打印到Sheet2的單元格A1。否則,我重置該輸出單元格。 On Error GoTo -1對重置錯誤處理程序很重要。

Sub MyMacro() 
    Dim x As Integer 
    Dim errMsg As String 
    Dim outWs As Worksheet 
    Set outWs = ThisWorkbook.Worksheets("Sheet1") 
    errMsg = "" 

    On Error GoTo CurrRecFail 
    x = 1 
    Do Until x = 15 
     ' My loop code 

CurrRecFail: 
     If Err.Number > 0 Then 
      errMsg = errMsg & x & ", " 
     End If 
     On Error GoTo -1 
     x = x + 1 

    Loop 

    If Len(errMsg) > 0 Then 
     outWs.Cells(1, 1).Value = "Missing Loads: " & Left(errMsg, Len(errMsg) - 2) 
    Else 
     outWs.Cells(1, 1).Value = "" 
    End If 

End Sub 

上面的代碼會在遇到錯誤時跳轉到下一個循環迭代。如果您希望繼續執行當前循環迭代中的其餘行,請將On Error GoTo CurrRecFail更改爲On Error Resume Next,並刪除現在是無意義標籤的行CurrRecFail: