Demande d'aide concernant la fonction Replace

Fermé
Alex - Modifié par Chris 94 le 22/08/2014 à 16:17
 Alex - 24 août 2014 à 12:27
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

Utilisateur anonyme
22 août 2014 à 16:30
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
0
ccm81 Messages postés 10903 Date d'inscription lundi 18 octobre 2010 Statut Membre Dernière intervention 19 novembre 2024 2 426
Modifié par ccm81 le 22/08/2014 à 16:50
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
0
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
0
Utilisateur anonyme
22 août 2014 à 18:55
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.
0
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é ^^)
0
ccm81 Messages postés 10903 Date d'inscription lundi 18 octobre 2010 Statut Membre Dernière intervention 19 novembre 2024 2 426
Modifié par ccm81 le 22/08/2014 à 19:20
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
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
ccm81 Messages postés 10903 Date d'inscription lundi 18 octobre 2010 Statut Membre Dernière intervention 19 novembre 2024 2 426
22 août 2014 à 19:15
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
0
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
0
ccm81 Messages postés 10903 Date d'inscription lundi 18 octobre 2010 Statut Membre Dernière intervention 19 novembre 2024 2 426
22 août 2014 à 19:27
Absolution accordée :-)

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

Cdlmnt
0
C'est clair, je te dois un pack ;-)
0
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
0
ccm81 Messages postés 10903 Date d'inscription lundi 18 octobre 2010 Statut Membre Dernière intervention 19 novembre 2024 2 426
Modifié par ccm81 le 23/08/2014 à 16:48
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
0
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
0