Macro rechercher remplacer [Résolu]

Macro rechercher remplacer [Résolu] - VB/VBA/VBS - Programmation

Marsh Posté le 22-03-2013 à 11:58:37    

Bonjour à tous,
 
Avec l'aide de l'enregistreur de macro Excel j'ai créé cette Macro pour rechercher et remplacer.
 
Sub Macro1()
Macro1 Macro
 
    Sheets(Array("Nom feuille 1", "Nom feuille 2", "Nom feuille 3" )).Select
    Sheets("Nom feuille 1" ).Activate
    Columns("V:BO" ).Select
    Selection.Replace What:=",", Replacement:=".", LookAt:=xlPart, _
        SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, _
        ReplaceFormat:=False
    Sheets("Nom feuille 1" ).Select
    Range("H1:P1" ).Select
End Sub
 
J'ai essayer de modifier quelques lignes car je souhaite faire une référence au code name des feuilles pour que, si le nom d'une feuille est modifié il n'y ait pas d'impact sur la macro, mais sans succès.
 
D'autre part j'aimerais aussi ajouter 2 autres options :
 
1) Donner une condition pour que la macro se lance automatiquement et en une seule fois
Ma condition serait si la cellule A1 de mes 3 feuilles est non vide alors la macro peut se lancer automatiquement
 
2) J'aimerais que si la macro ne trouve rien, elle ne remplace rien ou ne se lance pas.
 
 
Merci pour votre aide.

Message cité 1 fois
Message édité par benoug le 22-03-2013 à 17:41:55
Reply

Marsh Posté le 22-03-2013 à 11:58:37   

Reply

Marsh Posté le 22-03-2013 à 13:39:36    

 
            Bonjour.

benoug a écrit :

2) J'aimerais que si la macro ne trouve rien, elle ne remplace rien ou ne se lance pas.

            :lol:   Merci pour ce moment de logique improbable ‼
 
 
            Au lieu de spécifier le nom de la feuille comme dans

      Worksheets("Nom feuille 1" ).Activate

            il est préférable d'indiquer soit le numéro de la feuille (voir l'aide intégrée de VBA concernant l'objet Worksheet)
            soit le nom objet (le fameux CodeName !) de la feuille tel qu'il apparaît dans l'environnement VBA avant les parenthèses,
            par défaut Feuil1 (nom de la feuiile)

      Worksheets(1).Activate          ou          Feuil1.Activate

           Pour désigner par exemple la cellule A1 de la feuille 2 :

      Worksheets(2).[A1]              ou          Feuil2.[A1]


            Le code exposé ne traite qu'une seule feuille, donc la première ligne avec  .Select  ne sert à rien,  comme les deux dernières ‼
 
            Pour trouver quelque chose dans une feuille, voir l'aide intégrée de VBA concernant sa puissante méthode Find.
 
            Sinon de nécessaires claires explications pour de l'aide apporter …
 

Reply

Marsh Posté le 22-03-2013 à 15:30:07    

Je n'ai pas bien compris votre réponse.
Cependant j'ai avancé dans mon code que je vais coller dans chaque feuille.
Mais il y a un problème car la macro ne s'arrête pas elle tourne en boucle j'ai été obligé de forcer l'arrêt d'Excel
 
Est ce que vous avez une idée ?
Merci pour vos réponses.
 
Private Sub Worksheet_Change(ByVal Target As Excel.Range)
If [A1] = "Année" Then
    Columns("V:BO" ).Select
    Selection.Replace What:=",", Replacement:=".", LookAt:=xlPart, _
        SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, _
        ReplaceFormat:=False
MsgBox "Opération réalisé avec succès", vbInformation, "Rechercher-remplacer"
 
Else
MsgBox "Veuillez coller la base en A1", vbExclamation, "Attention"
End If
End Sub


Message édité par benoug le 22-03-2013 à 15:33:48
Reply

Marsh Posté le 22-03-2013 à 16:22:28    

Code :
  1. Private Sub Worksheet_Change(ByVal Target As Excel.Range)
  2.     If [A1] = "Année" Then
  3.         Application.EnableEvents = False
  4.         Columns("V:BO" ).Replace ",", ".", xlPart, xlByRows, False, , False, False
  5.         MsgBox "Opération réalisée avec succès", vbInformation, "Rechercher-remplacer"
  6.         Application.EnableEvents = True
  7.     Else
  8.         MsgBox "Veuillez coller la base en A1", vbExclamation, "Attention"
  9.     End If
  10. End Sub

           Aide primaire :   curseur sur une instruction puis touche F1 …
 

Reply

Marsh Posté le 22-03-2013 à 16:55:55    

Merci beaucoup, ça fonctionne.
Ma base étant assez conséquente comment puis je intégrer une MsgBox pendant l'exécution de la macro qui demande de patienter ?
 
Merci pour votre réponse.

Reply

Marsh Posté le 22-03-2013 à 17:30:03    

 
           Impossible avec MsgBox
 
           Il y a bien la solution de créer un Userform en mode non modal mais pas simple pour un débutant à mettre en œuvre …
 
           Le plus simple est d'afficher le message soit dans une cellule de la feuille
           soit dans la barre d'état (voir l'aide de la propriété StatusBar).
 
           Pour accélérer le traitement, il faut penser aussi à désactiver le rafraichissement de l'écran :

Code :
  1. Private Sub Worksheet_Change(ByVal Target As Excel.Range)
  2.     If [A1] = "Année" Then
  3.         Application.EnableEvents = False: Application.ScreenUpdating = False
  4.         Columns("V:BO";).Replace ",", ".", xlPart, xlByRows, False, , False, False
  5.         Application.EnableEvents = True:  Application.ScreenUpdating = True
  6.         MsgBox "Opération réalisée avec succès", vbInformation, "Rechercher-remplacer"
  7.     Else
  8.         MsgBox "Veuillez coller la base en A1", vbExclamation, "Attention"
  9.     End If
  10. End Sub


           Si c'est toujours long après cette modification, la conception du code est certainement à revoir !
 
           Dans l'hypothèse d'une modification d'une seule et unique cellule, le Replace est exécuté sur l'intégralité des colonnes V à BO
           et ce, même si cette cellule est située en dehors de ces colonnes, si ce n'est pas un peu bêta cela, non ?‼
 
           D'autant dommage car dans cet événement de feuille la variable  Target  renvoie uniquement les cellules modifiées …
           En la croisant avec ces colonnes via la méthode  Intersect  il y aurait moins de cellules à traiter,
           uniquement les modifiées de ces colonnes, ce qui serait somme toute bien plus rapide !

Message cité 1 fois
Message édité par Marc L le 22-03-2013 à 17:37:14
Reply

Marsh Posté le 22-03-2013 à 17:41:31    

Merci mais ça à l'air complexe.
 
J'ai inséré une MsgBox après le If qui dit que : "Excel risque de se figer quelques instants". Je pense que ça devrait aller.
 
Normalement la Macro ne fonctionnera qu'une fois au moment ou la personne collera sa base de donnée dans la feuille. Après la base ne sera plus modifié donc ça devrait aller. Je pense aussi que c'est long car ma base contient 72000 lignes.
 
Merci pour votre aide
 
 

Reply

Marsh Posté le 22-03-2013 à 17:58:23    

 
           Si l'alimentation s'effectue par un copier / coller, rien à faire de plus …
 
           Par contre si c'est par l'importation d'un fichier externe, il y aurait certainement à faire.
 
           Récemment j'ai réduit le temps de chargement d'un "dictionnaire" externe (> 1 Mo) de + de 72 000 lignes de 48 secondes à l'origine
           à 18 secondes dans un premier temps rien qu'en retirant une barre de progression
           puis enfin en optimisant à moins de 3 secondes tout en effectuant des contrôles !
 
           Et ce pour le premier appel car, une fois en mémoire, les appels suivants c'est de l'instantané  (< 1 centième)
           alors qu'à l'origine c'était 48 secondes à chaque appel …  :pt1cable:  
 

Reply

Marsh Posté le 22-03-2013 à 18:04:58    

Oui c'est du copier coller.
Par contre dernière question comment se fait il que lorsque je clique sur n'importe qu'elle cellule de ma feuille la macro se lance.
 
Voici mon code définitif :
 
Private Sub Worksheet_Change(ByVal Target As Excel.Range)
 
If [A1] = "Année" Then
MsgBox "Vous venez de coller l'extraction" & vbCr & "Après avoir cliqué sur OK la base va se mettre en forme" & vbLf & "Excel peut se figer quelques instants, Veuillez patienter", vbInformation, "Mise ne forme de la base"
Application.EnableEvents = False
Columns("V:BO" ).Replace ",", ".", xlPart, xlByRows, False, , False, False
MsgBox "Opération réalisée avec succès", vbInformation, "Mise en forme de la base"
Application.EnableEvents = True
[A1].Select
 
Else
MsgBox "Veuillez coller l'extraction en A1", vbExclamation, "Attention"
End If
End Sub
 

Reply

Marsh Posté le 22-03-2013 à 21:25:41    

 
           A quoi cela sert que Ducros il se décarcasse ?‼
 
           Dans mon avant dernier message de 17h30, j'ai pourtant bien indiqué qu'en désactivant le rafraichissement de l'écran
           (dans le code  Screenupdating = False)  le traitement en est accéléré (moins ralenti en fait) !
           Pourquoi ne pas l'intégrer alors ?‼             Et comparer les temps d'exécution avec et sans …
 
           Sinon en regardant l'aide de ma version concernant l'évènement  Change  d'une feuille,
           il est déclenché uniquement par la modification d'une cellule, pas par la sélection d'une nouvelle cellule;
           à vérifier dans la vôtre.  Sinon vérifier le code dans chacun des modules de classes, notamment celui du classeur …
 
           Cela serait bien aussi de ne déclencher le Replace seulement si la modification concerne les colonnes en question …
 

Reply

Marsh Posté le 22-03-2013 à 21:25:41   

Reply

Marsh Posté le 25-03-2013 à 09:17:26    

Bonjour Marc,
 
J'avais testé en désactivant le rafraichissement de l'écran mais je n'ai pas vu de différence nette.
 
Pour ce qui est des cellules ce n'est pas lorsque je je les sélectionne mais lorsque je rentre à l'intérieur que la macro se relance. (Je m'étais mal exprimé)
 
Comment déclencher le replace uniquement si il y a une modification dans les colonnes ?
 
Merci pour votre aide.

Message cité 1 fois
Message édité par benoug le 25-03-2013 à 09:17:37
Reply

Marsh Posté le 25-03-2013 à 12:08:17    

 
            Bonjour,      ce n'est pas l'action d'entrer dans une cellule qui déclenche la macro,
                              mais bien, comme précisé dans mon message précédent, le fait de la modifier …
 
            Valider en saisie de cellule correspond à une modification et quand c'est la touche Echap qui est pressée, rien ne se passe, CQFD …

benoug a écrit :

Comment déclencher le replace uniquement si il y a une modification dans les colonnes ?

            Réponse datant de trois jours :

Marc L a écrit :

    […]  dans cet événement de feuille la variable  Target  renvoie uniquement les cellules modifiées …
           En la croisant avec ces colonnes via la méthode  Intersect  il y aurait moins de cellules à traiter,
           uniquement les modifiées de ces colonnes, ce qui serait somme toute bien plus rapide !

            Donc en consultant l'aide d'Intersect et son exemple …
 

Reply

Marsh Posté le 25-03-2013 à 13:34:32    

J'ai testé le code ci-dessous mais sans succès.
 
Private Sub Worksheet_Change(ByVal Intersect ("V:BO" ) As Excel.Range)
 
Je ne comprend pas bien si je dois changer dans le corps du code de ma macro ou bien cette première ligne.

Reply

Marsh Posté le 25-03-2013 à 14:14:01    

 
           Déjà comme indiqué dans l'aide de la méthode Intersect, au moins deux plages sont nécessaires, je n'en vois qu'une ‼
 
           Et non, surtout ne pas modifier la première ligne ‼
           Car, encore une fois,  la variable  Target  renvoie uniquement les cellules modifiées …
 
           Il s'agit donc de comparer dans le corps  Target  et les colonnes  afin d'appliquer à leur intersection le Replace.
 

Reply

Marsh Posté le 25-03-2013 à 15:35:42    

Pouvez-vous être plus explicite ou me donner une exemple SVP.
Je vous avoue avoir du mal.
Je vous remercie

Reply

Marsh Posté le 25-03-2013 à 16:42:58    

 
           Difficile d'être plus explicite que l'exemple de l'aide d'Intersect !

     Set isect = Application.Intersect(zone1, zone2)

           Les zones doivent être remplacées par ce que l'on veut "croiser", en l'ocurrence les cellules modifiées et les colonnes …
 

Reply

Marsh Posté le 25-03-2013 à 17:59:24    

Merci mais je débute et je n'y arrive vraiment pas. De plus dans l'aide excel je n'ai pas ce que vous m'avez donné.
J'ai essayé le code ci-dessous mais sans succès. Je ne comprends pas trop la logique.
 
Set Insect = Application.Intersect(Target.Cells, Range ("V1:BO80000" ))
If Insect Is Nothing Then
Suite de mon code
 
Je vais devoir arrêter car je n'ai plus trop de temps pour travailler dessus.
Je vous remercie pour votre aide en tout cas.


Message édité par benoug le 25-03-2013 à 18:00:15
Reply

Marsh Posté le 25-03-2013 à 19:07:43    

 
           Bien, il y a du progrès !     Dommage de ne pas avoir laissé l'objet pointant sur les colonnes mais l'esprit est là.

Code :
  1. Private Sub Worksheet_Change(ByVal Target As Excel.Range)
  2.     Set Ri = Application.Intersect(Target, Columns("V:BO" ))
  3.  
  4.     If Not Ri Is Nothing Then
  5.         If Not Ri.Find(",", , xlValues, xlPart) Is Nothing Then
  6.             Application.EnableEvents = False:  Application.ScreenUpdating = False
  7.             Ri.Replace ",", ".", xlPart, xlByRows, False, , False, False
  8.             Application.EnableEvents = True:   Application.ScreenUpdating = True
  9.         End If
  10.     End If
  11. End Sub

           La ligne n°5 vérifie dans la plage d'intersection la présence d'une virgule à remplacer …


Message édité par Marc L le 25-03-2013 à 19:36:22
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed