Corriger les problèmes d'utilisation de certains symboles ASCII

Boostez vos compétences Excel avec notre communauté !

Rejoignez Excel Downloads, le rendez-vous des passionnés où l'entraide fait la force. Apprenez, échangez, progressez – et tout ça gratuitement ! 👉 Inscrivez-vous maintenant !

Lu76Fer

XLDnaute Occasionnel
Bonjour,
Il est possible d'afficher les 255 caractères ASCII dans des cellules Excel sans aucune erreur, indépendamment de la police de caractère utilisée. Par contre, si on utilise certains symboles ASCII dans des formes (Dessin ou Contrôle de formulaire), il arrive que le symbole affiché dans la forme ne corresponde pas au symbole qu'on a affecté via la propriété 'Texte' de l'objet.​

J'avais déjà essayé de passer par un copié-collé pour reprendre le symbole à partir d'une cellule mais cela ne change rien, c'est l'encodage du symbole en mémoire qui est anormal. Il faut savoir que dans une variable de type 'String', les caractères sont stockées sous forme de caractère étendu sur 16 bits soit 2 octets (Byte).​

I - Illustration du problème
VB:
Sub ReadExtCar(c As String)
Dim yIn() As Byte
   yIn = c  'Charge le caractère c dans un tableau de 'Byte'
   Debug.Print "Low Byte=" & yIn(1)
   Debug.Print "High Byte=" & yIn(0)
End Sub

Sub AfficherCarEtendu()
Dim s As String
   s = Chr(135)
   ReadExtCar s
End Sub
Résultat de la macro 'AfficherCarEtendu' : Low Byte=32, High Byte=33
On voit ici que le symbole 135 est converti en symbole 33 du Charset 32 au lieu d'avoir le symbole 135 du Charset 0 !​
Pour pouvoir lister tous les symboles concernés par ce problème voici 2 fonctions utilisateurs permettant de simplifier la recherche de cette liste :
VB:
Function HBchr(c As String) As Byte
Dim yIn() As Byte
   yIn = c  'Charge s dans un tableau de 'Byte'
   HBchr = yIn(0)
End Function

Function LBchr(c As String) As Byte
Dim yIn() As Byte
   yIn = c  'Charge s dans un tableau de 'Byte'
   LBchr = yIn(1)
End Function
Liste des symboles posant problème :
Func_Chr_Anomalies.jpg

Question : qui aurait une explication de cette anomalie qui affecte ces 27 symboles ?

II - Solution proposée
La fonction Chr(n°) qui date des débuts du Basic permet d'affecter un symbole dans une chaîne à partir d'une seule table des caractères, la Zéro. Je ne pense pas qu'il existe une fonction qui permette d'affecter un caractère étendu à une chaîne, je propose donc de l'écrire ainsi :​
VB:
Function ExtChr(code As Byte, Optional charset As Byte = 0) As String
Dim yIn(1) As Byte
   yIn(0) = code: yIn(1) = charset
   ExtChr = yIn
End Function

'Voici la fonction qui permet d'établir une chaîne de caractère à partir d'un
'tableau de variant dans le Jeu de caractère 'charset'
Function ExtStr(codes As Variant, Optional charset As Byte = 0) As String
Dim yIn() As Byte, v As Variant, pos As Integer
   ReDim yIn(UBound(codes) * 2 + 1)
   For Each v In codes
      yIn(pos) = v: yIn(pos + 1) = charset
      pos = pos + 2
   Next v
   ExtStr = yIn
End Function

'Ex. d'utilisation de la fonction précédente pour une forme du menu Dessin 'MyShape'
Sub DisplayExtStr()
Dim shp As Shape, s as String
   Set shp = Me.Shapes("MyShape")
    s = ExtStr(Array(135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146))
   shp.TextFrame2.TextRange.Text = s
    Debug.Print s
