XL 2016 VBA - Impossible: c <> Chr(Asc(c)) ! Unicode Character 'NARROW NO-BREAK SPACE'

Dudu2

XLDnaute Barbatruc
Bonjour,

D'une feuille récupérée de Google Sheets ou les nombres sont en String, j'essaie de les transformer en nombres.
Le blanc insécable Chr(160) est bien présent et pourtant je n'arrive pas à l'identifier dans un Instr().
De plus pour ce caractère c <> Chr(Asc(c)).

C'est le b.a. ba du VBA et je n'y comprends rien !
Une idée ? Merci.
 

Pièces jointes

  • FromGoogleSheets.xlsm
    24.2 KB · Affichages: 7

Dudu2

XLDnaute Barbatruc
Le AscW() donne 8239 ! Soit U+202F
Ça veut dire que ce caractère est en Unicode ? Dans Excel ? C'est possible ?

Comment le convertir ? StrConv(Mid(v, 2, 1), vbFromUnicode) donne un longueur nulle !
 
Dernière édition:

Staple1600

XLDnaute Barbatruc
Bonjour Dudu2

Apparemment, ce n'est pas un Chr(160)
car cette formule : =CHERCHE(CAR(160);C5) donne #VALEUR!

Alors que ce test fonctionne
VB:
Sub test()
Range("A1").FormulaR1C1 = "=""Staple""&CHAR(160)&1600"
Range("A1") = Range("A1").Value
Range("B1").FormulaR1C1 = "=SEARCH(CHAR(160),RC[-1])" 'renvoie 7
End Sub
 

Dranreb

XLDnaute Barbatruc
Bonjour.
Oui, c'est possible :

1647079498412.png
 

Dudu2

XLDnaute Barbatruc
C'est un autre caractère. Pas seulement, c'est un autre jeu de caractères.
Et dans le code, on travaille avec de l'ASCII. Si je teste >= "0" And <= "9" je vais pas aussi le coder pour des valeurs UNICODE.

Il existe bien des fonctions de conversions (ex: https://blog.brettski.com/2009/12/04/vba-convert-unicode-to-ascii/) mais pour le séparateur insécable - [narrow] no-break space - (ASCII x'A0', Unicode x'202F') ça ne fonctionne pas (résultat = "&").

Quant au StrConv(Mid(ActiveCell.Value, 2, 1), vbFromUnicode) ça ne donne rien pour le "NNBSP".

Donc je vais faire du pas propre en faisant une correspondance hard-codée pour le "NNBSP".
 

yal

XLDnaute Occasionnel
Bonjour
J'ai réussi à faire la conversion mais j'espère qu'il n'y a pas 100000 valeurs à convertir.

VB:
Sub Transforme()
  Dim x, y
  Dim i!, j!
    x = Range("C5:C8")
    For i = 1 To UBound(x)
      For j = 1 To Len(x(i, 1))
        If (Asc(Mid(x(i, 1), j, 1)) >= 48 And Asc(Mid(x(i, 1), j, 1)) <= 57) Or Asc(Mid(x(i, 1), j, 1)) = 44 Then
          y = y & Mid(x(i, 1), j, 1)
        End If
      Next j
      x(i, 1) = CDbl(y)
      y = ""
    Next i
    Range("C10:C13") = x
 
End Sub
 

Dudu2

XLDnaute Barbatruc
Bonjour @Marcel32, @yal,

Merci pour vos contributions.
Je peux effectivement faire une exception pour le "NNBSP" 8239.

Ce que j'aurais préféré c'est:
Si c'est un caractère sur 2 octets (Asc() <> AscW()) je prends arbitrairement l'hypothèse que c'est un caractère UNICODE et je le convertis en ASCII avant d'appliquer le traitement.

Hélas je ne peux pas faire ça car rien que pour le NNBSP, je ne trouve aucune fonction de conversion qui marche. Donc je vais le faire à la hache: convertir le NNBSP 8239 en 160 (Application.ThousandsSeparator) et supposer que tout le reste est en ASCII.
 

Dranreb

XLDnaute Barbatruc
Ben il vaudrait mieux me semble-t-il utiliser AscW pour éviter de récupérer, avec Asc, une partie seulement d'un unicode qui pourrait très bien aussi être comprise entre 48 et 57 ou valoir 44 !
Je le répète Asc et AscW donne la même chose pour un caractère codé sur un octet.
 

Statistiques des forums

Discussions
312 506
Messages
2 089 111
Membres
104 037
dernier inscrit
damsau