Demande d'aide concernant la fonction Replace

Alex -  
 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

  1. Utilisateur anonyme
     
    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
  2. ccm81 Messages postés 11033 Statut Membre 2 434
     
    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
  3. Alex
     
    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
  4. Utilisateur anonyme
     
    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
    1. Alex
       
      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
    2. ccm81 Messages postés 11033 Statut Membre 2 434
       
      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
  5. Vous n’avez pas trouvé la réponse que vous recherchez ?

    Posez votre question
  6. ccm81 Messages postés 11033 Statut Membre 2 434
     
    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
  7. Alex
     
    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
  8. ccm81 Messages postés 11033 Statut Membre 2 434
     
    Absolution accordée :-)

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

    Cdlmnt
    0
    1. Alex
       
      C'est clair, je te dois un pack ;-)
      0
    2. Alex
       
      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
  9. ccm81 Messages postés 11033 Statut Membre 2 434
     
    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
    1. Alex
       
      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