web-dev-qa-db-fra.com

VBA - Range.Row.Count

J'ai écrit un code simple pour illustrer ma situation. 

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

Qu'est-ce qui se passe est la suivante: Nous comptons les lignes qui contiennent des valeurs commençant à A1. Si le nombre de lignes contenant des valeurs est> 1, le code fonctionne très bien. Toutefois, si A1 est la seule cellule contenant une valeur quelconque, k = 1 048 576, ce qui correspond, je suppose, au nombre maximal de lignes autorisées dans Excel.

Pourquoi k = 1?

Des photos:

The code works

This is wrong

EDIT: La solution de contournement que j'utilise est la suivante:

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

Puisque k est toujours égal à 1048576 lorsque le nombre de lignes avec des valeurs est 1. Cela semble un peu ridicule de devoir faire quelque chose comme ça.

19
docjay

Une meilleure solution est probablement de travailler à partir du bas:

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

Vous devriez plutôt utiliser UsedRange comme ceci:

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

La partie + rn.Row - 1 vient du fait que UsedRange ne commence qu'à la première ligne et à la première colonne utilisées. Par conséquent, si vous avez quelque chose dans les lignes 3 à 10, mais que les lignes 1 et 2 sont vides, rn.Rows.Count serait 8

6
neelsg

Vous pouvez également utiliser la fonction "Last" de Ron de Bruin ( http://www.rondebruin.nl/win/s9/win005.htm ), cela a parfaitement fonctionné pour moi et rend également cellule si tu veux. Pour obtenir la dernière ligne, utilisez-la comme

lastRow = Last(1,yourRange)

J'ai trouvé cela assez pratique.

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
2
suiluj_julius
CountRows = ThisWorkbook.Worksheets(1).Range("A:A").Cells.SpecialCells(xlCellTypeConstants).Count
2
Dado

C'est une belle question :)

Lorsque vous avez une situation avec 1 cellule (A1), il est important d'identifier si la deuxième cellule déclarée n'est pas vide (sh.Range("A1").End(xlDown)). Si c'est vrai, cela signifie que votre portée est devenue incontrôlable :) Regardez le code ci-dessous:

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
1
lowak
k = sh.Range("A2", sh.Range("A1").End(xlDown)).Rows.Count

ou

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

ou

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

Au cas où quelqu'un regarderait à nouveau ceci, vous pouvez utiliser ceci: 

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
1
greg

Cela fonctionne pour moi en particulier dans le filtrage de la table de pivots lorsque je veux le nombre de cellules avec des données sur une colonne filtrée. Réduisez k en conséquence (k - 1) si vous avez une ligne d’en-tête pour le filtrage:

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

As-tu essayé :-

Sub test()

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

    MsgBox (k)

End Sub

Le/seulement/catch est que s'il n'y a pas de données, il retourne quand même 1.

0
user3205578