Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1665 connectés 

  FORUM HardWare.fr
  Programmation
  VB/VBA/VBS

  bug PC à cause d'une macro

 


 Mot :   Pseudo :  
 
 Page :   1  2
Page Précédente
Auteur Sujet :

bug PC à cause d'une macro

n°2174147
minimoack
Posté le 05-02-2013 à 13:27:11  profilanswer
 

Euh... pourquoi Dans le If : si je mets Range(..) à la place de Cells(..) j'ai une erreur, et si je laisse Cells(..), ben j'ai mon ordinateur en mode écran noir, l'écran se met en veille, l'ordi toujours allumé mais impossible d'avoir une réponse, pas de ctrl alt suppr rien, donc obligé de shut down... ?
 
(i étant un compteur)
 

Code :
  1. For Each Cell In Selection
  2.         If Not (Cell.Value Like "D*" ) Then
  3.             Rows(i).Delete shift:=xlUp
  4.             i = i - 1
  5.         End If
  6.         If Cells(i, 1).Value = "" And Cells(i + 1, 1).Value = "" And Cells(i + 2, 1).Value = "" Then
  7.             Exit For
  8.         End If
  9.         i = i + 1
  10. Next Cell

mood
Publicité
Posté le 05-02-2013 à 13:27:11  profilanswer
 

n°2174154
minimoack
Posté le 05-02-2013 à 13:59:42  profilanswer
 

Si la cellule ne commence pas par D, Alors on supprime la ligne, et on décrémente i pour reprendre correctement le parcours des lignes
 
Si 3 cellules consécutives sont vides (c'est-à-dire qu'on est à la fin du tableau) Alors on sort du For

n°2174155
vave
Nice to meet me
Posté le 05-02-2013 à 13:59:56  profilanswer
 

For each et like doivent utiliser pas mal de mémoire je pense.

 

Tu devrais essayer avec une boucle type do ... loop et à la place du like "D*" faire un left(cells(i,1).value, 1) = "D".

 
Code :
  1. i = LigneMax
  2. do while i <> 1 step -1
  3.    if left(cells(i,1).value, 1) <> "D" then
  4.       Rows(i).Delete shift:=xlUp
  5. ... etc
  6. loop
 

Y a sûrement des erreurs dans mon code, je l'ai écrit directement dans le post.


Message édité par vave le 05-02-2013 à 14:00:12

---------------
Bel ours Vave, je me dois de l’admettre. -Skyl"win"-  Mais toi tu es intelligent -Homerde- - Ce génie -SkylWINd- JDD S16M72 10:43:46 GMT-DTC +1
n°2174156
minimoack
Posté le 05-02-2013 à 14:02:16  profilanswer
 

je n'ai pas LigneMax, vu que le tableau ne sera pas toujours de la même taille... :(

n°2174158
vave
Nice to meet me
Posté le 05-02-2013 à 14:08:41  profilanswer
 

Tu peux la trouver comme ça :
(la colonne est à adapter) :

 
Code :
  1. LigneMax = Range("A1048576" ).End(xlUp).Row
 

1048576 à partir d'excel 2007, 65536 avant.

 

Ca revient à te positionner tout en bas de l'onglet et de faire ctrl + flèche du haut => ça t'emmène à la dernière cellule renseignée.


Message édité par vave le 05-02-2013 à 14:09:04

---------------
Bel ours Vave, je me dois de l’admettre. -Skyl"win"-  Mais toi tu es intelligent -Homerde- - Ce génie -SkylWINd- JDD S16M72 10:43:46 GMT-DTC +1
n°2174159
minimoack
Posté le 05-02-2013 à 14:09:47  profilanswer
 

ooooh... c'est bon à savoir ça!! :D
merci je vais essayé :)

n°2174164
minimoack
Posté le 05-02-2013 à 14:17:34  profilanswer
 

alors... j'ai fait :  

