VBA:函数在调用时给出 "Run time error '424': Object required" 错误
VBA: Function gives "Run time error '424': Object required" Error when called
我主要有两个功能,第一个是search_bank。它逐个单元格地搜索 Credits、Type 和存储列,并确定我们是否有匹配项或 not.If 有匹配项,它 returns True 并且副作用会改变颜色匹配的单元格。
第二个 sub 我用来测试第一个 function。
我遇到的问题是我收到 运行 时间错误“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
我试过在测试仪上使用 'set':
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
如果可以的话,我会post将此作为评论,但我不能。所以我知道这不会直接解决它,但它会有助于调试。见下文:
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
我 post 编辑了一条内联评论,但基本上我为您的前三个对象添加了一个反向检查(您也想为您的第二组对象执行此操作)。这是最佳做法,但在这种情况下,它还(希望)帮助您查明找不到对象的位置。
你的 OP 下有很多好的评论,还有@BrandonBarney 的回答,但这是我的两分钱:
第一点:我看到的最重要的事情是您从未声明 [=11=] 却在设置范围对象时尝试使用它。这就是您的错误来源。它正在寻找 Range("1:1").Find("M_STORE")
,但不知道 bank_sheet
是什么。
第二点:向您指出这一点的一种快速方法是在您的代码顶部 always use Option Explicit
。这确保显式声明了您使用的 any 变量。即:
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_store
和 m_type
成为 Variant
因为它没有声明。只有 Credit_Amt_Col
在这种情况下会是 Range
。所以你仍然必须明确说明 每个变量 的类型)。
我主要有两个功能,第一个是search_bank。它逐个单元格地搜索 Credits、Type 和存储列,并确定我们是否有匹配项或 not.If 有匹配项,它 returns True 并且副作用会改变颜色匹配的单元格。
第二个 sub 我用来测试第一个 function。 我遇到的问题是我收到 运行 时间错误“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
我试过在测试仪上使用 'set':
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
如果可以的话,我会post将此作为评论,但我不能。所以我知道这不会直接解决它,但它会有助于调试。见下文:
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
我 post 编辑了一条内联评论,但基本上我为您的前三个对象添加了一个反向检查(您也想为您的第二组对象执行此操作)。这是最佳做法,但在这种情况下,它还(希望)帮助您查明找不到对象的位置。
你的 OP 下有很多好的评论,还有@BrandonBarney 的回答,但这是我的两分钱:
第一点:我看到的最重要的事情是您从未声明 [=11=] 却在设置范围对象时尝试使用它。这就是您的错误来源。它正在寻找 Range("1:1").Find("M_STORE")
,但不知道 bank_sheet
是什么。
第二点:向您指出这一点的一种快速方法是在您的代码顶部 always use Option Explicit
。这确保显式声明了您使用的 any 变量。即:
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_store
和 m_type
成为 Variant
因为它没有声明。只有 Credit_Amt_Col
在这种情况下会是 Range
。所以你仍然必须明确说明 每个变量 的类型)。