web-dev-qa-db-fra.com

Excel VBA Trouver la dernière ligne de la plage

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:

 Example of data

 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.

3
atame

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
5
Shai Rado

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.

1
Marcucciboy2

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

1
Niclas
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
1
ArindamD
LR_wbSelect = ThisWorkbook.Sheets("Sheet1").Range("A" & Rows.Count).End(xlUp).Row
1
Punith

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
1
Rockstar
    '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)
0
Jayant Kumar jain

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.

0
atame

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
0
user6432984

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.

0
gibberish