Demande d'aide concernant la fonction Replace

Fermé
Signaler
-
 Alex -
Bonjour à tous,
Les quelques connaissances que je possède en VBA ne me permettent pas de résoudre mon problème ; je fais donc appel à vous dans l'espoir que vous réussirez à m'aider à désembrouiller le schmilblick ^^

Tout d'abord, ce que je souhaite faire : une macro qui "lit" une cellule et qui en "analyse" le contenu. Pour chaque caractère non-alphabétique (hormis certains caractères particuliers à savoir ¤%' et l'espace), je veux qu'elle m'ajoute devant ledit caractère le signe %.

Pour ce faire, voici la macro que j'ai écrite :

Sub Remplace()
Selection = UCase(Selection)
Selection = Selection & "¤"
Selection = Replace(Selection, "À", "A")
Selection = Replace(Selection, "Â", "A")
Selection = Replace(Selection, "Ä", "A")
Selection = Replace(Selection, "É", "E")
Selection = Replace(Selection, "È", "E")
Selection = Replace(Selection, "Ê", "E")
Selection = Replace(Selection, "Ë", "E")
Selection = Replace(Selection, "Î", "I")
Selection = Replace(Selection, "Ï", "I")
Selection = Replace(Selection, "Ô", "O")
Selection = Replace(Selection, "Ö", "O")
Selection = Replace(Selection, "Ù", "U")
Selection = Replace(Selection, "Ü", "U")
Selection = Replace(Selection, "Û", "U")
Selection = Replace(Selection, "Ç", "C")
Selection = Replace(Selection, "Ñ", "N")
Selection = Replace(Selection, "OE", "OE")
I = 1
Do Until char = "¤"
    char = Mid(Selection, I, 1)
    If char Like "[!A-Z,!%,! ,!¤]" Then
    Selection = Replace(Selection, char, "%" & char, , 1)
    I = I + 1
    End If
    I = I + 1
Loop
Selection = Replace(Selection, "¤", "")
End Sub


Le soucis arrive lors des tests (forcément, c'est à ça qu'ils servent ^^)
Quand je la teste avec, par exemple, az12er34ty15, elle me renvoie AZ%%1%2ER%3%4TY1%5 au lieu de AZ%1%2ER%3%4TY%1%5
En résumé, les deux signes % se retrouvent devant un seul 1 au lieu de se répartir (et plus j'ajoute de 1, plus les % se cumulent au niveau de la première instance)
En exécutant la macro pas à pas, je vois que le problème vient de l'instruction Replace mais je ne sais pas comment le résoudre.

Merci de l'aide que vous m'apporterez
Amicalement

Alex

8 réponses


Bonjour

Personnellement, au lieu de faire de 'Replace', j'aurais reconstruit la chaîne en recopiant les caractères tels quels ou modifiés selon les cas.
Mais pour rester dans ta logique, ton problème vient du fait que le Replace se fait toujours sur le premier caractère rencontré. Pourtant, il y a bien le 4e paramètre de Replace qui sert à dire à partir d'où doit se faire la recherche : tu ne t'en sers pas.
Si tu fais :
Selection = Replace(Selection, char, "%" & char, I , 1)

ça ne va faire de replace qu'à partir du Ième caractère et non pas à partir du premier
Messages postés
10185
Date d'inscription
lundi 18 octobre 2010
Statut
Membre
Dernière intervention
27 novembre 2021
2 251
Bonjour

essaies ceci (une fonction sera plus souple à utiliser)

Public Function RP(S As String) As String
Dim I As Long, c As String, ls As Long, SS As String
S = UCase(S)
S = Replace(S, "À", "A")
S = Replace(S, "Â", "A")
S = Replace(S, "Ä", "A")
S = Replace(S, "É", "E")
S = Replace(S, "È", "E")
S = Replace(S, "Ê", "E")
S = Replace(S, "Ë", "E")
S = Replace(S, "Î", "I")
S = Replace(S, "Ï", "I")
S = Replace(S, "Ô", "O")
S = Replace(S, "Ö", "O")
S = Replace(S, "Ù", "U")
S = Replace(S, "Ü", "U")
S = Replace(S, "Û", "U")
S = Replace(S, "Ç", "C")
S = Replace(S, "Ñ", "N")
S = Replace(S, "OE", "OE")
SS = ""
ls = Len(S)
For I = 1 To ls
c = Mid(S, I, 1)
If c Like "[!A-Z,!%,! ,!¤]" Then
SS = SS & "%"
End If
SS = SS & c
Next I
RP = SS
End Function

Cdlmnt
Merci à vous deux pour vos réponses aussi rapides !

-> le père : je ne vois pas bien ce que tu entends par "reconstruire les chaînes telles quelles"
Concernant le 4ème paramètre, j'ai essayé de m'en servir
Résultat : %34TY15
Je ne sais pas où est parti le reste de ma chaîne de test ...

-> CCM81 : je vais essayer ta méthode
En revanche, la boucle for n'est pas une bonne idée : comme je rajoute un caractère en milieu de chaîne, celle-ci est rallongée et la boucle garde en valeur de fin la longueur initiale
D'où la boucle Do-Loop
(J'ai tt de même essayé cette méthode mais pas moyen de faire prendre en compte la valeur réactualisée de Len à mon for :-S)

Encore merci pour le coup de main

Cordialement

Alex

Effectivement, l'utilisation de 4e paramètre n'est pas une bonne idée, j'aurais dû le vérifier avant de poster. L'aide de la fonction replace précise qu'elle remplace à partir d'un certain caractère, mais elle oublie de dire que cette fonction supprime tout ce qu'il y a avant !

Quand je parlais de reconstruire la chaîne, je voulais parler de la méthode de ccm81. Et la boucle for est une bonne idée contrairement à ce que tu dis : la chaîne S n'est pas modifiée pendant la boucle puisque on construit une nouvelle chaîne SS.
Ah la sale bête !
Elle supprime purement et simplement ce qui précède :-S
Je comprends mieux ; je craignais de mal me servir des différents arguments de cette fonction

Concernant ce qu'a proposé CCM81, effectivement, ça fonctionne (si tu me lis, désolé d'avoir douté ;-) )
Et j'étais à l'instant en train de me creuser la tête à essayer de comprendre pourquoi !
En effet, il yavait le For-To qui me tracassait (et tu viens de répondre à ma question) mais aussi le fait qu'il rajoute le % après ce qu'il a appelé SS alors que j'essayais de le rajouter avant le caractère "hors liste"

