2017-03-16 104 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'不会引发任何错误。 –

相关问题