Save text file UTF-8 encoded with VBA
我如何从VBA将UTF-8编码的字符串写入文本文件,例如
1 2 3 4 5 | 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 |
在应用程序级别上是否有设置?
我在网上找到了答案:
1 2 3 4 5 6 7 | 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 |
当然不是我所期望的...
您可以使用CreateTextFile或OpenTextFile方法,它们都具有" unicode"属性,可用于编码设置。
1 2 | object.CreateTextFile(filename[, overwrite[, unicode]]) object.OpenTextFile(filename[, iomode[, create[, format]]]) |
示例:覆盖:
1 2 3 4 5 6 7 | CreateTextFile: fileName ="filename" Set fso = CreateObject("Scripting.FileSystemObject") Set out = fso.CreateTextFile(fileName, True, True) out.WriteLine ("Hello world!") ... out.close |
示例:追加:
1 2 3 4 5 | OpenTextFile Set fso = CreateObject("Scripting.FileSystemObject") Set out = fso.OpenTextFile("filename", ForAppending, True, 1) out.Write"Hello world!" ... out.Close |
在MSDN文档上查看更多信息
这会在文件的开头写入字节顺序标记,这在UTF-8文件中是不必要的,并且某些应用程序(在我的情况下为SAP)不喜欢它。
这里的解决方案:我可以使用没有BOM的UTF-8导出Excel数据吗?
这是执行此操作的另一种方法-使用API??函数WideCharToMultiByte:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | 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 ="??ü?μ@€|~{}[]23\\ .." & _ " 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 |
我调查了Má?a的答案,他的名字暗示了编码资格和经验。 VBA文档说
- TriStateDefault 2"使用系统默认值打开文件。"
- TriStateTrue 1"以Unicode打开文件"。
- TriStateFalse 0"以ASCII文件形式打开文件。"
玛阿(Máa)为此参数传递了-1。
从VB.NET文档(不是VBA)来看,但我认为反映了有关底层Windows OS如何表示unicode字符串并回显到MS Office的现实,我不知道)系统默认值是使用ANSI的1字节/ unicode字符的编码语言环境的代码页。
将字符串转换为UTF-8字符串的传统方法如下:
1 | StrConv("hello world",vbFromUnicode) |
所以简单地说:
1 2 3 4 5 | Dim fnum As Integer fnum = FreeFile Open"myfile.txt" For Output As fnum Print #fnum, StrConv("special characters: ??ü?", vbFromUnicode) Close fnum |
不需要特殊的COM对象