Code :
  1. i = ligneMax
  2.        
  3.     ' Suppression des lignes inutiles
  4.     Do While i <> 1
  5.         If Left(Cells(i, 1).Value, 1) <> "D" Then
  6.             Rows(i).Delete shift:=xlUp
  7.             i = i - 1
  8.         End If
  9.         i = i + 1
  10.     Loop


 
 
et mon PC a redémarré...

n°2174165
minimoack
Posté le 05-02-2013 à 14:18:11  profilanswer
 

avec ligneMax = Range("A65536 " ).End(xlUp).Row

n°2174169
minimoack
Posté le 05-02-2013 à 14:33:06  profilanswer
 

et le problème vient de cette partie du code, vu que si je mets le do loop en commentaire, ça fonctionne...  Là j'ai eu mon écran qui a "clignoté un peu", puis mon PC a redémarré...

n°2174173
minimoack
Posté le 05-02-2013 à 14:52:29  profilanswer
 

erreur stupide j'ai fait


Message édité par minimoack le 05-02-2013 à 14:52:41
mood
Publicité
Posté le 05-02-2013 à 14:52:29  profilanswer
 

n°2174174
vave
Nice to meet me
Posté le 05-02-2013 à 14:53:47  profilanswer
 

Tu as encore le problème ?


---------------
Bel ours Vave, je me dois de l’admettre. -Skyl"win"-  Mais toi tu es intelligent -Homerde- - Ce génie -SkylWINd- JDD S16M72 10:43:46 GMT-DTC +1
n°2174175
rufo
Pas me confondre avec Lycos!
Posté le 05-02-2013 à 14:55:04  profilanswer
 

Tu ferais mieux de partir de la première colonne de la première ligne et scanner le contenu et voir s'il est non nul (ou prendre une autre colonne), passer à la suivante jusqu'à trouver la dernière ligne de ton tableau.. Ca devrait aller plus vite que de partir de la fin du nb de lignes max d'Excel :/


---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Planeta Calandreta : https://framalibre.org/content/planeta-calandreta
n°2174176
Marc L
Posté le 05-02-2013 à 14:57:49  profilanswer
 

 
           Il y a une grosse erreur de "logique" dans le dernier code ‼   Personnellement je préfères une boucle comme dans le premier …
 
           Ensuite, c'est parfois risqué de travailler avec Selection sans contrôle au préalable.
           De plus je note le même souci de logique avec un coup i = i - 1 puis plus bas i = i + 1 ...
 
           Sans code plus exhaustif ni une explication claire des besoins, je ne pourrais aider …
 

n°2174177
minimoack
Posté le 05-02-2013 à 15:00:15  profilanswer
 

Code :
  1. Do While i <> 1
  2.         If Left(Cells(i, 1).Value, 1) <> "D" Then
  3.            Rows(i).Delete shift:=xlUp
  4.         End If
  5.         i = i - 1
  6.     Loop


 A oovaveoo : ben je pense qu'il boucle à l'infini car MsbBox de ligneMax me renvoie 757 alors que ma dernière ligne 754
 
A rufo : c'est ce que j'avais fait au début avec

Code :
  1. If Cells(i, 1).Value = "" And Cells(i + 1, 1).Value = "" And Cells(i + 2, 1).Value = "" Then
  2.             Exit For
  3.         End If

mais ça ne marchait pas...  
en fait, j'ai des lignes vides dans mon tableau, donc je suis obligée de faire un test sur au moins deux cellules vides consécutivement
 
 

n°2174178
vave
Nice to meet me
Posté le 05-02-2013 à 15:00:59  profilanswer
 

rufo a écrit :

Tu ferais mieux de partir de la première colonne de la première ligne et scanner le contenu et voir s'il est non nul (ou prendre une autre colonne), passer à la suivante jusqu'à trouver la dernière ligne de ton tableau.. Ca devrait aller plus vite que de partir de la fin du nb de lignes max d'Excel :/


