j'ai un peu de mal à trouver la dernière rangée.
Ce que j'essaie de faire est de trouver la dernière ligne de la colonne "A", puis de l'utiliser pour trouver la dernière ligne d'une plage.
Exemple de données:
1) LR_wbSelect = wbshtSelect.cells(Rows.count, "A").End(xlUp).Row - 22
2) LR_wbSelectNew = wbshtSelect.cells(LR_wbSelect, "A").End(xlUp).Row
J'utilise la dernière ligne de la colonne "A", car les données de la ligne 29 suivante auront toujours la même longueur, les lignes utilisées dans la colonne "B" de la ligne 29 peuvent comporter un nombre variable de lignes.
J'essaie donc d'utiliser LR_wbSelect
dans la colonne "A" pour obtenir ma dernière ligne de départ, puis au sein de LR_wbSelectNew
en l'utilisant comme point de départ pour la recherche.
Cela fonctionne lorsque la colonne définie sur "A", LR_wbSelectNew
me donne la ligne de "17", mais lorsque je change la colonne dans LR_wbSelectNew
en "B", elle ne donne pas la dernière ligne correcte de "18".
Je peux changer la colonne en "C, D, E, F" et le code fonctionne bien, mais la seule colonne que je peux utiliser est "B" car il y aura toujours des données, où le reste de cette ligne pourrait avoir une cellule vide.
Après avoir effectué quelques tests sur la feuille, appuyez sur CRTL & Up à partir du point final de LR_wbSelect
colonne "B" pour ignorer les données des lignes et accéder à la ligne où elles se trouvent. Je ne vois pas pourquoi Excel ne pense pas qu'il y ait des données dans ces cellules?
J'espère que j'ai expliqué cela afin que vous puissiez suivre, sinon demandez s'il vous plaît.
Si besoin, je peux télécharger le code complet si nécessaire, faites le moi savoir.
Toute aide serait appréciée.
Il existe de nombreux résultats et méthodes lors de la recherche de LastRow (colonne B).
Lorsque vous utilisez Cells(.Rows.Count, "B").End(xlUp).Row
, vous obtiendrez la dernière ligne avec les données de la colonne B (elle ignore les lignes avec des espaces et descend complètement).
En utilisant:
With wbshtSelect.Range("B10").CurrentRegion
LR_wbSelectNew = .Rows(.Rows.Count).Row
End With
Vous recherchez la dernière ligne avec des données dans la colonne B de la CurrentRegion
, qui commence à partir de la cellule B10, jusqu'à la première ligne sans données (elle s’arrête sur la première ligne avec une ligne vide).
Code complet:
Sub GetLastRow()
Dim wbshtSelect As Worksheet
Dim LR_wbSelectNew As Long
' modify "Sheet2" to your sheet's name
Set wbshtSelect = Sheets("Sheet2")
' find last row with data in Column B
With wbshtSelect
LR_wbSelectNew = .Cells(.Rows.Count, "B").End(xlUp).Row
End With
' for debug only
Debug.Print LR_wbSelectNew ' >>result 31
' find last row with data in Column B at current regioun starting at cell B10
With wbshtSelect.Range("B10").CurrentRegion
LR_wbSelectNew = .Rows(.Rows.Count).Row
End With
' for debug only
Debug.Print LR_wbSelectNew ' >> result 18
End Sub
Edit1 : code recherche la dernière ligne pour les cellules avec des valeurs (il ignore les cellules vides avec des formules à l'intérieur).
Sub GetLastRow()
Dim wbshtSelect As Worksheet
Dim LR_wbSelectNew As Long
' modify "Sheet2" to your sheet's name
Set wbshtSelect = Sheets("Sheet2")
' find last row with data in Column B at current regioun starting at cell B10
With wbshtSelect.Range("B10").CurrentRegion
LR_wbSelectNew = .Rows(.Rows.Count).Row
End With
Dim Rng As Range
Set Rng = wbshtSelect.Range("B10:B" & LR_wbSelectNew)
' find last row inside the range, ignore values inside formulas
LR_wbSelectNew = Rng.Find(What:="*", _
After:=Range("B10"), _
LookAt:=xlPart, _
LookIn:=xlValues, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row
' for debug
Debug.Print LR_wbSelectNew ' << result 18 (with formulas in the range)
End Sub
Je suis venu ici pour trouver un moyen de trouver la dernière ligne d'une plage non contiguë La plupart des réponses ici ne vérifient qu'une colonne à la fois et j'ai donc créé plusieurs fonctions différentes pour résoudre ce problème. J'avouerai cependant que la réponse de Shai Rado est essentiellement la même que celle de mon implémentation de .Find()
.
Implémentation 1 - Utilise Range().End(xlUp)
sur chaque colonne
Function LastRowInRange_xlUp(ByVal rng As Range) As Long
Dim lastRowCurrent As Long
Dim lastRowBest As Long
'loop through columns in range
Dim i As Long
For i = rng.Column To rng.Column + rng.Columns.count - 1
If rng.Rows.count < Rows.count Then
lastRowCurrent = Cells(rng.row + rng.Rows.count, i).End(xlUp).row
Else
lastRowCurrent = Cells(rng.Rows.count, i).End(xlUp).row
End If
If lastRowCurrent > lastRowBest Then
lastRowBest = lastRowCurrent
End If
Next i
If lastRowBest < rng.row Then
LastRowInRange_xlUp = rng.row
Else
LastRowInRange_xlUp = lastRowBest
End If
End Function
Implementation 2 - Utilise Range().Find()
dans l'ordre inverse
Function LastRowInRange_Find(ByVal rng As Range) As Long
'searches range from bottom up looking for "*" (anything)
Dim rngFind As Range
Set rngFind = rng.Find( What:="*", _
After:=Cells(rng.row, rng.Column), _
LookAt:=xlWhole, _
LookIn:=xlValues, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious)
If Not rngFind Is Nothing Then
LastRowInRange_Find = rngFind.row
Else
LastRowInRange_Find = rng.row
End If
End Function
Implementation 3 - Boucle dans un tableau en ordre inverse
Function LastRowInRange_Array(ByVal rng As Range) As Long
'store range's data as an array
Dim rngValues As Variant
rngValues = rng.Value2
Dim lastRow As Long
Dim i As Long
Dim j As Long
'loop through range from left to right and from bottom upwards
For i = LBound(rngValues, 2) To UBound(rngValues, 2) 'columns
For j = UBound(rngValues, 1) To LBound(rngValues, 1) Step -1 'rows
'if cell is not empty
If Len(Trim(rngValues(j, i))) > 0 Then
If j > lastRow Then lastRow = j
Exit For
End If
Next j
Next i
If lastRow = 0 Then
LastRowInRange_Array = rng.row
Else
LastRowInRange_Array = lastRow + rng.row - 1
End If
End Function
Je n'ai pas testé laquelle de ces implémentations fonctionnait le plus rapidement sur de grands ensembles de données, mais j'imagine que le gagnant serait _Array
puisqu'il ne parcourt pas chaque cellule de la feuille individuellement mais parcourt les données stockées en mémoire. Cependant, j'ai inclus tous les 3 pour la variété :)
Comment utiliser
Pour utiliser ces fonctions, vous les déposez dans votre feuille de code/module, spécifiez une plage en tant que paramètre, puis ils renverront la ligne remplie "la plus basse" de cette plage.
Voici comment vous pouvez utiliser l’un d’entre eux pour résoudre le problème initial posé:
Sub answer()
Dim testRange As Range
Set testRange = Range("A1:F28")
MsgBox LastRowInRange_xlUp(testRange)
MsgBox LastRowInRange_Find(testRange)
MsgBox LastRowInRange_Array(testRange)
End Sub
Chacun de ceux-ci retournera 18
.
Si votre wbshtSelect est défini en tant que feuille de calcul et que vous avez utilisé set pour définir la feuille de calcul spécifique, vous pouvez l'utiliser.
Dim LastRow As Long
wbshtSelect.UsedRange ' Refresh UsedRange
LastRow = wbshtSelect.UsedRange.Rows(wbshtSelect.UsedRange.Rows.Count).Row
Sinon, jetez un oeil ici http://www.ozgrid.com/VBA/ExcelRanges.htm
LR_wbSelectNew = wbshtSelect.cells(LR_wbSelect, "B").End(xlUp).Row
Pourquoi utilisez-vous "LR_wbSelect" comme compteur de lignes? Si vous voulez connaître la dernière ligne de la colonne 'B', utilisez Rows.count.
Rows.count -> Retourne le nombre maximum de lignes (ce qui correspond à 1048576 pour Excel 2007 et les versions ultérieures) End (xlUp) -> Déplace le pointeur vers le haut jusqu'à la dernière ligne utilisée.
Alors, cells (Rows.count, "A"). End (xlUp) .Row -> Ceci place le pointeur sur la dernière ligne si la colonne "A" (comme si vous appuyez sur les touches Crtl + Up quand la cellule A1048576 est sélectionnée).
Utilisez donc Rows.count pour sélectionner également la dernière ligne de la colonne 'B'. Si vous avez des exigences spécifiques liées à LR_wbSelect, veuillez les mentionner.
Sinon, si vous souhaitez connaître la dernière ligne utilisée dans une feuille, vous pouvez utiliser les éléments suivants:
mySheet.Cells.SpecialCells(xlCellTypeLastCell).Row
LR_wbSelect = ThisWorkbook.Sheets("Sheet1").Range("A" & Rows.Count).End(xlUp).Row
J'espère que ce morceau de code aide!
Sub LastRowInOneColumn()
'Find the last used row in a Column: column A in this example
Dim LastRow As Long
With ActiveSheet
LastRow = .Cells(.Rows.Count, "A").End(xlUp).Row
End With
MsgBox LastRow
End Sub
'This is sure method to find or catch last row in any column even 'if some cell are blank in-between. (Excel-2007)`
'This works even if sheet is not active
'mycol is the column you want to get last row number
for n=1048575 to 1 step -1
myval=cells(n,mycol)
if myval<>"" then
mylastrow=n 'this is last row in the column
exit for
end if
next
ret=msgbox("Last row in column-" & mycol & "is=" & mylastrow)
Le problème avec cette tentative est que si une cellule contient une formule, Excel pense alors qu'elle est remplie même si la formule renvoie un blanc.
Range().End
vous mènera à la fin d'un bloc de code. Si la cellule de départ est vide, cela vous amène la première cellule utilisée ou la dernière cellule. Si les cellules ne sont pas vides, cela vous amène à la dernière cellule utilisée. Pour cette raison, vous devez vérifier si la cellule de la colonne B doit déterminer si vous souhaitez utiliser LR_wbSelectNew
comme dernière ligne.
With wbshtSelect
LR_wbSelect = .Cells(Rows.Count, "A").End(xlUp).Row - 22
If .Cells(LR_wbSelect, "B") <> "" Then
LR_wbSelectNew = LR_wbSelect
Else
LR_wbSelectNew = .Cells(LR_wbSelect, "B").End(xlUp).Row
End If
End With
Ce code définit une plage cible qui s'étend de A1 à la dernière ligne de la colonne a-22 et s'étend sur 10 colonnes.
Dim Target As Range
With wbshtSelect
Set Target = .Range("A1", .Cells(Rows.Count, "A").End(xlUp).Offset(-22)).Resize(, 10)
End With
La première solution de Shai Rado est excellente , mais pour certains, elle pourrait nécessiter un peu plus de précisions:
Dim rngCurr, lastRow
rngCurr = wbshtSelect.Range("B10").CurrentRegion
lastRow = rngCurr.Rows(rngCurr.Rows.Count).Row
Si vous voulez connaître la dernière ligne utilisée dans toute la feuille de calcul:
Dim rngCurr, lastRow
rngCurr = Range("A1").CurrentRegion
lastRow = rngCurr.Rows(rngCurr.Rows.Count).Row
Si vous trouvez cela utile, veuillez s'il-vous-plaît faire remonter sa réponse.