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:
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.
Une meilleure solution est probablement de travailler à partir du bas:
k=sh.Range("A1048576").end(xlUp).row
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
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
CountRows = ThisWorkbook.Worksheets(1).Range("A:A").Cells.SpecialCells(xlCellTypeConstants).Count
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
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
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
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
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.