保存用VBA编码的文本文件UTF-8
我怎样才能把UTF-8编码的string写入vba的文本文件中呢
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
应用程序级别是否有一些设置?
我在网上find了答案:
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”有用的编码设置。
object.CreateTextFile(filename[, overwrite[, unicode]]) object.OpenTextFile(filename[, iomode[, create[, format]]])
例如:覆盖:
CreateTextFile: fileName = "filename" Set fso = CreateObject("Scripting.FileSystemObject") Set out = fso.CreateTextFile(fileName, True, True) out.WriteLine ("Hello world!") ... out.close
示例:追加:
OpenTextFile Set fso = CreateObject("Scripting.FileSystemObject") Set out = fso.OpenTextFile("filename", ForAppending, True, 1) out.Write "Hello world!" ... out.Close
在MSDN文档上查看更多信息
这在文件的开头写了一个字节顺序标记,这在UTF-8文件中是不必要的,一些应用程序(在我的情况下是SAP)不喜欢它。 这里的解决scheme: 我可以用UTF-8导出excel数据吗?
这是另一种方法 – 使用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
我研究了Máťa的答案,他的名字暗示了编码的资格和经验。 VBA文档说CreateTextFile(filename, [overwrite [, unicode]])
创build一个文件“作为一个Unicode或ASCII文件,如果该文件创build为一个Unicode文件,则为True;如果创build为ASCII文件,则为False。如果省略,则假定为ASCII文件。“ 一个文件存储unicode字符是好的,但在什么编码? 未编码的unicode不能在文件中表示。
OpenTextFile(filename[, iomode[, create[, format]]])
的VBA文档页面为OpenTextFile(filename[, iomode[, create[, format]]])
提供了第三个选项:
- TriStateDefault 2“使用系统默认值打开文件。”
- TriStateTrue 1“以Unicodeforms打开文件。”
- TriStateFalse 0“以ASCIIforms打开文件”。
Máťa为这个论点传递-1。
从VB.NET文档判断(不是VBA,但我认为反映了底层Windows操作系统是如何代表unicodestring和回声到微软Office的现实,我不知道)系统默认是一个编码使用1字节/ Unicode字符使用ANSI代码页的语言环境。 UnicodeEncoding
是UTF-16。 文档还描述了UTF-8也是一个“Unicode编码”,这对我来说是有意义的。 但是我还不知道如何为VBA输出指定UTF-8,也不知道我用OpenTextFile(,,, 1)写入磁盘的数据是UTF-16编码的。 Tamalek的post是有帮助的。