Traitement D'une colonne avec une liste
Bonjour,
je cherche actuellement à supprimer toutes les lignes ayant une cellule A égale à l'une des valeurs de ma liste.
voici la macro que j'utilise :
Sub suppressionSelonCritereceintre(ByVal ligne_index As Integer)
' --- --- --- By BibuNesco --- --- --- '
Dim Ws_source As Worksheet
Set Ws_source = ThisWorkbook.Worksheets("Critère") ' Feuille de la liste des critères à respecter
Dim Ws_cible As Worksheet
Set Ws_cible = ThisWorkbook.Worksheets("Traitement") ' Feuille où l'on va supprimer les lignes
derlig_source = Ws_source.Range("D" & Rows.Count).End(xlUp).Row ' Création d'un tableau avec la liste des critères
Dim tab_source() As Variant ' En supposant que la liste est sur une seule colonne partant de A1
tab_source = Ws_source.Range("A1", "A" & derlig_source).Value
derlig_cible = Ws_cible.Range("A" & Rows.Count).End(xlUp).Row
For i = ligne_index To derlig_cible
compteEgalite = 0
For j = 1 To UBound(tab_source, 1)
If tab_source(j, 1) = Ws_cible.Range("A" & i) Then
compteEgalite = compteEgalite + 1
End If
Next j
If compteEgalite = 0 Then
Ws_cible.Range("A" & i).EntireRow.Delete
Call suppressionSelonCritereceintre(i)
End If
Next iExcel n'arrive pas à suivre car je fais cela sur plus de 700 lignes avec une liste d'environ 200 valeurs.
Ces deux valeurs sont aussi variable, les lignes à traiter dépende d'une extraction hebdo et les valeurs de la liste d'un révérenciel qui évolue .
Quelqu'un aurait il une macro qui pourrait faire ceci ?
Je vous remercie par avance :)
Bonjour,
Voici un essai à améliorer probablement ! Ce code nécessite d'avoir la liste sous forme de tableau structuré nommé "Liste" :
Sub suppressionLignes()
set r = sheets("Traitement").usedrange 'plage utilisée en feuille traitement (range à sonder)
with r
t = .value 'tableau dynamique contenant valeurs de la range à sonder
For i = lbound(t) To ubound(t) 'pour chaque ligne
if application.countif(range("Liste"), t(i, 1)) = 0 then 'si la valeur en 1ère colonne de t n'existe pas dans la liste "Liste"
n = n + 1 'incrémentation de n (n représente le nombre de valeurs à conserver)
for k = lbound(t, 2) to ubound(t, 2) 'pour chaque colonne
t(n, k) = t(i, k) 'l'item n prend les valeurs de l'item i - méthode de tassement
next k
end if
Next i
.clearcontents 'suppression du contenu
if n > 0 then .resize(n, ubound(t, 2)).value = t 'restitution du contenu avec seulement les n lignes qui nous intéressent
end with
end subCdlt
Bonjour,
je ne comprend pas le fonctionnement de ta macro, surement par manque de connaissance car je commence juste en macro.
je redonne mon but je me suis peut-être mal exprimé.
Mais bon but est supprimer les lignes dont la cellule A, feuill1 n'est pas égale à une des valeurs de la liste de la colonne A,feuil2.
et de pouvoir adapter dans l'autre sens où si la valeur est égale alors la ligne est supprimer,
ma macro de base fonctionne très bien mais trop lourde je pense pour un traitement sur 800 ligne avec 300 ligne dans la liste car elle me fait planter excel, je voudrais donc pouvoir l'optimiser avec votre aide.
Bonjour,
J'ai édité mon précédent post pour y ajouter des commentaires.
Le code fonctionne en mémoire et, au lieu de supprimer les lignes dont la valeur en A existe dans "Liste", il garde les lignes dont la valeur en A n'existe pas dans "Liste". C'est équivalent...
La principale contrainte est d'avoir la liste des valeurs de la feuille 2 sous la forme d'un tableau structuré nommé "Liste" (ce qui est le minimum). Sinon, il faut savoir adapter le code pour le rendre plus complexe...
Cdlt,
j'ai une erreur lors du lancement de la macro :
Erreur d'exécution '1004'
La méthode 'Range' de l'objet '_Global' a échoué
ligne qu'il me surligne :
If Application.CountIf(Range("Liste"), t(i, 1)) = 0 Then 'si la valeur en 1ère colonne de t n'existe pas dans la liste "Liste"
Et à votre avis, à quoi pourrait être due cette erreur ? Je pense avoir déjà donné la réponse...
Bonjour,
j'ai bien structuré mon tableau nommé liste.
enfin je vais arrêter ce poste ici car je pense que vous ne pourrez pas m'aider d'avantage
Bonjour,
Le code que je t'avais fourni sur ce topic ne fonctionne pas ?
Tu peux me demander des éclaircissements si tu le souhaite.
Bibu
Bonjour bibu,
Ta macro marche parfaitement pour mon cas précédent, j'ai même pu la réutiliser sur d'autre sujet avec quelque modif.
Mais pour mon nouveau cas, La macro n'arrive pas à gérer la charge de donnée, elle fait planter l'Excel ou me dit que la charge de la liste est trop importante.
je fonctionne avec une liste de critère d'environ 300 valeurs et une colonne à traiter de plus de 700 lignes.
Si tu peux m'envoyer le fichier je peux essayer de faire quelque chose fonctionnera qu'importe le volume de données
Rappel du but du fichier: traiter la colonne A de la feuille traitement pour supprimer les lignes dont les valeurs sont égale à la colonne A de la feuille critère, sur un nombre de ligne non déterminée.
je te remercie par avance de ton aide.
j'ai vidée mon fichier de toutes les macros test.
Salut, essaye ça, de mon coté ça fonctionne sans bug (mais j'ai pas vérifié les lignes une par une)
Private Sub supprimerLignes()
' --- --- --- By BibuNesco --- --- --- '
Application.ScreenUpdating = False
Application.EnableEvents = False
Dim Ws_trait As Worksheet
Set Ws_trait = ThisWorkbook.Worksheets("Traitement")
Dim Ws_crit As Worksheet
Set Ws_crit = ThisWorkbook.Worksheets("Critère")
derlig_trait = Ws_trait.Range("A" & Rows.Count).End(xlUp).Row
derlig_crit = Ws_crit.Range("A" & Rows.Count).End(xlUp).Row
Dim tab_crit() As Variant
tab_crit = Ws_crit.Range("A1", "A" & derlig_crit)
For i = derlig_trait To 2 Step -1
compteEgalite = 0
For j = LBound(tab_crit, 1) To UBound(tab_crit, 1)
If Trim(UCase(Ws_trait.Range("A" & i))) = Trim(UCase(tab_crit(j, 1))) Then
compteEgalite = compteEgalite + 1
End If
Next j
If compteEgalite <> 0 Then
Ws_trait.Range("A" & i).EntireRow.Delete
End If
Next i
Application.ScreenUpdating = True
Application.EnableEvents = True
End SubTu peux noter que le Trim( UCase (...) ) servant dans la comparaison permet d'éviter quelques erreurs. Le Trim( ) retire les espaces avant et/ou après les valeurs qu'on compare, et le UCase( ) met tout en majuscule (au cas où il y ai des erreurs de saisies .. et il y en a, c'est pour ça que j'ai pensé à mettre UCase( ) ^^ ).
J'ai remplacé la récursivité de mon précédent programme (sûrement ça qui rendait le problème très lourd et augmentait sa complexité ..) en passant simplement par une boucle inversée, partant de la dernière pour aller à la première, et non l'inverse.
Pour faciliter la tâche à Excel, tu peux aussi utiliser des petites ruses telles que
Application.ScreenUpdating = FalsePour que l'écran n'aie pas à s'actualiser à chaque itération de la boucle (attention, de pas oublier de le remettre à True à la fin du programme !)
Bibu
Ca marche parfaitement et en 1 seconde,
je te remercie beaucoup pour ton aide et tes conseils.
je commence à comprendre un peux mieux le montage d'une macro : )
Pars du principe quand tu dois faire une macro, ou un programme en règle générale :
1. Faire quelque chose qui fonctionne
2. Essayer de le rendre plus robuste et sensible à la casse (par ex: ne pas utiliser des références de colonnes fixes, etc..)
3. Le factoriser, le fiabiliser et le rendre plus rapide
En espérant t'avoir aidé :)
Bibu
Bonjour POUL, Bonjour BibuNesco,
@POUL : Il ne fallait pas mal prendre ma question, j'ai juste douté du fait que vous ayez correctement nommé le tableau structuré.
Vous avez dit :
j'ai bien structuré mon tableau nommé liste.
Mais le code agit sur un tableau nommé "Liste" et non "liste". Si votre tableau était nommé "liste", il aurait suffi d'adapter le code en conséquence en remplaçant range("Liste") par range("liste").
Mais tant mieux si votre problème est résolu en tout cas.
Cdlt,