C'est ce qu'on fait dans excel et normalement c'est immédiat.

Marc L a écrit :

 
           Il y a une grosse erreur de "logique" dans le dernier code ‼   Personnellement je préfères une boucle comme dans le premier …
 
           Ensuite, c'est parfois risqué de travailler avec Selection sans contrôle au préalable.
           De plus je note le même souci de logique avec un coup i = i - 1 puis plus bas i = i + 1 ...
 
           Sans code plus exhaustif ni une explication claire des besoins, je ne pourrais aider …
 


La boucle du premier avec For Each ?
 


---------------
Bel ours Vave, je me dois de l’admettre. -Skyl"win"-  Mais toi tu es intelligent -Homerde- - Ce génie -SkylWINd- JDD S16M72 10:43:46 GMT-DTC +1
n°2174179
minimoack
Posté le 05-02-2013 à 15:02:02  profilanswer
 

Marc L a écrit :

 
           Il y a une grosse erreur de "logique" dans le dernier code ‼   Personnellement je préfères une boucle comme dans le premier …
 
           Ensuite, c'est parfois risqué de travailler avec Selection sans contrôle au préalable.
           De plus je note le même souci de logique avec un coup i = i - 1 puis plus bas i = i + 1 ...
 
           Sans code plus exhaustif ni une explication claire des besoins, je ne pourrais aider …
 


 
Bah sur mon code du début, je fais i-1 lorsque je supprime une ligne, car sinon je louperais des lignes, puis après j'incrémente... ce n'est pas une erreur de logique

n°2174180
minimoack
Posté le 05-02-2013 à 15:03:14  profilanswer
 

si je supprime la ligne 3 par exemple, la ligne 4 va prendre la place de la ligne 3. Donc je dois décrémenter i quand je supprime, et l'incrémenter à la fin de ma boucle

n°2174181
minimoack
Posté le 05-02-2013 à 15:06:15  profilanswer
 

Marc L a écrit :

 
           Il y a une grosse erreur de "logique" dans le dernier code ‼   Personnellement je préfères une boucle comme dans le premier …
 
           Ensuite, c'est parfois risqué de travailler avec Selection sans contrôle au préalable.
           De plus je note le même souci de logique avec un coup i = i - 1 puis plus bas i = i + 1 ...
 
           Sans code plus exhaustif ni une explication claire des besoins, je ne pourrais aider …
 


 
Les besoins, je les ai mis plus haut :  

Citation :

Si la cellule ne commence pas par D, Alors on supprime la ligne, et on décrémente i pour reprendre correctement le parcours des lignes
 
Si 3 cellules consécutives sont vides (c'est-à-dire qu'on est à la fin du tableau) Alors on sort du For


 
je pense que c'est plutot clair non?

n°2174182
vave
Nice to meet me
Posté le 05-02-2013 à 15:07:56  profilanswer
 

Comme ça sinon :

Code :
  1. ligneMax = Range("A65536 " ).End(xlUp).Row
  2. For i = ligneMax To 1 Step -1
  3.         If Left(Cells(i, 1).Value, 1) <> "d" Then
  4.            Rows(i).Delete shift:=xlUp
  5.         End If
  6. Next


---------------
Bel ours Vave, je me dois de l’admettre. -Skyl"win"-  Mais toi tu es intelligent -Homerde- - Ce génie -SkylWINd- JDD S16M72 10:43:46 GMT-DTC +1
n°2174184
Marc L
Posté le 05-02-2013 à 15:10:21  profilanswer
 

 
           +1 avec oovaveoo, j'étais pratiquement en train de poster le même code !
 

n°2174185
vave
Nice to meet me
Posté le 05-02-2013 à 15:10:58  profilanswer
 

Et pour les 3 lignes vides, tu ajoutes un compteur :
 

