首页 文章

如何在VBA(Excel)中使用没有BOM编码的UTF-8保存文本文件(CSV)?

提问于
浏览
2

所以这是我最初的问题 . The answer 在我的问题下面,似乎是获得UTF-8(和没有BOM的UTF-8)编码的唯一解决方案是使用ADODB.Stream对象 .
主题行中我的新问题的答案将作为代码发布 .

我坐在这里尝试 Save Excel工作表作为带有VBA宏的 .CSV -file .
但是,我想知道我是否使用 ADODB / ADODB.Stream 或只是 .SaveAs Fileformat:=xlCSV 是否重要 . 我试过谷歌它,似乎我找不到答案的方法是"best" . 我需要它以逗号分隔,UTF-8和双引号(“”)作为文本标识符 .

使用 Fileformat:= 时,是否正确 SaveAs UTF-8,因为 xlCSV 没有使用该编码? YES, that is correct.

此代码将转换Excel工作表并将其保存为带有UTF-8的CSV文件,而不使用BOM编码 . 我在网站上找到了这个代码,所以我不会因此而受到赞扬 . CSV without BOM link

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

' 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
  Next

  'skip BOM
  UTFStream.Position = 3

  'copy UTFStream to BinaryStream
  Set BinaryStream = CreateObject("adodb.stream")
  BinaryStream.Type = adTypeBinary
  BinaryStream.Mode = adModeReadWrite
  BinaryStream.Open

  'Strips BOM (first 3 bytes)
  UTFStream.CopyTo BinaryStream

  UTFStream.Flush
  UTFStream.Close

  'save to file
  BinaryStream.SaveToFile FName, adSaveCreateOverWrite
  BinaryStream.Flush
  BinaryStream.Close

End Sub

1 回答

  • 0

    感谢您发布此问题以及解决方案 . 这对我帮助很大 . 是的,我还发现SaveAs不会将CSV文件保存为UTF8 . 在我的情况下,它使用shift-JIS . adodb.stream对我很有用 .

    但是,我不确定为什么,但我必须声明您在代码中使用的一些常量(枚举) . (我对VBA真的很陌生,所以也许我错过了为什么会这样的事情) . 我在函数的开头添加了这个,然后它完美地运行了:

    Const adTypeText = 2
      Const adModeReadWrite = 3
      Const adTypeBinary = 1
      Const adLF = 10
      Const adSaveCreateOverWrite = 2
      Const adWriteLine = 1
    

    我从Microsoft docs获得了 Value . 再一次,谢谢!

相关问题