End Sub
En utilisant la fonction ExtChr ou ExtStr, les 27 symboles s'affichent comme attendu sur la partie texte d'une forme ainsi que tous les autres symboles ASCII. J'ai noté cependant que ces symboles problèmatiques n'ont pas leur espace d'occupation adapté en largeur et hauteur.​

Enfin, il est aussi possible d'utiliser les symboles étendus des 255 autres tables de caractère à partir de fonction du même genre que celles écrites ci-dessus ...
 
Dernière édition:
Hello,

Question : qui aurait une explication de cette anomalie qui affecte ces 27 symboles ?
je n'ai pas la réponse, mais ce site montre bien qu'il y a qqchose sur ces 27 caractères
 
La table des codes ACSII est universelle et ne comporte que 128 codes allant de 0 à 127.

De 128 à 255 c'est de l'ASCII étendu et ça dépend de la plateforme comme le dit Microsoft.

Si tu utilises AscW() tu retrouves le code Unicode.

Dans ton exemple, la fonction AscW() retourne 8225, soit en hexadécimal $2021, et $20=32 et $21=33.

VB:
Sub AfficherCarEtendu()
Dim s As String
    s = Chr(135)
    ReadExtCar s
End Sub

Sub ReadExtCar(c As String)
Dim yIn() As Byte
    Debug.Print "Octet fort   : " & Int(AscW(c) / 256)
    Debug.Print "Octet faible : " & AscW(c) Mod 256
    yIn = c     ' Charge le caractère c dans un tableau de 'Byte'
    Debug.Print "Low Byte=" & yIn(1)
    Debug.Print "High Byte=" & yIn(0)
End Sub


ps : attention de ne pas confondre "octet" et "byte". Ici ça marche parce que Microsoft n'en est pas à une connerie près, mais en pour de vrai ce n'est pas la même chose. 😉
 
Dernière édition:
La table des codes ACSII est universelle et ne comporte que 128 codes allant de 0 à 127.

De 128 à 255 c'est de l'ASCII étendu et ça dépend de la plateforme comme le dit Microsoft.

Si tu utilises AscW() tu retrouves le code Unicode.

Dans ton exemple, la fonction AscW() retourne 8225, soit en hexadécimal $2021, et $20=32 et $21=33.

VB:
Sub AfficherCarEtendu()
Dim s As String
    s = Chr(135)
    ReadExtCar s
End Sub

Sub ReadExtCar(c As String)
Dim yIn() As Byte
    Debug.Print "Octet fort   : " & Int(AscW(c) / 256)
    Debug.Print "Octet faible : " & AscW(c) Mod 256
    yIn = c     ' Charge le caractère c dans un tableau de 'Byte'
    Debug.Print "Low Byte=" & yIn(1)
    Debug.Print "High Byte=" & yIn(0)
End Sub


ps : attention de ne pas confondre "octet" et "byte". Ici ça marche parce que Microsoft n'en est pas à une connerie près, mais en pour de vrai ce n'est pas la même chose. 😉
Bonne idée de passer par les codes Unicode, je n'avais jamais utilisé cette fonction je vais voir si je trouve mon bonheur parmi tous ces symboles ...
 
La table des codes ACSII est universelle et ne comporte que 128 codes allant de 0 à 127.

De 128 à 255 c'est de l'ASCII étendu et ça dépend de la plateforme comme le dit Microsoft.

Si tu utilises AscW() tu retrouves le code Unicode.

Dans ton exemple, la fonction AscW() retourne 8225, soit en hexadécimal $2021, et $20=32 et $21=33.

VB:
Sub AfficherCarEtendu()
Dim s As String
    s = Chr(135)
    ReadExtCar s
End Sub

Sub ReadExtCar(c As String)
Dim yIn() As Byte
    Debug.Print "Octet fort   : " & Int(AscW(c) / 256)
    Debug.Print "Octet faible : " & AscW(c) Mod 256
    yIn = c     ' Charge le caractère c dans un tableau de 'Byte'
    Debug.Print "Low Byte=" & yIn(1)
    Debug.Print "High Byte=" & yIn(0)