Code :
  1. compteur = 0
  2. ligneMax = Range("A65536 " ).End(xlUp).Row
  3. For i = ligneMax To 1 Step -1
  4.         If Left(Cells(i, 1).Value, 1) <> "d" Then
  5.            Rows(i).Delete shift:=xlUp
  6.         End If
  7. if cells(i,1) = "" then
  8. compteur = compteur+1
  9.     if compteur = 3 then: exit for
  10. else
  11. compteur = 0
  12. end if
  13. Next


---------------
Bel ours Vave, je me dois de l’admettre. -Skyl"win"-  Mais toi tu es intelligent -Homerde- - Ce génie -SkylWINd- JDD S16M72 10:43:46 GMT-DTC +1
n°2174186
minimoack
Posté le 05-02-2013 à 15:11:46  profilanswer
 

ça ne peut pas marcher, il va boucler à l'infini non?

n°2174187
minimoack
Posté le 05-02-2013 à 15:14:22  profilanswer
 

je vais essayer! si je mets du temps à répondre, c'est que mon PC a planté! :D

n°2174188
Marc L
Posté le 05-02-2013 à 15:17:26  profilanswer
 

 
           Au contraire vu que les bornes sont cette fois bien définies et non modifiées en cours de route !
 
           Dans le cas de suppression de lignes, il faut remonter vers le haut pour ne pas avoir de souci …
 
           A tous, mieux vaut éviter de mettre en dur le numéro de la dernière ligne car lorsque l'on change de version d'Excel …
           … et qu'il est extrêmement simple de l'obtenir :   Rows.Count  !

Code :
  1. For i = Cells(Rows.Count, 1).End(xlUp).Row To 1 Step -1

n°2174190
minimoack
Posté le 05-02-2013 à 15:22:18  profilanswer
 

bon... je viens de redémarrer...

Code :
  1. If Left(Cells(i, 1).Value, 1) <> "d" Then
  2.            Rows(i).Delete shift:=xlUp
  3. End If


 
il faut pas plutot mettre :=xldown?
 
parce que imaginons :  
la macro supprime la dernière ligne du tableau (749) car la cellule est de type "----". Donc la ligne 750 qui est vide va prendre la place de la 749, et la macro boucle dessus... non?

n°2174192
vave
Nice to meet me
Posté le 05-02-2013 à 15:28:58  profilanswer
 

Marc L a écrit :

 
           Au contraire vu que les bornes sont cette fois bien définies et non modifiées en cours de route !
 
           Dans le cas de suppression de lignes, il faut remonter vers le haut pour ne pas avoir de souci …
 
           A tous, mieux vaut éviter de mettre en dur le numéro de la dernière ligne car lorsque l'on change de version d'Excel …
           … et qu'il est extrêmement simple de l'obtenir :   Rows.Count  !

Code :
  1. For i = Cells(Rows.Count, 1).End(xlUp).Row To 1 Step -1



C'est noté ;)  

minimoack a écrit :

bon... je viens de redémarrer...

Code :
  1. If Left(Cells(i, 1).Value, 1) <> "d" Then
  2.            Rows(i).Delete shift:=xlUp
  3. End If


 
il faut pas plutot mettre :=xldown?
 
parce que imaginons :  
la macro supprime la dernière ligne du tableau (749) car la cellule est de type "----". Donc la ligne 750 qui est vide va prendre la place de la 749, et la macro boucle dessus... non?


Ben non, essaye tu verras.
 


---------------
Bel ours Vave, je me dois de l’admettre. -Skyl"win"-  Mais toi tu es intelligent -Homerde- - Ce génie -SkylWINd- JDD S16M72 10:43:46 GMT-DTC +1
n°2174193
minimoack
Posté le 05-02-2013 à 15:30:33  profilanswer
 

ça marche avec xlDown, et pas avec xlUp

n°2174194
minimoack
Posté le 05-02-2013 à 15:31:53  profilanswer
 

je ne sais pas vraiment pourquoi... mais avec xlUp il m'éteignait systématiquement l'ordi, et avec xlDown non... j'ai tout ce que je veux là... ben Merci pour votre aide :D  
:jap:

