La technique recommandée pour la lecture des fichiers UTF-8 est:Lire UTF-8 fichier codé qui comprend encodages 4 octets dans Excel
Dim FileStream As Stream
Dim FileBodyADO As String
Set FileStream = CreateObject("ADODB.Stream")
With FileStream
.Charset = "utf-8"
.Open
.LoadFromFile ("C:\DataArea\Resources\VBA Outlook\Tutorial\examples.json")
FileBodyADO = .ReadText()
.Close
End With
Set FileStream = Nothing
Toutefois, si vous essayez de lire « examples.json » qui fait partie de la documentation SO archivée, l'instruction FileBodyADO = .ReadText()
ne se termine jamais.
Un fichier UTF-8 est un octet fichier orienté (contrairement, par exemple, UTF-16) avec des caractères dont les codes sont dans la gamme de 0 à & H7F effectuée inchangé et des caractères avec des codes ci-dessus & H7F codés à plusieurs octets séquences:
-Code (Hex)- ---------------Encoding---------------
Start End Byte 1 Byte 2 Byte 3 Byte 4
0 7F 0xxxxxxx
80 7FF 110xxxxx 10xxxxxx
800 FFFF 1110xxxx 10xxxxxx 10xxxxxx
10000 10FFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
« examples.json » contient:
92,601,220 1-byte encodings
8,848 2-byte encodings
20,122 3-byte encodings and
166 4-byte encodings.
Les codages de 1 octet sont des caractères ASCII. Les codages sur 2 octets sont, par exemple, § (HA7) et I (H131). Les codages à 3 octets sont, par exemple, √ (H221A) et 年 (H5E74). Les codages de 4 octets sont, par exemple, "Coeur étincelant" (H1F496) et "Visage souriant avec des yeux souriants" (H1F601).
Je ne trouve rien qui puisse suggérer que les produits Office puissent gérer des caractères avec des codes au-dessus de U + FFFF. Je soupçonne que ReadText
se termine par une boucle sans fin quand il frappe un encodage de 4 octets. J'ai mon propre programme VBA pour décoder un fichier UTF-8. Il a également échoué à traiter les encodages de 4 octets lorsqu'ils ont été rencontrés pour la première fois. Depuis, j'ai amélioré/corrigé ma routine pour accepter les encodages de 4 octets et les décoder comme des entités de caractères numériques. Par exemple, "Sourire avec des yeux souriants" (H1F601) est porté dans le fichier sous HF0 9F 98 81 que ma routine décode à 😁
. Si cette entité de caractères numériques est placée dans un fichier html, Microsoft Edge affiche l'emoji correct. Je comprends Google Chrome et la plupart (tous?) Les navigateurs modernes peuvent également gérer de telles entités de caractères numériques. Que pouvez-vous voir: & # x01F601 ;? Puisque le texte qui inclut ces caractères est html, ma solution est adéquate pour mes besoins actuels.
Je posterai ma routine sous forme de réponse dans quelques jours à moins qu'une meilleure réponse ne soit postée en premier. Est-ce que les gens sont d'accord que ReadText
ADODB est vaincu par des codages de 4 octets? Les produits Office, en particulier Excel, peuvent-ils gérer les caractères Unicode Plane 1 (H10000 à H1FFFF)? Existe-t-il une alternative à mon utilisation du caractère numérique?
Plus fond
J'ai accepté la réponse de Tom Blodget parce qu'il ne répond à ma question. Cependant, ce n'est pas la réponse que j'espérais.
Il y a quelques années, je recevais des fichiers dans différents formats incluant UTF-16, UTF-8, ASCII et ISO-8859-1. Les auteurs de ces fichiers extrayaient des données provenant de différentes applications mais j'ai trouvé la variété de formats inattendue; dans mon expérience, la plupart des applications utilisent UTF-8 ces jours-ci. Aucun de mes fournisseurs ne connaissait le format de leur application source ni comment changer le format de sortie en UTF-8 ou quelque chose de cohérent. "VBA traditionnel" lit ou écrit des fichiers ASCII ou Unicode (par lesquels Microsoft signifie OCS-2). Apparemment OCS-2 est "pratiquement identique" à UTF-16. Pour moi, "pratiquement identique" signifie différent mais je ne trouve rien pour expliquer comment ils diffèrent. ADODB est une bibliothèque VBA qui acceptera d'autres formats mais toute la documentation implique que vous deviez savoir ce qu'est ce format. Des utilitaires comme NotePad ++ ouvriront n'importe quel fichier texte et vous indiqueront son format. Je n'ai rien trouvé de similaire avec VBA.
J'ai décidé que je devais écrire mon propre code pour lire chaque fichier dans un tableau d'octets et identifier le format. Identifier le format n'était pas beaucoup moins de travail que l'identification et la conversion à une chaîne VBA, c'est ce que j'ai fait. Les fichiers n'étaient pas particulièrement volumineux, donc la lecture et la conversion prenaient moins de 0,01 seconde, ce qui était suffisant pour mes besoins.
Quand j'avais besoin de lire "examples.json", j'ai naturellement utilisé ma routine. Je sais maintenant que "examples.json" contient 166 encodages à 4 octets et que ma routine ne les gère pas correctement. J'ai corrigé les bugs dans ma routine et j'étais content du résultat, sauf qu'il a fallu 34 secondes avec la dernière version pour traiter le fichier 92Mb. J'ai essayé ADODB pour voir à quel point c'était plus rapide mais ça ne s'est jamais terminé. C'était jusqu'où j'avais été avant que je pose cette question. J'avais lu que ADODB n'était pas très efficace et que vous devriez lire un petit bloc à la fois. Cependant, je n'ai pas assimilé «inefficace» à «ne se termine pas» avant d'avoir essayé la réponse de Tom Blodget. En optimisant l'utilisation de ADODB comme suggéré, il a maintenant terminé. L'étude de la sortie a augmenté ma compréhension de l'encodage UTF-8, donc c'était un exercice utile. Cependant, à environ 40 secondes, ADODB était encore plus lent que ma routine VBA.
Sur mon ordinateur portable, le code suivant lit le fichier entier de 92 Mb dans un tableau d'octets en environ 0,1 secondes:
FileNum = FreeFile
Open PathFileName For Binary Access Read As FileNum
ReDim FileBodyByte(1 To LOF(FileNum))
Get FileNum, , FileBodyByte
Close FileNum
Une fois dans un tableau d'octets, la conversion à une chaîne est totalement liés au processeur. Pourquoi ADODB a-t-il besoin que le bloc soit lu dans des blocs de 128K? Que se passe-t-il si un bloc se termine au milieu d'un encodage? Pourquoi cela prend-il autant de temps? J'ai converti les routines VBA liées au processeur à VB.Net et j'ai réduit les durées d'un facteur de 1000. Je ne me sentirais pas à l'aise d'utiliser ADODB est une routine que j'ai libéré à un client.
Microsoft semble être obsédé par la compatibilité ascendante. Le code VBA que j'ai écrit il y a 15 ans fonctionne toujours. Microsoft n'améliore pas les vieilles routines; il introduit de nouvelles bibliothèques si de nouvelles fonctionnalités doivent être fournies. ADODB est vieux. J'espérais quelque chose de nouveau et de meilleur plutôt qu'une solution de rechange.
Non, ADODB.Stream poignées de caractères UTF-8 codé avec 4 unités de code très bien. Le problème semble être quelque chose d'autre, peut-être la taille du fichier. –