VBA-Range.Row.Count
我已经写了一个简单的代码来说明我的困境VBA-Range.Row.Count,vba,excel,Vba,Excel,我已经写了一个简单的代码来说明我的困境 Sub test() Dim sh As Worksheet Set sh = ThisWorkbook.Sheets("Sheet1") Dim k As Long k = sh.Range("A1", sh.Range("A1").End(xlDown)).Rows.Count End Sub 发生的情况是:我们计算包含从A1开始的值的行。如果包含值的行数大于1,则代码工作正常。但是,如果A1是唯一包含任何值的单元
Sub test()
Dim sh As Worksheet
Set sh = ThisWorkbook.Sheets("Sheet1")
Dim k As Long
k = sh.Range("A1", sh.Range("A1").End(xlDown)).Rows.Count
End Sub
发生的情况是:我们计算包含从A1开始的值的行。如果包含值的行数大于1,则代码工作正常。但是,如果A1是唯一包含任何值的单元格,则k=1048576,我猜这是Excel中允许的最大行数
为什么k=1
图片:
编辑:我使用的解决方法如下:
Sub test()
Dim sh As Worksheet
Set sh = ThisWorkbook.Sheets("Sheet1")
Dim k As Long
k = sh.Range("A1", sh.Range("A1").End(xlDown)).Rows.Count
If k = 1048576 Then
k = 1
End If
MsgBox (k)
End Sub
因为当具有值的行数为1时,k始终等于1048576。这样做感觉有点傻。可能更好的解决方案是从底部向上工作:
k=sh.Range("A1048576").end(xlUp).row
您应该使用
UsedRange
,如下所示:
Sub test()
Dim sh As Worksheet
Dim rn As Range
Set sh = ThisWorkbook.Sheets("Sheet1")
Dim k As Long
Set rn = sh.UsedRange
k = rn.Rows.Count + rn.Row - 1
End Sub
+rn.Row-1
部分是因为UsedRange仅从使用的第一行和第列开始,因此如果第3到第10行中有一些内容,但第1和第2行为空,rn.rows.Count
将为8您尝试过:-
Sub test()
k = Cells(Rows.Count, "A").End(xlUp).Row
MsgBox (k)
End Sub
唯一的问题是,如果没有数据,它仍然返回1。这是一个很好的问题:)
当您遇到1个单元格(A1)的情况时,必须确定第二个声明的单元格是否为空(sh.Range(“A1”).End(xlDown)
)。如果这是真的,则表示您的范围失控:)请查看下面的代码:
Dim sh As Worksheet
Set sh = ThisWorkbook.Sheets("Arkusz1")
Dim k As Long
If IsEmpty(sh.Range("A1").End(xlDown)) = True Then
k = 1
Else
k = sh.Range("A1", sh.Range("A1").End(xlDown)).Rows.Count
End If
您还可以使用Ron de Bruin()中的“Last”函数,它对我来说非常有效,如果需要,还可以返回最后一列和单元格。要获得最后一行,请像这样使用它
lastRow = Last(1,yourRange)
我觉得这个很方便
Function Last(choice As Long, rng As Range)
'Ron de Bruin, 5 May 2008
' 1 = last row
' 2 = last column
' 3 = last cell
Dim lrw As Long
Dim lcol As Long
Select Case choice
Case 1:
On Error Resume Next
Last = rng.Find(What:="*", _
After:=rng.Cells(1), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row
On Error GoTo 0
Case 2:
On Error Resume Next
Last = rng.Find(What:="*", _
After:=rng.Cells(1), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByColumns, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Column
On Error GoTo 0
Case 3:
On Error Resume Next
lrw = rng.Find(What:="*", _
After:=rng.Cells(1), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row
On Error GoTo 0
On Error Resume Next
lcol = rng.Find(What:="*", _
After:=rng.Cells(1), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByColumns, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Column
On Error GoTo 0
On Error Resume Next
Last = rng.Parent.Cells(lrw, lcol).Address(False, False)
If Err.Number > 0 Then
Last = rng.Cells(1).Address(False, False)
Err.Clear
End If
On Error GoTo 0
End Select
End Function
这对我很有用,尤其是在数据透视表过滤中,当我需要在过滤列上包含数据的单元格计数时。如果有用于筛选的标题行,则相应地减少
k
(k-1):
k = Sheets("Sheet1").Range("$A:$A").SpecialCells(xlCellTypeVisible).SpecialCells(xlCellTypeConstants).Count
或
或
如果有人再次查看此内容,您可以使用以下内容:
Sub test()
Dim sh As Worksheet
Set sh = ThisWorkbook.Sheets("Sheet1")
Dim k As Long
k = sh.Range("A1", sh.Range("A1").End(xlDown).End(xlDown).End(xlUp)).Rows.Count
End Sub
最好的解决办法是使用
Cells(Rows.Count, 1).End(xlUp).Row
因为它会计算单元格的数量,直到找到最后一个写入的单元格
不像
Range("A1", sh.Range("A1").End(xlDown)).Rows.Count
它所做的是选择一个“从到”范围,并显示最后一个忙行的行号一个范围意味着两个最小值,所以。。。同时,A1的范围值继续计数到极限(1048576),然后显示
Sub test()
Dim sh As Worksheet
Set sh = ThisWorkbook.Sheets(1)
Dim k As Long
k = Cells(Rows.Count, 1).End(xlUp).Row
MsgBox k
k = sh.Range("A1", sh.Range("A1").End(xlDown)).Rows.Count
MsgBox k
End Sub
我无法使用此解决方案,因为我在多列中计算行数。示例:如果我使用这个,它将循环5000次左右。这会显著降低代码的速度吗?因为从一百万开始计算,5000次似乎有点低效。Excel存储信息稀疏,因此不需要查看中间单元格。所以不,它不会慢下来-它非常快在测试了所有的解决方案后,这是最快的一个。谢谢根据Excel版本的不同,图纸可能有不同数量的行。您应该使用
行。Count
而不是range对象中的那个大静态数字。为什么在我删除表中的某些行时返回Watch 1048569?
Sub test()
Dim sh As Worksheet
Set sh = ThisWorkbook.Sheets("Sheet1")
Dim k As Long
k = sh.Range("A1", sh.Range("A1").End(xlDown).End(xlDown).End(xlUp)).Rows.Count
End Sub
Cells(Rows.Count, 1).End(xlUp).Row
Range("A1", sh.Range("A1").End(xlDown)).Rows.Count
Sub test()
Dim sh As Worksheet
Set sh = ThisWorkbook.Sheets(1)
Dim k As Long
k = Cells(Rows.Count, 1).End(xlUp).Row
MsgBox k
k = sh.Range("A1", sh.Range("A1").End(xlDown)).Rows.Count
MsgBox k
End Sub