Se connecter avec
S'enregistrer | Connectez-vous

[vba] ma macros supprime tout

Dernière réponse : dans Programmation

salut c'est encore moi et oui
c'est toujours a propos d'une macros sur excel.
voila le topo :
j'ai deux classeurs :
ref |label | appli 2eme tableau appli |...........
----------------------- ----------------
1 | | x x |..........
------------------------ ------------------
2 | |y z |..............

alor voila ce que j'ai essayer de faire: dans le tableau 1 je voudrai supprimer toute les appli qui sont différentes des appli du tableau 2. (donc dans cette ex il devrai rester dans le tableau 1 que l'aplli x )
alor voila une partie de mon code qui ne fonctionne pas top :
  1. Workbooks(cl2).Activate ' tableau 1
  2. Dim tbl2() As String
  3. Dim i As Variant
  4. Dim j As Variant 'Nbre éléments du tableau
  5. Dim NbreLignes As Integer
  6. Dim Cel2 As Range
  7. Set Cel2 = Range("A1")
  8. NbreLignes = Cel2.End(xlDown).Row
  9.  
  10. For i = NbreLignes To 1 Step -1
  11. j = j + 1
  12. 'Redimension du tableau en conservant ses éléments
  13. ReDim Preserve tbl2(j)
  14. tbl2(j) = Cel2.Offset(i)
  15.  
  16. Workbooks(cl3).Activate 'tableau 2
  17. Dim tbl3() As String
  18. Dim k As Variant
  19. Dim l As Variant
  20. Dim NbreLignes2 As Integer
  21. Dim Cel3 As Range
  22. Set Cel3 = Range("A1")
  23. NbreLignes2 = Cel3.End(xlDown).Row - 1
  24.  
  25. For k = NbreLignes2 To 1 Step -1
  26. l = l + 1
  27. ReDim Preserve tbl3(l)
  28. tbl3(l) = Cel3.Offset(i)
  29. If Not(Cel2.Offset(i, 2) = Cel3.Offset(k, 0)) Then
  30. Workbooks(cl2).Activate
  31. Rows(1).Offset(i).Delete
  32. End If
  33. Next k
  34. Next i

le probleme c'est que sa supprime tout mon premier tableau et en faisan du pas à pas j'ai compris le problème
->il y aura toujours un Cel3.Offset(k, 0) qui sera différent d'un Cel2.Offset(i, 2)

alors voila je vous demande si il y a pas un moyen d'esquiver se problème

Autres pages sur : vba macros supprime

Lassé par la pub ? Créez un compte
Expert Programmation

Une solution et quelques commentaires.

Problème archi-classique de débutant :D 

Avant la seconde boucle, initialise un booleén à Faux, appelons le Trouvé.
Dans cette boucle, mets-le à Vrai si tu trouve quelque chose.
Après cette boucle, effectue la suppression si et seulement si Trouvé est Faux.

Et voilà !