n°2174195
minimoack
Posté le 05-02-2013 à 15:47:31  profilanswer
 

Un dernier petit truc :  
je souhaite faire un for pour supprimer la récurrence des entêtes des colonnes dans mon tableau. Vaut-il mieux utiliser celui que vous m'avez montré, et l'alourdir, ou vaut-il mieux en créer un autre? quelle solution est la moins lourde?

n°2174196
vave
Nice to meet me
Posté le 05-02-2013 à 15:52:15  profilanswer
 

Si tu dois tester toutes les lignes, il vaut mieux utiliser la même boucle, ça les parcourras qu'une seule fois.


---------------
Bel ours Vave, je me dois de l’admettre. -Skyl"win"-  Mais toi tu es intelligent -Homerde- - Ce génie -SkylWINd- JDD S16M72 10:43:46 GMT-DTC +1
n°2174197
minimoack
Posté le 05-02-2013 à 15:55:35  profilanswer
 

oki merci :D

n°2174200
minimoack
Posté le 05-02-2013 à 16:24:30  profilanswer
 

Bon... en fait ça me shut down environs une fois sur deux...


Message édité par minimoack le 05-02-2013 à 16:43:10
n°2174202
minimoack
Posté le 05-02-2013 à 16:48:06  profilanswer
 

Voici donc mon code actuel :  

Code :
  1. For i = ligneMax To 1 Step -1
  2.         If Cells(i, 1).Value = Range("A1" ).Value Then
  3.             Rows(i).Delete
  4.         End If
  5.         If Left(Cells(i, 1).Value, 1) <> "D" Then
  6.             Rows(i).Delete shift:=xlDown
  7.         End If
  8.         If Cells(i, 1) = "" Then
  9.             compteur = compteur + 1
  10.         If compteur = 3 Then: Exit For
  11.         Else
  12.             compteur = 0
  13.         End If
  14.     Next


 
y-aurait-il un moyen de l'alléger? Il me shut down une fois sur deux, donc il marche, mais  il est trop lourd je crois...

n°2174206
vave
Nice to meet me
Posté le 05-02-2013 à 17:15:40  profilanswer
 

T'as beaucoup de lignes ?
 
Sinon, une autre solution serait de filtrer les lignes qui ne commencent pas par D et les supprimer.
Avec l'enregistreur de macro ça doit bien se faire.


---------------
Bel ours Vave, je me dois de l’admettre. -Skyl"win"-  Mais toi tu es intelligent -Homerde- - Ce génie -SkylWINd- JDD S16M72 10:43:46 GMT-DTC +1
n°2174231
Marc L
Posté le 05-02-2013 à 19:20:24  profilanswer
 

 
           Avant toute chose, où se situe le code : dans un module, dans une classe d'une feuille ou ThisWorkbook ?

 

           La feuille traitée a l'air d'être la feuille active, fait-elle partie du classeur contenant le code ou d'un autre classeur ?
           Si c'est un classeur de macros (.xla), il faut alors bien qualifier les objets, éviter donc les raccourcis …

 

           J'éviterais le compteur (même si je pense qu'il ne pause pas de problème sauf peut-être la syntaxe employée),
           je remplacerais les lignes 8 à 13 par celle-ci :

Code :
  1. If Cells(i, 1) = "" And Cells(i + 1, 1) = "" And Cells(i + 2, 1) = "" Then Exit For


            Edit :   en fait il n'y a pas besoin de compteur car c'est une remontée et non pas une descente !

 

            De plus, je suppose que la première ligne ne doit pas être supprimée (à cause du test avec la cellule A1),
            donc la remontée devrait s'arrêter à ligne 2;    la non imbrication des If pourrait poser problème
            alors qu'à mon avis il faudrait les combiner comme ceci :

