VBA : 保存一个没有BOM的UTF-8文件
VBA : save a file with UTF-8 without BOM
这可能很简单,这是我尝试过的:
Set objStream = CreateObject("ADODB.Stream")
Set objStreamNoBOM = CreateObject("ADODB.Stream")
With objStream
.Open
.Charset = "UTF-8"
.WriteText "aaaaaa"
.Position = 0
End With
With objStreamNoBOM
'.Charset = "Windows-1252" ' WORK
.Charset = "UTF-8" ' DOESN'T WORK!!
.Open
.Type = 2
.WriteText objStream.ReadText
.SaveToFile "toto.php", 2
.Close
End With
objStream.Close
如果字符集是UTF-8,则文件开头有ï»。
知道如何使用 UTF-8 和不带 BOM 保存文件吗?
在最好的情况下,相关列表将包含对 this question 的引用,我发现它是 "vbscript adodb.stream bom vbscript site:whosebug.com".
的第一个匹配项
基于boost's answer的第二个策略:
Option Explicit
Const adSaveCreateNotExist = 1
Const adSaveCreateOverWrite = 2
Const adTypeBinary = 1
Const adTypeText = 2
Dim objStreamUTF8 : Set objStreamUTF8 = CreateObject("ADODB.Stream")
Dim objStreamUTF8NoBOM : Set objStreamUTF8NoBOM = CreateObject("ADODB.Stream")
With objStreamUTF8
.Charset = "UTF-8"
.Open
.WriteText "aÄö"
.Position = 0
.SaveToFile "toto.php", adSaveCreateOverWrite
.Type = adTypeText
.Position = 3
End With
With objStreamUTF8NoBOM
.Type = adTypeBinary
.Open
objStreamUTF8.CopyTo objStreamUTF8NoBOM
.SaveToFile "toto-nobom.php", adSaveCreateOverWrite
End With
objStreamUTF8.Close
objStreamUTF8NoBOM.Close
证据:
chcp
Active code page: 65001
dir
...
15.07.2015 18:48 5 toto-nobom.php
15.07.2015 18:48 8 toto.php
type toto-nobom.php
aÄö
我知道脚本文件系统对象的流插入了一个字节顺序标记,但我还没有在 ADODB 流中看到它。
或者至少,现在还没有:我很少使用 ADODB 流对象...
但我确实记得几年前在一些代码中写过这句话:
' **** WHY THIS IS COMMENTED OUT **** **** **** **** **** **** **** ****
'
' Microsoft ODBC and OLEDB database drivers cannot read the field names from
' the header when a unicode byte order mark (&HFF & &HFE) is inserted at the
' start of the text by Scripting.FileSystemObject 'Write' methods. Trying to
' work around this by writing byte arrays will fail; FSO 'Write' detects the
' string encoding automatically, and won't let you hack around it by writing
' the header as UTF-8 (or 'Narrow' string) and appending the rest as unicode
'
' (Yes, I tried some revolting hacks to get around it: don't *ever* do that)
'
' **** **** **** **** **** **** **** **** **** **** **** **** **** **** ****
'
' With FSO.OpenTextFile(FilePath, ForWriting, True, TristateTrue)
' .Write Join(arrTemp1, EOROW)
' .Close
' End With ' textstream object from objFSO.OpenTextFile
'
' **** **** **** **** **** **** **** **** **** **** **** **** **** **** ****
你可以看出我今天过得很糟糕。
接下来,使用原始 C:
中出现文件处理之前的史前 PUT 命令
' **** WHY WE 'PUT' A BYTE ARRAY INSTEAD OF A VBA STRING VARIABLE **** ****
'
' Put #hndFile, , StrConv(Join(arrTemp1, EOROW), vbUnicode)
' Put #hndFile, , Join(arrTemp1, EOROW)
'
' If you pass unicode, Wide or UTF-16 string variables to PUT, it prepends a
' Unicode Byte Order Mark to the data which, when written to your file, will
' render the field names illegible to Microsoft's JET ODBC and ACE-OLEDB SQL
' drivers (which can actually read unicode field names, if the helpful label
' isn't in the way). However, the 'PUT' statements writes a Byte array as-is
'
' **** **** **** **** **** **** **** **** **** **** **** **** **** **** ****
所以有实际执行此操作的代码:
Dim arrByte() As Byte
Dim strText As String
Dim hndFile As String
strText = "Y'all knew that strings are actually byte arrays?"
arrByte = strText
hndFile = FreeFile
Open FilePath For Binary As #hndFile
Put #hndFile, , arrByte
Close #hndFile
Erase arrByte
我假设 strText 实际上是 UTF-8。我的意思是,我们在 VBA,在 Microsoft Office 中,我们 绝对 知道这始终是 UTF-8,即使我们在国外使用它...
...对吗?
这可能很简单,这是我尝试过的:
Set objStream = CreateObject("ADODB.Stream")
Set objStreamNoBOM = CreateObject("ADODB.Stream")
With objStream
.Open
.Charset = "UTF-8"
.WriteText "aaaaaa"
.Position = 0
End With
With objStreamNoBOM
'.Charset = "Windows-1252" ' WORK
.Charset = "UTF-8" ' DOESN'T WORK!!
.Open
.Type = 2
.WriteText objStream.ReadText
.SaveToFile "toto.php", 2
.Close
End With
objStream.Close
如果字符集是UTF-8,则文件开头有ï»。
知道如何使用 UTF-8 和不带 BOM 保存文件吗?
在最好的情况下,相关列表将包含对 this question 的引用,我发现它是 "vbscript adodb.stream bom vbscript site:whosebug.com".
的第一个匹配项基于boost's answer的第二个策略:
Option Explicit
Const adSaveCreateNotExist = 1
Const adSaveCreateOverWrite = 2
Const adTypeBinary = 1
Const adTypeText = 2
Dim objStreamUTF8 : Set objStreamUTF8 = CreateObject("ADODB.Stream")
Dim objStreamUTF8NoBOM : Set objStreamUTF8NoBOM = CreateObject("ADODB.Stream")
With objStreamUTF8
.Charset = "UTF-8"
.Open
.WriteText "aÄö"
.Position = 0
.SaveToFile "toto.php", adSaveCreateOverWrite
.Type = adTypeText
.Position = 3
End With
With objStreamUTF8NoBOM
.Type = adTypeBinary
.Open
objStreamUTF8.CopyTo objStreamUTF8NoBOM
.SaveToFile "toto-nobom.php", adSaveCreateOverWrite
End With
objStreamUTF8.Close
objStreamUTF8NoBOM.Close
证据:
chcp
Active code page: 65001
dir
...
15.07.2015 18:48 5 toto-nobom.php
15.07.2015 18:48 8 toto.php
type toto-nobom.php
aÄö
我知道脚本文件系统对象的流插入了一个字节顺序标记,但我还没有在 ADODB 流中看到它。
或者至少,现在还没有:我很少使用 ADODB 流对象...
但我确实记得几年前在一些代码中写过这句话:
' **** WHY THIS IS COMMENTED OUT **** **** **** **** **** **** **** ****
'
' Microsoft ODBC and OLEDB database drivers cannot read the field names from
' the header when a unicode byte order mark (&HFF & &HFE) is inserted at the
' start of the text by Scripting.FileSystemObject 'Write' methods. Trying to
' work around this by writing byte arrays will fail; FSO 'Write' detects the
' string encoding automatically, and won't let you hack around it by writing
' the header as UTF-8 (or 'Narrow' string) and appending the rest as unicode
'
' (Yes, I tried some revolting hacks to get around it: don't *ever* do that)
'
' **** **** **** **** **** **** **** **** **** **** **** **** **** **** ****
'
' With FSO.OpenTextFile(FilePath, ForWriting, True, TristateTrue)
' .Write Join(arrTemp1, EOROW)
' .Close
' End With ' textstream object from objFSO.OpenTextFile
'
' **** **** **** **** **** **** **** **** **** **** **** **** **** **** ****
你可以看出我今天过得很糟糕。
接下来,使用原始 C:
中出现文件处理之前的史前 PUT 命令' **** WHY WE 'PUT' A BYTE ARRAY INSTEAD OF A VBA STRING VARIABLE **** ****
'
' Put #hndFile, , StrConv(Join(arrTemp1, EOROW), vbUnicode)
' Put #hndFile, , Join(arrTemp1, EOROW)
'
' If you pass unicode, Wide or UTF-16 string variables to PUT, it prepends a
' Unicode Byte Order Mark to the data which, when written to your file, will
' render the field names illegible to Microsoft's JET ODBC and ACE-OLEDB SQL
' drivers (which can actually read unicode field names, if the helpful label
' isn't in the way). However, the 'PUT' statements writes a Byte array as-is
'
' **** **** **** **** **** **** **** **** **** **** **** **** **** **** ****
所以有实际执行此操作的代码:
Dim arrByte() As Byte
Dim strText As String
Dim hndFile As String
strText = "Y'all knew that strings are actually byte arrays?"
arrByte = strText
hndFile = FreeFile
Open FilePath For Binary As #hndFile
Put #hndFile, , arrByte
Close #hndFile
Erase arrByte
我假设 strText 实际上是 UTF-8。我的意思是,我们在 VBA,在 Microsoft Office 中,我们 绝对 知道这始终是 UTF-8,即使我们在国外使用它...
...对吗?