Maintenant quelques conseils de vieux singe (T'en fais ce que tu veux).
Déclare toutes tes variables avant les traitements. Les lignes Dim.. en plein milieu d'une boucle, c'est très moche.
Evite la méthode Activate. Elle consomme plein de ressources et fait s'activer Excel pour rien. Quelques exemples :

Pas bon :
  1. Workbooks(cl2).Activate
  2. Set Cel2 = Range("A1")


Pas mal :
  1. Set Cel2 = Workbooks(cl2).Range("A1")


Dans d'autres cas, ne pas hésiter à faire :
  1. Set W2 = Workbooks(cl2)
  2. Set Cel2 = W2.Range("A1")

(Dans ce cas, une seule fois, ce n'est pas utile)

Il existe aussi le mot-clef With pour rappeler de quoi on parle sans avoir à le préciser à chaque fois.

Déclare les entiers en entiers, pas en variant !

Sors des boucles tout ce qui n'est pas indispensable.
Avant de rentrer dans les boucles, tu connais la taille des tableaux. Ne pas faire 50 ReDim.

Sois cohérent dans le nom de tes variables.
(C'est fait exprès, le i ligne 28 ?)

Ne compte pas sur le langage pour initialiser tes variables !!

  1. Dim tbl2() As String
  2. Dim tbl3() As String
  3. Dim i2 As Integer
  4. Dim j2 As Integer
  5. Dim i3 As Integer
  6. Dim j3 As Integer
  7. Dim NbreLignes2 As Integer
  8. Dim NbreLignes3 As Integer
  9. Dim Cel2 As Range
  10. Dim Cel3 As Range
  11. Dim Trouve As Boolean
  12.  
  13. Set Cel2 = Workbooks(cl2).Range("A1") ' Tableau 1
  14. Set Cel3 = Workbooks(cl3).Range("A1") ' tableau 2
  15. NbreLignes2 = Cel2.End(xlDown).Row
  16. NbreLignes3 = Cel3.End(xlDown).Row - 1
  17.  
  18. 'Redimension des tableaux
  19. ReDim tbl2(NbreLignes2)
  20. ReDim tbl3(NbreLignes4)
  21.  
  22. j2 = 0
  23. For i2 = NbreLignes2 To 1 Step -1
  24. j2 = j2 + 1
  25. tbl2(j2) = Cel2.Offset(i2)
  26. j3 = 0
  27. Trouve = False
  28. For i3 = NbreLignes3 To 1 Step -1
  29. j3 = j3 + 1
  30. tbl3(j3) = Cel3.Offset(i3)
  31. If Cel2.Offset(i2, 2) = Cel3.Offset(i3, 0) Then Trouve = True
  32. Next i3
  33. if Not Trouve Then Workbooks(cl2).Rows(1).Offset(i2).Delete
  34. Next i


Constate qu'après ça, la partie utile du code est bien plus claire et facilement compréhensive.

(Je n'ai pas l'habitude de donner un corrigé complet. Ce n'est pas aider le programmeur. Mais je donne tellement de conseils que je préfère les étayer avec un exemple)
Expert Programmation

Encore une remarque. les i et les j sont très liés. Tu peux faire sans les j.

  1. For i2 = 0 To NbreLignes2 - 1
  2. tbl2(j2) = Cel2.Offset(NbreLignes2 - i2)
  3. ..


Si tu as compris le pourquoi de toutes ses remarques, c'est toi bientôt qui aideras les autres ici ;) 

Zeb franchement merci japprend vraiment plein de truc et en plus je comprend pratiquement tout tu veu pas venir remplacer mon prof d'informatique qui est trop nul ? :) 
seul petit problème le programme veut pas de
  1. Set Cel2 = Workbooks(cl2).Range("A1") ' Tableau 1

ou aussi de
  1. Workbooks(cl2).Rows(1).Offset(i2).Delete

erreur d'execution 438: propriéré ou méthode non gérer par cet objet

c'est peut être à cause du début de mon code que voila : (il me sert pour nommer les nom de mes deux classeur ouvert )
  1. Dim cl2 As String
  2. Dim cl3 As String
  3. Dim cl As String
  4. Dim x As Workbook
  5. For Each x In Workbooks
  6. If x.Name <> ("PERSO1.XLS") Then
  7. If x.Name <> ("PERSO.XLS") Then
  8.  
  9. If cl3 <> cl2 Then
  10. cl = x.Name
  11. End If
  12. If x.Name <> cl Then
  13. cl2 = x.Name
  14. End If
  15. If x.Name = cl Then
  16. cl3 = x.Name
  17.  
  18. End If
  19. End If
  20. End If
  21. Next
Expert Programmation

Oups, le prof zeb est pas mieux que les autres :whistle: 

Evidemment, quand tu actives tel workbook, en même temps tu actives la feuille courante et la cellule courant.
Donc
  1. Workbooks(..).Sheets(..).Range(..)
devrait fonctionner.

desolé me suis mal expliquer je voudrai savoir si on peut comparer Cel2.Offset(i2, 2) au contenu de ma liste parce que UserForm1.ListBoxApplication ne contient rien et UserForm1.ListBoxApplication.list non plus et rowsource marche pas non plus
Expert Programmation

Qu'est-ce que ListBoxApplication, Le nom d'une ListBox sur ta UserForm ?

Bon. Essaye ce truc. (Marche tout le temps)
  1. Msgbox UserForm1.LsitBoxApplication ' Pour le mettre dans le contexte
  2. Stop

Au moment du stop, l'application s'arrête et te donne la main. Dans la fenêtre espion, ajoute ton UserForm1.ListBoxApplication et explore-le. Tu y trouveras peut être ton bonheur.

c'est j'ai esquiver le problème (solution de faciliter je sais )
mais j'ai encore un petit problème qui m'agace un peu
voila je voudrai ouvrir un fichier Excel a la fin de ma macro
voila mon code
  1. Dim objXL As New Excel.Application
  2.  
  3. With objXL
  4. .Application.Visible = False
  5. .Workbooks.Open ("//BATAX352/GMAO/Statut.xls" )
  6. End With

petit problème sa m'ouvre un autre fichier Excel et moi je vou drai que se sois dans le même que j'ai ouvert depuis le début(me suis je bien fait comprendre) .
Y a til solution?
Expert Programmation

M'enfin, tu comprends ce que tu codes ?

New Excel.Application, ça crée une nouvelle instance de l'application Excel.

  1. Workbooks.Open
s'applique soit à l'instance en cours (si tu ne précises rien) ou à une instance en particulier si tu précises
  1. Instance.Workbooks.Open

(Le With n'est une autre façon d'écrire ça.)

Je sais qu'il y a ce code:
  1. Application.StatusBar = "Traitement en cours" //par exemple

Pour changer ce qu'il y a d'écrit en bas de ta page.
Ce qui fait que tu peut y insérer des 10%, 25%, 50%, 75%...
Mais après, faire quelquechose qui évolue tout seul, aucune idée...

oups dernier petit probleme et apres je vous dit adieu
dans ma macro quand je fai ca
  1. Windows("Liste des Applications.xls").Close

il me demande si je veut enregister ou pas et moi je voudrai pas qu'il maffiche se messages c'est possible(et qu'il nenregistre pas)?

2 solutions:

  1. application.saved=true
  2. Windows("Liste des Applications.xls").Close

qui te permettra d'esquiver seulement la sauvegarde en faisant croire que tu as déjà sauvegardé

  1. application.displayalerts=false
  2. Windows("Liste des Applications.xls").Close

qui te permettra d'éviter la plupart des messages d'avertissement (à double tranchant).

Et alors t'as fait comment pour ta barre d'états? Pense à mettre la réponse en plus de la question, ca intéresse tout le monde.

dans ma premiere macro j'ai une grande boucle et elle dure au moin 10 s alors j'ai mis ca :
  1. For i = 1 To NbreLignes
  2. ....
  3. calci = (NbreLignes / i) * 100
  4. Application.StatusBar = calci & "%"
  5. ....
  6. Next i

ca fais pas mal je te remercie pour les tuyaux
Expert Programmation

Citation :
oups dernier petit probleme et apres je vous dit adieu
A bah non. Si tu as des questions tu seras toujours le bienvenu. :) 

En plus, maintenant que tu es devenu un cador en VBA et en programmation, merci de revenir souvent pour faire profiter les autres de tes futurs précieux conseils :o 

souso_95 a dit :
2 solutions:

  1. application.saved=true
  2. Windows("Liste des Applications.xls").Close

qui te permettra d'esquiver seulement la sauvegarde en faisant croire que tu as déjà sauvegardé

  1. application.displayalerts=false
  2. Windows("Liste des Applications.xls").Close

qui te permettra d'éviter la plupart des messages d'avertissement (à double tranchant).

Et alors t'as fait comment pour ta barre d'états? Pense à mettre la réponse en plus de la question, ca intéresse tout le monde.



La premiere solution me met un message d'erreur(propriete ou methode non gérer par cette objet) mais la deuxième marche nikel .

c'est clair, en plus chacun a sa propre logique. Il est souvent bon d'entendre plusieurs versions différente d'une solution pour un même problème.

Moi avec mes 3 mois d'expérience en vba, je pèse pas lourd, mais ca suffit souvent pour donner un coup de pouce au gens qui s'y mettent...

Idem pour toi :D 


non toujours pas mais bon l'autre me convient trés bien alors voila je voulai remercier toute l'équipe vous êtes franchement simpa avec tous les débutant et sans vous j'aurais vraiment pas beaucoup avancés . :hello: 
et a bientôt ;) 
Lassé par la pub ? Créez un compte