2017-03-16 90 views
0

我有兩個主要功能,第一個是search_bank。它會逐個單元格搜索Credits,Type和Store列,並判斷是否匹配。如果匹配,則返回True,並且副作用會更改匹配單元格的顏色。VBA:函數給出「運行時錯誤'424':所需的對象」錯誤時調用

第二個sub我用來測試第一個函數。 我遇到的問題是我得到一個運行時錯誤'424':對象需要,沒有指出問題出在哪裏。

這是第一個功能:

Function search_bank(Store As String, amount As Double, Amex As Boolean) As Boolean 
    Dim m_store As Range 
    Dim m_type As Range 
    Dim Credit_Amt_Col As Range 

    Set m_store = bank_sheet.Range("1:1").Find("M_STORE") 
    Set m_type = bank_sheet.Range("1:1").Find("M_TYPE") 
    Set Credit_Amt_Col = bank_sheet.Range("1:1").Find("Credit Amt") 

    search_bank = False 
    Dim i As Long 
    For i = 1 To 9000 
     If Not search_bank Then 
      Dim store_cell As Range 
      Dim type_cell As Range 
      Dim credit_cell As Range 

      Set store_cell = Worksheets(2).Cells(i, m_store.Column) 
      Set type_cell = Worksheets(2).Cells(i, m_type.Column) 
      Set credit_cell = Worksheets(2).Cells(i, Credit_Amt_Col.Column) 

      If InStr(UCase(store_cell.Value), UCase(Store)) > 0 And credit_cell.Value = amount Then 
       If store_cell.Interior.ColorIndex <> 46 Then 
        If Amex And InStr(UCase(type_cell.Value), UCase("amex deposit")) Then 
         store_cell.Interior.ColorIndex = 46 
         search_bank = True 

        End If 
        If Not Amex And InStr(UCase(type_cell.Value), UCase("Credit Card Deposit")) Then 
         store_cell.Interior.ColorIndex = 46 
         search_bank = True 

        End If 
       End If 
      End If 
     End If 
    Next i 

End Function 

,這裏是測試儀:

Sub Tester() 
    Dim x As Boolean 
    x = search_bank("ctc", 38.4, True) 
    Debug.Print (x) 
End Sub 

我一直在使用 '設置' 在測試儀上的嘗試:

Sub Tester() 
    Dim x As Boolean 
    Set x = search_bank("ctc", 38.4, True) 
    Debug.Print (x) 
End Sub 

即使在將它們傳遞給測試人員之前聲明變量(我不太習慣VBA,但一時之間,我相信這只是如此古老,在他們通過之前宣佈的事情)

Sub Tester() 
    Dim x As Boolean 
    Dim store As String 
    Dim Amount As Double 
    Dim amex As Boolean 
    store = "ctc" 
    Amount = 38.4 
    amex = True 
    x = search_bank(store, Amount, amex) 
    Debug.Print (x) 
End Sub 
+2

當您遇到運行時錯誤時,請選擇調試選項並使用F8逐句通過代碼,直到看到哪行出現錯誤。 –

+0

你在哪裏/何時/如何聲明'bank_sheet'? – BruceWayne

+1

另外,請確保您的三個Find方法的結果返回有效的對象。如果在第1行沒有找到這些值,那麼他們將返回一個'Nothing',這會在代碼中稍後引發此錯誤。 –

回答

0

有很多很好的評論你的OP下,並用@ BrandonBarney的答案太多,但這裏是我的兩分錢:

百分之一:我認爲最重要的事情是你從來沒有聲明blank_sheet還沒有嘗試使用它,同時設置範圍對象。這是你的錯誤來自哪裏。它正在尋找Range("1:1").Find("M_STORE"),但不知道bank_sheet是什麼。

二分法:有一個快速的方法讓你指出你的代碼是always use Option Explicit。這可確保您使用的任何變量都被明確聲明。 I .: .:

Option Explicit 

