VBA - Range.Row.Count

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/25056372/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 08:44:14  来源:igfitidea点击:

VBA - Range.Row.Count

excelvbaexcel-vba

提问by docjay

I have written a simple code to illustrate my predicament.

我写了一个简单的代码来说明我的困境。

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

What happens is this: We count the rows which contain values starting at A1. If the number of rows which contain values is > 1 the code works great. However, if A1 is the only cell which contains any value, k = 1,048,576 which I guess is the maximum number of rows allowed in Excel.

发生的事情是这样的:我们计算包含从 A1 开始的值的行。如果包含值的行数 > 1,则代码效果很好。但是,如果 A1 是唯一包含任何值的单元格,则 k = 1,048,576,我猜这是 Excel 中允许的最大行数。

Why doesn't k = 1?

为什么 k = 1?

Pictures:

图片:

The code works

代码有效

This is wrong

这是错误的

EDIT: The workaround that I'm using is the following:

编辑:我使用的解决方法如下:

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

Since k is always equal to 1048576 when the number of rows with values is 1. It just feels a bit silly having to do something like this.

由于当具有值的行数为 1 时,k 始终等于 1048576。不得不做这样的事情感觉有点傻。

回答by Charles Williams

Probably a better solution is work upwards from the bottom:

可能更好的解决方案是从底部向上工作:

k=sh.Range("A1048576").end(xlUp).row

回答by neelsg

You should use UsedRangeinstead like so:

你应该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

The + rn.Row - 1part is because the UsedRange only starts at the first row and column used, so if you have something in row 3 to 10, but rows 1 and 2 is empty, rn.Rows.Countwould be 8

+ rn.Row - 1部分是因为 UsedRange 仅从使用的第一行和第一列开始,所以如果您在第 3 到 10 行中有内容,但第 1 和第 2 行为空,则为rn.Rows.Count8

回答by Dado

CountRows = ThisWorkbook.Worksheets(1).Range("A:A").Cells.SpecialCells(xlCellTypeConstants).Count

回答by suiluj_julius

You could also use the "Last" function from Ron de Bruin (http://www.rondebruin.nl/win/s9/win005.htm), it worked perfectly for me and also gives back the last column and cell if you want. To get the last row use it like

您还可以使用 Ron de Bruin ( http://www.rondebruin.nl/win/s9/win005.htm)的“Last”函数,它对我来说非常有用,如果需要,还可以返回最后一列和单元格. 要获得最后一行,请使用它

lastRow = Last(1,yourRange)

I found this quite handy.

我发现这很方便。

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

回答by greg

In case anyone looks at this again, you can use this:

万一有人再看这个,你可以使用这个:

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

回答by user9089345

k = sh.Range("A2", sh.Range("A1").End(xlDown)).Rows.Count

or

或者

k = sh.Range("A2", sh.Range("A1").End(xlDown)).Cells.Count

or

或者

k = sh.Range("A2", sh.Range("A1").End(xlDown)).Count

回答by lowak

That is nice question :)

这是个好问题:)

When you have situation with 1 cell (A1), it is important to identify if second declared cell is not empty (sh.Range("A1").End(xlDown)). If it is true it means your range got out of control :) Look at code below:

当您遇到 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

回答by lowak

Have you tried :-

你有没有尝试过 :-

Sub test()

    k = Cells(Rows.Count, "A").End(xlUp).Row

    MsgBox (k)

End Sub

The /only/ catch is that if there is no data it still returns 1.

/only/ 的问题是,如果没有数据,它仍然返回 1。

回答by pnacamuli

This works for me especially in pivots table filtering when I want the count of cells with data on a filtered column. Reduce kaccordingly (k - 1)if you have a header row for filtering:

这对我有用,特别是在数据透视表过滤中,当我想要过滤列上包含数据的单元格计数时。如果您有用于过滤的标题行,请k相应减少(k - 1)

k = Sheets("Sheet1").Range("$A:$A").SpecialCells(xlCellTypeVisible).SpecialCells(xlCellTypeConstants).Count

回答by APO69

The best solution is to use

最好的解决方案是使用

Cells(Rows.Count, 1).End(xlUp).Row

since it counts the number of cells until it finds the last one written.

因为它会计算单元格的数量,直到找到最后一个写入的单元格。

Unlike

不像

Range("A1", sh.Range("A1").End(xlDown)).Rows.Count

what it does is select an "from-to" range and display the row number of the last one busy.
A range implies two minimum values, so ... meanwhile A1 has a value of the range continues to count to the limit (1048576) then it is shown.

它所做的是选择一个“from-to”范围并显示最后一个 busy 的行号
一个范围意味着两个最小值,所以......同时 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

enter image description here

在此处输入图片说明