Dernière étape pour moi : qd mm faire une macro : au final, je ne serai pas le seul utilisateur de cette commande et cliquer sur un bouton et plus facile que devoir appeler une fonction (même si c'est pas bien compliqué ^^)
Messages postés
10185
Date d'inscription
lundi 18 octobre 2010
Statut
Membre
Dernière intervention
27 novembre 2021
2 251
Il te suffit d'appeler la fonction dans la procédure Click du bouton!
Et d'ailleurs au passage, j'aurai bien déporté tes S =r eplace... dans une fonction chargée de nettoyer la chaine, fonction (S=Nettoie(S)) elle même utilisée par RP dont le code deviendrait plus simple!
Cdlmnt
Messages postés
10185
Date d'inscription
lundi 18 octobre 2010
Statut
Membre
Dernière intervention
27 novembre 2021
2 251
En revanche, la boucle for n'est pas une bonne idée : comme je rajoute un caractère en milieu de chaîne, celle-ci est rallongée et la boucle garde en valeur de fin la longueur initiale
Non, la boucle for sur le nombre de caractères de la chaine initiale S créee une "copie allongée" SS dont la valeur finale est renvoyée par la fonction
https://www.cjoint.com/?3Hwtoohwmha

Cdlmnt
Mea Culpa CCM81 : en effet, tout tourne correctement
Je vais voir ca ensuite pour "ranger" mon code ; pour l'instant, je préfère tout avoir à portée d'oeil et de souris

Merci d'avoir pris la peine de me concocter un p'tit xls en démo :-)

Un grand merci à tous les deux pour vos réponses excessivement rapides et utiles !

Cordialement

Alex
Messages postés
10185
Date d'inscription
lundi 18 octobre 2010
Statut
Membre
Dernière intervention
27 novembre 2021
2 251
Absolution accordée :-)

Voilà ce que ça peut donner avec un bouton
https://www.cjoint.com/?3HwtAHGRVKe

Cdlmnt
C'est clair, je te dois un pack ;-)
En espérant ne pas abuser de ton temps, j'aimerais savoir s'il te serait possible de me redonner ces lignes de codes mais en version macro au lieu de la version fonction
En effet, je n'arrive pas a les transformer moi même ni à les intégrer dans les lignes que j'ai déjà écrites
D'avance, merci

Cordialement

Alex
Messages postés
10185
Date d'inscription
lundi 18 octobre 2010
Statut
Membre
Dernière intervention
27 novembre 2021
2 251
Dommage, mais voilà (la procédure s'applique à la cellule sélectionnée)
Si la sélection contient plus d'une cellule, ça ne fait rien
On peut bien sur modifier le code pour que la procédure s'applique à une plage

Public Sub Remplace()
Dim I As Long, c As String, ls As Long, S As String, SS As String
If Selection.Cells.Count > 1 Then Exit Sub
S = UCase(Selection)
S = Replace(S, "À", "A")
S = Replace(S, "Â", "A")
S = Replace(S, "Ä", "A")
S = Replace(S, "É", "E")
S = Replace(S, "È", "E")
S = Replace(S, "Ê", "E")
S = Replace(S, "Ë", "E")
S = Replace(S, "Î", "I")
S = Replace(S, "Ï", "I")
S = Replace(S, "Ô", "O")
S = Replace(S, "Ö", "O")
S = Replace(S, "Ù", "U")
S = Replace(S, "Ü", "U")
S = Replace(S, "Û", "U")
S = Replace(S, "Ç", "C")
S = Replace(S, "Ñ", "N")
S = Replace(S, "OE", "OE")
SS = ""
ls = Len(S)
For I = 1 To ls
c = Mid(S, I, 1)
If c Like "[!A-Z,!%,! ,!¤]" Then
SS = SS & "%"
End If
SS = SS & c
Next I
Selection.Value = SS
End Sub

Cdlmnt
Arrgh ! Je n'avais qu'une erreur : le
Selection.Value = SS
; le reste était bon ... bah, c'est de ses erreurs qu'on apprend !
Encore un grand merci pour le temps consacré !

Cordialement

Alex