Function search_bank(Store As String, amount As Double, Amex As Boolean) As Boolean 
    Dim m_store As Range 
    Dim m_type As Range 
    Dim Credit_Amt_Col As Range 

    ''''' New code here: '''''' 
    Dim bank_sheet as Worksheet 
    Set bank_sheet = Worksheets("Bank Sheet") ' change to whatever the name is. 
    ''''''''''''''''''''''''''' 
    Set m_store = bank_sheet.Range("1:1").Find("M_STORE") 
    Set m_type = bank_sheet.Range("1:1").Find("M_TYPE") 
    Set Credit_Amt_Col = bank_sheet.Range("1:1").Find("Credit Amt") 
    ' etc. etc. 

Option Explicit也將有所幫助,如果你不小心有一個錯字。所以,如果你曾經做過bank_sheeet.Range("A:A")它會錯誤並要求你聲明bank_sheeet。或者,當然,你會意識到這是一個錯字,然後修復它。

獎金分:您可以結合您的Dim s:
Dim m_store as Range, m_type as Range, Credit_Amt_Col as Range都可以保存在一行上。

(注:這樣做會Dim m_store, m_type, Credit_Amt_Col as Range設置所有三種類型Range它會讓m_storem_type一個Variant因爲它沒有聲明。在這種情況下,只有Credit_Amt_Col將是Range。所以你仍然必須明確說明的類型,每個變量)。

1

如果可以的話,我會發布這個評論,但我不能。所以我知道這不會直接解決它,但它有助於調試。請看下圖:

Function search_bank(Store As String, amount As Double, Amex As Boolean) As Boolean 
Dim m_store As Range 
Dim m_type As Range 
Dim Credit_Amt_Col As Range 

' It is always best to check the inverse of an object before setting 
' setting an object variable to the target object. In this case 
' I check to make sure each range can be found, and if not, I 
' debug.print which variable cannot be set. 

Set m_store = bank_sheet.Range("1:1").Find("M_STORE") 
Set m_type = bank_sheet.Range("1:1").Find("M_TYPE") 
Set Credit_Amt_Col = bank_sheet.Range("1:1").Find("Credit Amt") 

If m_store is Nothing then Debug.Print "m_store is nothing" 
If m_type is Nothing then Debug.Print "m_type is nothing" 
If Credit_Amt_Col is Nothing then Debug.Print "Credit_Amt_Col is nothing." 

search_bank = False 
Dim i As Long 
For i = 1 To 9000 
    If Not search_bank Then 
     Dim store_cell As Range 
     Dim type_cell As Range 
     Dim credit_cell As Range 

     ' Use the inverse method above on these three items as well. 
     Set store_cell = Worksheets(2).Cells(i, m_store.Column) 
     Set type_cell = Worksheets(2).Cells(i, m_type.Column) 
     Set credit_cell = Worksheets(2).Cells(i, Credit_Amt_Col.Column) 

     If InStr(UCase(store_cell.Value), UCase(Store)) > 0 And credit_cell.Value = amount Then 
      If store_cell.Interior.ColorIndex <> 46 Then 
       If Amex And InStr(UCase(type_cell.Value), UCase("amex deposit")) Then 
        store_cell.Interior.ColorIndex = 46 
        search_bank = True 

       End If 
       If Not Amex And InStr(UCase(type_cell.Value), UCase("Credit Card Deposit")) Then 
        store_cell.Interior.ColorIndex = 46 
        search_bank = True 

       End If 
      End If 
     End If 
    End If 
Next i 

End Function 

我發佈的評論內嵌,但基本上我添加了一個逆檢查你的前三個對象(你想爲你的第二組對象也這麼做)。這是最好的做法,但在這種情況下,它也會(希望)幫助您查明對象不能找到的位置。

+1

會更容易'設置'對象變量,然後簡單地測試'如果設置m_store是Nothing'等。也更少的開銷和更少的「硬編碼」字符串文字。 –

+0

如果您嘗試在設置後未使用,則如果find不返回對象,則可能會遇到「對象變量未設置」錯誤。首先這是倒置塊的意圖。此外,我會理想地消除硬編碼的字符串文字,並且如果可能的話使用listobject而不是使用Find,但這不是Codereview。有很多工作可以改進代碼,但問題必須首先確定。 –

+1

如果變量輸入正確,'如果m_store是Nothing'不會引發任何錯誤。 –