这是我的第一个问题。对我下面问题的答案似乎是,获得UTF-8 (和UTF-8没有BOM)编码的唯一解决方案是使用ADODB.Stream对象。
标题中我的新问题的答案是以代码形式发布的。
我坐在这里,试图将一个Save
表作为一个带有VBA宏的.CSV
_-文件。
但是,我想知道我是使用ADODB
/ADODB.Stream
还是只使用.SaveAs
Fileformat:=xlCSV
__。我尝试过搜索它,似乎我找不到哪种方法是“最好”的答案。我需要用逗号分隔,UTF-8和双引号("")作为文本标识符。
当您使用Fileformat:=
__时,SaveAs
UTF-8是不可能的,因为xlCSV
没有使用该编码,这是正确的吗?是的,这是正确的。。
请看我对解决方案的回答。
发布于 2020-04-02 21:43:34
所以我再次遇到了需要这段代码的情况,我读了评论和Leonard的答案,这让我更新了我的代码,并提供了更好的描述。
此代码将转换您的Excel表,并将它保存为一个CSV文件与UTF-8没有BOM编码。我在一个网站上找到了这段代码,所以我不会因此而受到赞扬。无BOM链路的CSV
Option Explicit
Sub CSVFileAsUTF8WithoutBOM()
Dim SrcRange As Range
Dim CurrRow As Range
Dim CurrCell As Range
Dim CurrTextStr As String
Dim ListSep As String
Dim FName As Variant
Dim UTFStream As Object
Dim BinaryStream As Object
' ADO Constants
Const adTypeBinary = 1 ' The stream contains binary data
Const adTypeText = 2 ' The stream contains text data (default)
Const adWriteLine = 1 ' write text string and a line separator (as defined by the LineSeparator property) to the stream.
Const adModeReadWrite = 3 ' Read/write
Const adLF = 10 ' Line feed only - default is carriage return line feed (adCRLF)
Const adSaveCreateOverWrite = 2 ' Overwrites the file with the data from the currently open Stream object, if the file already exists
' Open this workbook location
ChDrive Left(ThisWorkbook.Path, 1)
ChDir ThisWorkbook.Path
' ask for file name and path
FName = Application.GetSaveAsFilename("", "CSV File (*.csv), *.csv")
' prepare UTF-8 stream
Set UTFStream = CreateObject("adodb.stream")
UTFStream.Type = adTypeText
UTFStream.Mode = adModeReadWrite
UTFStream.Charset = "UTF-8"
UTFStream.LineSeparator = adLF
UTFStream.Open
'set field separator
ListSep = ";"
'set source range with data for csv file
If Selection.Cells.Count > 1 Then
Set SrcRange = Selection
Else
Set SrcRange = ActiveSheet.UsedRange
End If
For Each CurrRow In SrcRange.Rows
'enclose each value with quotation marks and escape quotation marks in values
CurrTextStr = ""
For Each CurrCell In CurrRow.Cells
CurrTextStr = CurrTextStr & """" & Replace(CurrCell.Value, """", """""") & """" & ListSep
Next
'remove ListSep after the last value in line
While Right(CurrTextStr, 1) = ListSep
CurrTextStr = Left(CurrTextStr, Len(CurrTextStr) - 1)
Wend
'add line to UTFStream
UTFStream.WriteText CurrTextStr, adWriteLine ' Writes character data to a text Stream object
Next
'skip BOM
UTFStream.Position = 3 ' sets or returns a long value that indicates the current position (in bytes) from the beginning of a Stream object
'copy UTFStream to BinaryStream
Set BinaryStream = CreateObject("adodb.stream")
BinaryStream.Type = adTypeBinary
BinaryStream.Mode = adModeReadWrite
BinaryStream.Open ' Opens a Stream object
'Strips BOM (first 3 bytes)
UTFStream.CopyTo BinaryStream ' Copies a specified number of characters/bytes from one Stream object into another Stream object
UTFStream.Flush ' Sends the contents of the Stream buffer to the associated underlying object
UTFStream.Close ' Closes a Stream object
'save to file
BinaryStream.SaveToFile FName, adSaveCreateOverWrite
BinaryStream.Flush ' Sends the contents of the Stream buffer to the associated underlying object
BinaryStream.Close ' Closes a Stream object
End Sub
发布于 2018-03-21 01:24:52
谢谢你贴出这个问题和解决方案。这对我有很大帮助。是的,我还发现SaveAs没有在UTF8中保存CSV文件。在我的例子中,它使用shift-JIS。adodb.stream对我来说很好。
但是,我不知道为什么,但我必须声明您在代码中使用的一些常量(enum)。(我对VBA非常陌生,所以我可能忽略了为什么会发生这种情况)。我在函数的开头添加了这个,然后它完美地工作了:
Const adTypeText = 2
Const adModeReadWrite = 3
Const adTypeBinary = 1
Const adLF = 10
Const adSaveCreateOverWrite = 2
Const adWriteLine = 1
我从微软文档中得到了价值。再一次,谢谢!
https://stackoverflow.com/questions/29468070
复制相似问题