Détermination de la dernière ligne REELLE d'une colonne Excel [Résolu]

ucfoutu 18039 Messages postés lundi 7 décembre 2009Date d'inscriptionModérateurStatut 11 avril 2018 Dernière intervention - 17 févr. 2016 à 22:13 - Dernière réponse : pijaku 12205 Messages postés jeudi 15 mai 2008Date d'inscriptionModérateurStatut 13 septembre 2017 Dernière intervention
- 22 févr. 2016 à 11:43
Bonjour,

Je suis "tombé" sur une discussion ouverte sur un autre site et relative à la détermination de la dernière ligne "réelle" d'une colonne d'une feuille Excel.
Le demandeur entendait par "dernière ligne réelle", la dernière cellule remplie (précédée ou non de lignes vides) d'une colonne, y compris si cette ligne faisait partie de lignes masquées.
Aucune des solutions proposées ne le satisfaisait dans la mesure où :
- certaines n'étaient valables que si la colonne était totalement remplie jusqu'à cette dernière ligne
- d'autres étaient "justes", mais passaient par un tremplin (une autre feuille). Lourd
- d'autres fonctionnaient, mais à condition de faire "harakiri" des lignes masquées (ce qui est gênant) ...
Ce qui m'a par ailleurs étonné, c'est d'une part que ceux qui ont proposé ces solutions boiteuses ne sont pas des débutants et que, d'autre part, des forumeurs à la fois avancés et d'habitude toujours présents n'ont pas proposé de solutions.
Je me suis dans un premier temps interrogé sur l'utilité de la "chose", mais, après réflexion, j'en ai trouvé plus d'une (dans certains cas).
Je m'y suis donc attelé.
Le but, donc : que les lignes visibles ou masquées contiennent ou non une ou plusieurs lignes (voire la totalité) vides, déterminer la dernière ligne remplie, masquée ou non, d'une colonne, quel que soit le nombre de plages masquées présentes.
Voici où j'en suis, qui fonctionne sans faille :
Private Function derlig_reelle(plage As Range) As Long
Dim plage_visible As Range, plageutile As Range, colonne As Long, ou As Long
Application.ScreenUpdating = False
With plage.Worksheet
Set plagevisible = .Columns(plage.Column).SpecialCells(xlCellTypeVisible)
ou = plagevisible.Areas(plagevisible.Areas.Count).Row
If ou = 1 Then
derlig_reelle = .Cells(Rows.Count, plage.Column).End(xlUp).Row
Else
Set plageutile = .Range(.Cells(1, plage.Column), .Cells(ou, plage.Column))
plageutile.EntireRow.Hidden = False
derlig_reelle = .Cells(Rows.Count, plage.Column).End(xlUp).Row
plageutile.EntireRow.Hidden = True
plagevisible.EntireRow.Hidden = False
End If
Application.ScreenUpdating = True
End With
End Function

Fonction appelable ainsi, au gré de chacun (exemples) :
 MsgBox derlig_reelle(Worksheets("Feuil1").Columns(1))
MsgBox derlig_reelle(Worksheets("Feuil1").Columns("A"))
MsgBox derlig_reelle(Worksheets("Feuil2").Range("B:B"))

Un snippet en sera fait, mais pas avant que d'autres ici n'aient cherché une solution éventuellement meilleure.
Je compte sur vous pour tenter de perfectionner (si possible).
Merci d'avance à ceux qui s'y mettront.
-
Afficher la suite 

6 réponses

Répondre au sujet
ucfoutu 18039 Messages postés lundi 7 décembre 2009Date d'inscriptionModérateurStatut 11 avril 2018 Dernière intervention - Modifié par ucfoutu le 18/02/2016 à 07:07
0
Utile
2
Une autre manière de procéder pourrait être celle-ci :
Dim plage_visible As Range, ou As Long, tabl
Application.ScreenUpdating = False
With plage.Worksheet
derlig = .Cells(Rows.Count, plage.Column).End(xlUp).Row
Set plagevisible = .Columns(plage.Column).SpecialCells(xlCellTypeVisible)
ou = plagevisible.Areas(plagevisible.Areas.Count).Row
If derlig >= ou Then
derlig_r = derlig
Else
tabl = .Range(.Cells(1, plage.Column), .Cells(ou, plage.Column))
derlig_r = derlig
For i = UBound(tabl, 1) To 1 Step -1
If tabl(i, 1) <> "" Then derlig_r = i: Exit For
Next
End If
End With
Application.ScreenUpdating = True

Celle-ci présente l'avantage de ne pas jouer au ping-pong avec les lignes visibles et masquées. Son inconvénient est la boucle, qui pourrait être source de ralentissement dans le cas (bien que peu probable) de la présence d'un grand nombre de ligne vides successives.
________________________
Nul ne saurait valablement coder ce qu'il ne saurait exposer clairement.
Whismeril 11407 Messages postés mardi 11 mars 2003Date d'inscriptionContributeurStatut 20 avril 2018 Dernière intervention - 18 févr. 2016 à 09:29
Bonjour Uc, c'est du VBA non?
jordane45 20567 Messages postés mercredi 22 octobre 2003Date d'inscriptionModérateurStatut 20 avril 2018 Dernière intervention > Whismeril 11407 Messages postés mardi 11 mars 2003Date d'inscriptionContributeurStatut 20 avril 2018 Dernière intervention - 18 févr. 2016 à 09:47
Hello Whism.
Oui. Je déplace donc le sujet dans le "bon" forum.
Merci.
Commenter la réponse de ucfoutu
pijaku 12205 Messages postés jeudi 15 mai 2008Date d'inscriptionModérateurStatut 13 septembre 2017 Dernière intervention - 22 févr. 2016 à 09:45
0
Utile
Bonjour Jacques,

A ma connaissance, il n'y a rien de plus "simple" que la méthode find. Utilisée avec son paramètre SearchDirection réglé sur xlPrevious, elle devrait répondre à ton problème du jour.
Mais, son défaut est de retourner une erreur en cas de "plage" vide. Il suffit alors de tester avec CountA par exemple.

Cela nous donne, en VBA excel, cette fonction :
Private Function DrLig_Reelle(plage As Range) As Long

   If WorksheetFunction.CountA(plage) = 0 Then DrLig_Reelle = 1: Exit Function
   DrLig_Reelle = plage.Find("*", , , , , xlPrevious).Row
End Function

Commenter la réponse de pijaku
ucfoutu 18039 Messages postés lundi 7 décembre 2009Date d'inscriptionModérateurStatut 11 avril 2018 Dernière intervention - 22 févr. 2016 à 11:20
0
Utile
1
Bonjour, Franck,
Il ne m'était (que je suis stupide ...) pas venu à l'idée que la méthode Find était capable également de rechercher parmi les lignes masquées ...
Ta solution est impeccable.
Dépose un petit snippet à ce propos.
Amitiés
pijaku 12205 Messages postés jeudi 15 mai 2008Date d'inscriptionModérateurStatut 13 septembre 2017 Dernière intervention - 22 févr. 2016 à 11:43
Dépose un petit snippet à ce propos.
C'est chose faite : ICI

A bientôt
Commenter la réponse de ucfoutu

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.