Code :
  1.     Application.EnableCancelKey = xlInterrupt
  2.     For i = Cells(Rows.Count, 1).End(xlUp).Row To 2 Step -1
  3.         If Cells(i, 1) > "" And (Cells(i, 1) = [A1] Or _
  4.                             Left(Cells(i, 1), 1) <> "D" ) Then Rows(i).Delete
  5.     Next
  6.     Application.EnableCancelKey = xlDisabled
 

            Astuce :   la première ligne permet de suspendre la boucle via la touche ECHAP …


Message édité par Marc L le 06-02-2013 à 01:44:00
n°2174259
minimoack
Posté le 06-02-2013 à 09:04:11  profilanswer
 

Alors :  
le code est dans un module. Les fonctions qui y sont, sont appelées dans le ThisWorkbook.
Les données sont dans un autre classeur : je pars de Classeur1.xls qui contient la macro, et qui ouvre un fichier txt dans un excel.
 
je vais tester ça merci! et super l'astuce de la touche échap, j'étais bien embêtée :D

n°2174269
Marc L
Posté le 06-02-2013 à 10:16:05  profilanswer
 

 
           Comme dans un cas similaire en version 2003 j'ai été obligé de qualifier complètement les objets
           (exemple :   ActiveWorkbook.ActiveSheet.Cells(i, 1)   au lieu de   Cells(i, 1)   tout court …),
           je pense que dans ta version 2002 il faut aussi être rigoureux !

 

           Mais cela demande une vue d'ensemble, insuffisante avec des bouts de code …


Message édité par Marc L le 06-02-2013 à 10:16:54
n°2174271
minimoack
Posté le 06-02-2013 à 10:29:50  profilanswer
 

je vais le faire merci :D

n°2174272
minimoack
Posté le 06-02-2013 à 10:30:30  profilanswer
 

c'est ma principale fonction.
 
dans mon programme principal, j'ouvre un fichier, et j'appelle cette fonction, c'est tout

n°2174276
Marc L
Posté le 06-02-2013 à 11:01:41  profilanswer
 

 
           Soit une variable objet est créée juste après l'ouverture du fichier

Code :
  1.     Workbooks.Open […]
  2.     Set Ws = ActiveWorkbook.ActiveSheet

           puis cette référence est utilisée dans le code

Code :
  1.     For i = Ws.Cells(Ws.Rows.Count, 1).End(xlUp).Row To 2 Step -1
  2.         If Ws.Cells(i, 1) > "" And (Ws.Cells(i, 1) = Ws.[A1] Or _
  3.                                Left(Ws.Cells(i, 1), 1) <> "D" ) Then Ws.Rows(i).Delete
  4.     Next

          (l'utilisation de variables objet est pratique pour "naviguer" entre 2 classeurs ou feuilles),
 
          soit l'objet est qualifié ponctuellement dans une structure With
          (dans ce cas ne pas oublier le point devant chaque propriété y faisant référence)

Code :
  1.     With ActiveWorkbook.ActiveSheet
  2.         For i = .Cells(.Rows.Count, 1).End(xlUp).Row To 2 Step -1
  3.             If .Cells(i, 1) > "" And (.Cells(i, 1) = .[A1] Or _
  4.                                  Left(.Cells(i, 1), 1) <> "D" ) Then .Rows(i).Delete
  5.         Next
  6.     End With

mood
Publicité
Posté le   profilanswer
 

 Page :   1  2
Page Précédente

Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  VB/VBA/VBS

  bug PC à cause d'une macro

 

Sujets relatifs
Macro excel : le nom de variable apparaît dans la formule excelMACRO EXCEL
Macro Word 2010 / Autoexec replacemacro copier coller
Aide pour Macro Excelmacro sur excel
MacroComment exécuter ma macro Excel automatiquement ?
macro recherche cellules dans 2 fichiersMise en page d'un signet sous Word par macro
Plus de sujets relatifs à : bug PC à cause d'une macro


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR