Macro rechercher remplacer [Résolu] - VB/VBA/VBS - Programmation
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. |
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 …
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
Marsh Posté le 22-03-2013 à 16:22:28
Code :
|
Aide primaire : curseur sur une instruction puis touche F1 …
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.
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 :
|
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 !
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
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 …
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
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 …
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.
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 … |
Donc en consultant l'aide d'Intersect et son exemple …
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.
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.
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
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 …
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.
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 :
|
La ligne n°5 vérifie dans la plage d'intersection la présence d'une virgule à remplacer …
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 édité par benoug le 22-03-2013 à 17:41:55