XL 2019 VBA Range().SpecialCells(xlCellTypeVisible).Rows

MilkaQuercy

XLDnaute Nouveau
Bonjour,

Je rencontre un problème. Je boucle sur les lignes visibles d'un tableau avec la méthode Range.SpecialCells(xlCellTypeVisible).Rows
Tableau sur lequel j'applique des filtres via la méthode Range.AutoFilter.

Dans l'exemple ci-dessous, la variable "Tab" correspond au nom de l'onglet. La variable "TableName" correspond au nom du tableau dans lequel je travail.
SortList() est un tableau Array de type string. Je vous passe l'étape dans laquelle je le remplie. L'opération de filtrage de mon tableau "TableName" fonctionne.

Admettons que mon tableau fait 10 lignes. Si les lignes filtrées visibles sont consécutives, la 3ème & la 4ème. La variable "J" va bien me renvoyer "2" pour 2 lignes visibles. La boucle va bien effectuer 2 tours.
Mon problème est le suivant : si les lignes filtrées visibles ne sont pas consécutives, la 3ème et la 5ème par exemple.
Dans ce cas la variable "J" va renvoyer "1" là où j'aimerais qu'elle me renvoie "2" pour 2 lignes visibles. La boucle va boucler plusieurs fois sur la 3ème ligne et plusieurs fois sur la 5ème. Donc la variable "I" va renvoyer "3" sur plusieurs tour avant de passer à "5" sur plusieurs tour et enfin sortir de la boucle. Alors que je devrais effectuer 2 tours, un pour la ligne 3 puis un pour la ligne 5.
Suivant les cas et essaies que j'ai pu faire, elle boucle plusieurs fois sur la même ligne : 6, 9 ou 12 fois. Multiple de 3...

Est-ce que cette méthode Range.SpecialCells(xlCellTypeVisible).Rows ne fonctionne que sur des lignes visibles successivent?
Est-ce que je fais une erreur, est-ce qu'il me manque un argument?

Je ne peux pas poster mon fichier, si besoin je peux en créer un avec la même fonction, ce serait très rapide.

VB:
Dim Ws As WorkSheet
Dim I, J As Integer
Dim Tab, TableName As String

Set Ws = WorkSheets(Tab)

Ws.ListObjects(TableName).Range.AutoFilter Field:=13, Criteria1:=SortList(), Operator:=xlFilterValues

J = Range(TableName).SpecialCells(xlCellTypeVisible).Rows.Count

For Each Line In Range(TableName).SpecialCells(xlCellTypeVisible).Rows
    I = Line.Row
Next Line
 

MilkaQuercy

XLDnaute Nouveau
As tu observé le fichier.
Les boucles fonctionnent dans un cas et pas dans l'autre.
Pourtant, dans les 2 cas, l'onglet et le tableau présent sur l'onglet portent le même nom.
Un chien peut s'appeler Zigoto et un chat aussi. Le chien reste un chien et le chat reste un chat.
On parlait de condescendance non?
 

TooFatBoy

XLDnaute Barbatruc
@Marcel32 non je ne boucle pas sur chaque cellule visible mais bien sur chaque ligne. Rien à voir avec le nombre de colonne, car le tableau de mon fichier d'origine a plus de 100 colonnes.
Je viens de faire un test, et en fait tu boucles sur chaque "Area" visible (groupe de cellules visibles contiguës) dans le sens des colonnes.

VB:
For Each Line In Range("Final_Result").SpecialCells(xlCellTypeVisible).Rows
    I = Line.Row
    y = Line.Address
Next Line
Regarde la valeur de la variable y à chaque tour. ;)
 

MilkaQuercy

XLDnaute Nouveau
Je viens de faire un test, et en fait tu boucles sur chaque "Area" visible (groupe de cellules visibles contiguës).

VB:
For Each Line In Range("Final_Result").SpecialCells(xlCellTypeVisible).Rows
    I = Line.Row
    y = Line.Address
Next Line
Regarde la valeur de la variable y à chaque tour. ;)
En effet, sais-tu pourquoi la méthode de boucler sur la première colonne que tu as évoqué ne fonctionne pas dans mon cas?
 

patricktoulon

XLDnaute Barbatruc
re
écoute si de te rendre compte de tes lacunes provoque chez toi un malaise ceux qui t'aident n'en sont pas responsables
j'ai testé sur ton fichier
demo
demo.gif
 

MilkaQuercy

XLDnaute Nouveau
@patricktoulon ta démo ne sert à rien, sur l'onglet sur lequel tu travailles, je dis depuis le début que ça fonctionne (sauf la méthode If Line.Hidden = "False" Then)

Bref la conclusion est la suivante :
Comme le dis @Marcel32 la méthode Range().SpecialCells(xlCellTypeVisible).Rows boucle sur chaque "Area" visible (groupe de cellules visibles contiguës)
Sur le tableau de mon fichier d'origine, des colonnes sont masquées via groupement de colonne. La boucle se répétait donc sur chaque area visible. Ce qui explique pourquoi j'avais l'impression que ça bouclait plusieurs fois sur la même ligne. Visualiser l'adresse renvoyée l'a démontré. Merci @Marcel32.
Lorsque j'ai testé la méthode de @job75 j'ai renseigné Columns(1) comme il le suggérais. J'avais une erreur. Erreur dû au fait que la colonne 1 était masquée. Il m'a fallu soit ouvrir le groupement de colonnes, soit changer l'indice par une colonne visible pour que l'erreur disparaissent.

La méthode de remplir une variable (range) avec les lignes visibles puis de boucler dans cette variable, revenait au même.

Au final le problème depuis le début est le groupement de colonnes. Si toutes mes colonnes sont visibles, pas besoin de boucler uniquement sur une colonne. Si elles ne le sont pas, il faut boucler sur une colonne toujours visible.

J'ai donc trouvé la solution à mon problème, grâce à vous. Merci.
@patricktoulon, merci à toi aussi, il y avait peut être beaucoup de frustration de mon côté, ne pas trouver la solution en retournant le problème dans tous les sens me met dans tous mes états.

Bon weekend à tous.
 

patricktoulon

XLDnaute Barbatruc
re
y a pas de soucis
tu le saura pour l'avenir si tu dois boucler sur une plage filtré
NE PAS UTILISER DIRECTEMENT SPECIALCELLS(XLTYPEVISIBLE).ROWS dans une boucle
mais une des 4 méthodes proposées
ps: perso la méthode colums(x) étant pour moi la plus ennuyante puisqu' il faudrait l'adapter au besoins a chaque fois alors que les autres sont universelle

et je peux comprendre l'agacement quand on pèche sur un problème apparemment simple tu n'est pas le seul a qui ça arrive
 

job75

XLDnaute Barbatruc
Je crois que ce qu'il veut dire c'est simplement que si toutes les colonnes sont visibles, alors il n'y aura qu'un seul "Area" par ligne, et donc un seul passage sur chaque ligne visible. ;)
Non sur le fichier de mon post #7 J prend la valeur 1 si l'on utilise les Rows au lieu des cellules.

Mais on n'est pas obligé d'utiliser SpecialCells, fichier (2) :
VB:
Sub Filtrer()
Dim Ws As Worksheet
Dim I As Long
Dim Tabl As String, TableName As String
Dim SortList()
Dim Ligne As Range

Tabl = "Feuil1"
TableName = "Tableau1"
SortList = Array("a", "b", "c")
Set Ws = Worksheets(Tabl)

Ws.ListObjects(TableName).Range.AutoFilter Field:=13, Criteria1:=SortList(), Operator:=xlFilterValues

For Each Ligne In Range(TableName).Rows
    If Not Ligne.Hidden Then I = I + 1: MsgBox "Numéro de ligne : " & Ligne.Row 'pour tester
Next Ligne

MsgBox "Nombre de lignes : " & I 'pour tester

End Sub
 

Pièces jointes

  • Classeur(2).xlsm
    18.9 KB · Affichages: 9

Discussions similaires

Réponses
2
Affichages
653