我正在尝试学习函数,以便在必要时简化和重用代码。
我首先将经常使用的东西转变为一个函数:返回电子表格中最后一个非空列的整数值。
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
第二个原因是您使用的是Offset
。 Offset
实际上,它会按您指定的量移动 a Range
。您不想移动整个单元格范围,而是找到该范围内的最后一个单元格。您可以通过更改Offset
为Cells
、删除初始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
下面说明了如何调用此函数,以及一些示例输出。假设整个工作表都是空白的,除了在单元格中输入的一些随机数据B1
(B8
留空B10
)B9
。请注意,您不是将列作为范围输入,而是将列字母输入或者列号(无效值返回 -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 是一个属性。