web-dev-qa-db-fra.com

Enregistrer le fichier texte UTF-8 codé avec VBA

comment puis-je écrire des chaînes encodées en UTF-8 dans un fichier texte de vba, comme

Dim fnum As Integer
fnum = FreeFile
Open "myfile.txt" For Output As fnum
Print #fnum, "special characters: äöüß" 'latin-1 or something by default
Close fnum

Existe-t-il des paramètres au niveau de l'application?

44
Karsten W.

J'ai trouvé la réponse sur le web :

Dim fsT As Object
Set fsT = CreateObject("ADODB.Stream")
fsT.Type = 2 'Specify stream type - we want To save text/string data.
fsT.Charset = "utf-8" 'Specify charset For the source text data.
fsT.Open 'Open the stream And write binary data To the object
fsT.WriteText "special characters: äöüß"
fsT.SaveToFile sFileName, 2 'Save binary data To disk

Certainement pas comme je m'y attendais ...

70
Karsten W.

Vous pouvez utiliser la méthode CreateTextFile ou OpenTextFile, les deux ayant un attribut "unicode" utile pour les paramètres de codage.

object.CreateTextFile(filename[, overwrite[, unicode]])        
object.OpenTextFile(filename[, iomode[, create[, format]]])

Exemple: Ecraser:

CreateTextFile:
 fileName = "filename"
 Set fso = CreateObject("Scripting.FileSystemObject")
 Set out = fso.CreateTextFile(fileName, True, True)
 out.WriteLine ("Hello world!")
 ...
 out.close

Exemple: Ajouter:

 OpenTextFile Set fso = CreateObject("Scripting.FileSystemObject")
 Set out = fso.OpenTextFile("filename", ForAppending, True, 1)
 out.Write "Hello world!"
 ...
 out.Close

Voir plus sur documents MSDN

16
Máťa - Stitod.cz

Ceci écrit une marque d'ordre d'octet au début du fichier, ce qui est inutile dans un fichier UTF-8 et certaines applications (dans mon cas, SAP) ne l'aiment pas. Solution ici: Puis-je exporter des données Excel avec UTF-8 sans nomenclature?

7
PhilHibbs

Voici une autre façon de procéder: en utilisant la fonction API WideCharToMultiByte:

Option Explicit

Private Declare Function WideCharToMultiByte Lib "kernel32.dll" ( _
  ByVal CodePage As Long, _
  ByVal dwFlags As Long, _
  ByVal lpWideCharStr As Long, _
  ByVal cchWideChar As Long, _
  ByVal lpMultiByteStr As Long, _
  ByVal cbMultiByte As Long, _
  ByVal lpDefaultChar As Long, _
  ByVal lpUsedDefaultChar As Long) As Long

Private Sub getUtf8(ByRef s As String, ByRef b() As Byte)
Const CP_UTF8 As Long = 65001
Dim len_s As Long
Dim ptr_s As Long
Dim size As Long
  Erase b
  len_s = Len(s)
  If len_s = 0 Then _
    Err.Raise 30030, , "Len(WideChars) = 0"
  ptr_s = StrPtr(s)
  size = WideCharToMultiByte(CP_UTF8, 0, ptr_s, len_s, 0, 0, 0, 0)
  If size = 0 Then _
    Err.Raise 30030, , "WideCharToMultiByte() = 0"
  ReDim b(0 To size - 1)
  If WideCharToMultiByte(CP_UTF8, 0, ptr_s, len_s, VarPtr(b(0)), size, 0, 0) = 0 Then _
    Err.Raise 30030, , "WideCharToMultiByte(" & Format$(size) & ") = 0"
End Sub

Public Sub writeUtf()
Dim file As Integer
Dim s As String
Dim b() As Byte
  s = "äöüßµ@€|~{}[]²³\ .." & _
    " OMEGA" & ChrW$(937) & ", SIGMA" & ChrW$(931) & _
    ", alpha" & ChrW$(945) & ", beta" & ChrW$(946) & ", pi" & ChrW$(960) & vbCrLf
  file = FreeFile
  Open "C:\Temp\TestUtf8.txt" For Binary Access Write Lock Read Write As #file
  getUtf8 s, b
  Put #file, , b
  Close #file
End Sub
6
Falo

J'ai examiné la réponse de Máťa, dont le nom évoque des qualifications et de l'expérience en codage. Le documentation VBA dire CreateTextFile(filename, [overwrite [, unicode]]) crée un fichier "en tant que fichier Unicode ou ASCII. La valeur est True si le fichier est créé en tant que Unicode False s'il est créé sous la forme d'un fichier ASCII. S'il est omis, un fichier ASCII est supposé. ") quel encodage? Unicode non codé ne peut pas être représenté dans un fichier.

La page de documentation VBA pour OpenTextFile(filename[, iomode[, create[, format]]]) offre une troisième option pour le format:

  • TriStateDefault 2 "ouvre le fichier en utilisant la valeur par défaut du système."
  • TriStateTrue 1 "ouvre le fichier en tant que Unicode."
  • TriStateFalse 0 "ouvre le fichier en tant qu'ASCII."

Máťa passe -1 pour cet argument.

A en juger par documentation VB.NET (pas VBA mais je pense, reflète les réalités de la façon dont le système d'exploitation Windows sous-jacent représente les chaînes unicode et se répercute dans MS Office, je ne sais pas), la valeur par défaut du système est un codage utilisant 1 caractère octet/unicode utilisant une page de code ANSI pour les paramètres régionaux. UnicodeEncoding est UTF-16. La documentation décrit également UTF-8 est également un "encodage Unicode", ce qui me semble logique. Mais je ne sais pas encore comment spécifier UTF-8 pour une sortie VBA, ni être sûr que les données que j'écris sur le disque avec OpenTextFile (, 1) sont codées en UTF-16. Le post de Tamalek est utile.

2
Bennett Brown