web-dev-qa-db-ja.com

VBA:BOMなしでUTF-8でファイルを保存

それはおそらくsthgシンプルです、ここが私が試したものです:

 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を使用せずにファイルを保存する方法に関するアイデアはありますか?

10
Julien

すべての可能な世界の中で、関連リストには、「vbscript adodb.stream bom vbscript」の最初のヒットとして見つけた this question への参照が含まれます。 site:stackoverflow.com」。

ブーストの答え からの2番目の戦略に基づいて:

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Äö
19
Ekkehard.Horner

Scripting File System Objectのストリームがバイトオーダーマークを挿入することは知っていましたが、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になることを知っています...

...正しい?

2
Nigel Heffernan