Excel VBA 函数运行时错误 1004:应用程序定义或对象定义错误

Excel VBA 函数运行时错误 1004:应用程序定义或对象定义错误

我正在尝试学习函数,以便在必要时简化和重用代码。

我首先将经常使用的东西转变为一个函数:返回电子表格中最后一个非空列的整数值。

Function FindLastDataLine(strColName As String) As Long
    FindLastDataLine = Range(strColName).Offset(Rows.Count - 1, 0).End(xlUp).Row
End Function

Sub PracticeMacro()
    intItemCount = FindLastDataLine("A:A")
    MsgBox ("There are " & intItemCount & " rows of data in column A.")
End Sub

当我运行这个程序时,我收到运行时错误“1004”“应用程序定义或对象定义错误”,帮助中将其定义为“别人的错误”,但不完全逐字引用。

我可能哪里做错了?

答案1

为什么你的方法不起作用:这里有两个原因。首先,当你放置 时Rows.Count,没有 的引用Rows- 它是 的一个属性Range。要修复它,你只需要引用与已有相同的范围(只需在调用之前附加它,Rows.Count如下所示:

Function FindLastDataLine(strColName As String) As Long
    FindLastDataLine = Range(strColName).Offset(Range(strColName).Rows.Count - 1, 0).End(xlUp).Row
End Function

第二个原因是您使用的是OffsetOffset实际上,它会按您指定的量移动 a Range。您不想移动整个单元格范围,而是找到该范围内的最后一个单元格。您可以通过更改OffsetCells、删除初始Range()调用(因为我们将选择一个单元格)并更改0为所需的列来轻松完成此操作。但是,由于您将列作为 传递"A:A",因此这是不可能的,因此您必须将其替换为,Range(strColName).Column如下所示:

Function FindLastDataLine(strColName As String) As Long
    FindLastDataLine = Cells(Range(strColName).Rows.Count, Range(strColName).Column).End(xlUp).Row
End Function

更好的解决方案:以下解决方案适用于所有最新版本的 MS Office(2003、2007 和 2010),并能处理错误。您可以通过传递列字母或列号来调用它:

Function GetLastDataRow(col As Variant) As Long
    GetLastDataRow = -1
    If (IsNumeric(col) And col >= 1) Or Len(col) <= 2 Then
        On Error Resume Next
        GetLastDataRow = _
            Cells(Cells(1, col).EntireColumn.Rows.Count, col).End(xlUp).Row
        On Error GoTo 0
    End If
End Function

下面说明了如何调用此函数,以及一些示例输出。假设整个工作表都是空白的,除了在单元格中输入的一些随机数据B1B8留空B10B9。请注意,您不是将列作为范围输入,而是将列字母输入或者列号(无效值返回 -1):

GetLastDataRow(1)         =  1    GetLastDataRow("A")       =  1
GetLastDataRow(2)         = 10    GetLastDataRow("B")       = 10
GetLastDataRow("AX")      =  1    GetLastDataRow("A:X")     = -1
GetLastDataRow("Oops...") = -1    GetLastDataRow(200)       =  1

作为技术说明,如果该Cells方法失败,则假定输入无效,因此函数返回 -1。我建议您在函数中使用此做法(如果输入无效,则返回无效值),这将极大地帮助您避免将来的错误。

它的工作原理是,它找到任何特定列中的最后一行(取决于您的 MS Office 版本),然后使用该End方法找到该列中包含数据的最后一个单元格。


这是一个替代版本,如果该列中的所有单元格都为空白,则返回 0:

Function GetLastDataRow(col As Variant) As Long
    GetLastDataRow = -1
    If (IsNumeric(col) And col >= 1) Or Len(col) <= 2 Then
        On Error Resume Next
        If IsEmpty(Cells(Cells(1, col).EntireColumn.Rows.Count, col).End(xlUp).Value) Then
            GetLastDataRow = 0
        Else
            GetLastDataRow = _
                Cells(Cells(1, col).EntireColumn.Rows.Count, col).End(xlUp).Row
        End If
        On Error GoTo 0
    End If
End Function

示例输出:

GetLastDataRow(1)         =  0    GetLastDataRow("A")       =  0
GetLastDataRow(2)         = 10    GetLastDataRow("B")       = 10
GetLastDataRow("AX")      =  0    GetLastDataRow("A:X")     = -1
GetLastDataRow("Oops...") = -1    GetLastDataRow(200)       =  0

答案2

您写道“返回电子表格中最后一个非空白行的整数值。”但看起来您正在尝试获取电子表格特定列中最后一个非空白行。

如果你将你的功能更改为此,我认为它会起作用:

Function FindLastDataLine(strColName As String) As Long
    FindLastDataLine = ActiveSheet.Cells(ActiveSheet.Rows.Count, strColName).End(xlUp).Row
End Function

答案3

它可能无法修复您的错误,但会返回范围内的 ItemCount......

Function FindLastDataLine(strColName As String) As Long
    FindLastDataLine = Evaluate("COUNTA(" & strColName & ")")
End Function

Sub PracticeMacro()
    intItemCount = FindLastDataLine("A:A")
    MsgBox ("There are " & intItemCount & " rows of data in column A.")
End Sub

请注意,还有一些其他方法可以调用此 COUNTA Excel 函数...

答案4

尝试:

FindLastDataLine = _
     Range(strColName).Offset(ActiveSheet.Rows.Count - 1, 0).End(xlUp).Row

Rows 是一个属性。

相关内容