End Sub


ps : attention de ne pas confondre "octet" et "byte". Ici ça marche parce que Microsoft n'en est pas à une connerie près, mais en pour de vrai ce n'est pas la même chose. 😉

Oui, j'aurai dû chercher un peu car la fonction ChrW fonctionne parfaitement avec les formulaires et les formes !!

Merci TooFatBoy !
 
Une dernière chose est a noté tout de même, j'ai exactement le même problème de mauvaise occupation de l'espace avec les 27 symboles, en utilisant la fonction ChrW, la largeur et la hauteur attribuée n'est pas bonne et les symboles se chevauchent ...
 
Une dernière chose est a noté tout de même, j'ai exactement le même problème de mauvaise occupation de l'espace avec les 27 symboles, en utilisant la fonction ChrW, la largeur et la hauteur attribuée n'est pas bonne et les symboles se chevauchent ...
Sauf erreur de ma part ça n'a rien à voir avec le code du caractère, mais ça dépend de sa chasse ou d'un autre de leurs termes barbares...

Ceci dit, je n'ai pas vraiment compris quel problème il y a exactement.
Pour moi qui suis un peu simplet, un classeur avec un UserForm montrant le problème aurait été le bienvenu. 😉
 
Par curiosité, j'ai affiché les 27 caractères en anomalie à côté de tout les autres caractères; voyez le résultat :

Pb_Affichage_CarAno.jpg


Voyez le chevauchement en largeur sur la 1ère image !
J'ai utilisé des formes Round Square dans le menu dessin "RA_ANO" et "RA_NORM" ainsi qu'une zone range "AnoCar" de la feuille S_ANO contenant la liste de tous les codes des caractères en anomalie et voici le code pour remplir les formes :
VB:
Sub DisplayAllSymbol()
Dim rgAno As Range, vAno As Variant, anos(255) As Boolean
Dim shpAno As TextRange2, shpNorm As TextRange2, cnt As Integer
' AnoCar
   Set rgAno = S_ANO.Range("AnoCar").Cells
   For Each vAno In rgAno
      anos(vAno) = True
   Next vAno
   Set shpAno = Me.Shapes("RA_ANO").TextFrame2.TextRange
   Set shpNorm = Me.Shapes("RA_NORM").TextFrame2.TextRange
   shpAno.Text = "": shpNorm.Text = ""
   For cnt = 33 To 255
      If anos(cnt) Then shpAno.Text = shpAno.Text & ChrW(cnt) _
         Else shpNorm.Text = shpNorm.Text & ChrW(cnt)
   Next cnt
End Sub
 
Sauf erreur de ma part ça n'a rien à voir avec le code du caractère, mais ça dépend de sa chasse ou d'un autre de leurs termes barbares...

Ceci dit, je n'ai pas vraiment compris quel problème il y a exactement.
Pour moi qui suis un peu simplet, un classeur avec un UserForm montrant le problème aurait été le bienvenu. 😉
J'ai anticipé ta remarque grâce à mon QI de 180 🤓😄
 
Ah oui en effet, il y a comme un soucy...
Mais hélas, moi je n'ai pas 180... plutôt 18, donc je ne saurais dire pourquoi ni y remédier.
Pas très grave mais ce serait bien de savoir si cette bizarrerie a été corrigé sur les versions récentes d'Excel, mais sinon ce n'est pas très grave ...
Perso je suis sous Excel v2016 (64 bits)
 
- Navigue sans publicité
- Accède à Cléa, notre assistante IA experte Excel... et pas que...
- Profite de fonctionnalités exclusives
Ton soutien permet à Excel Downloads de rester 100% gratuit et de continuer à rassembler les passionnés d'Excel.
Je deviens Supporter XLD

Discussions similaires

Réponses
1
Affichages
2 K
Retour