[[20220810095633]] 『FSO OpenTextFileで書き込んだファイルフォーマッ』(エルモア) ページの最後に飛ぶ

[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]

 

『FSO OpenTextFileで書き込んだファイルフォーマットの違いについて』(エルモア)

FileSystemObjectのOpenTextFileを使用しよくファイルに書き込んでいるのですが
最近組んだマクロで普段UTF-8Nでテキストが作成されるのにUTF-16LEでデータが作成されてしまいました
コードが長すぎるのでここには載せられませんがUTF-16LEになる理由を知りたいので教えてもらえませんか?

処理としては以下のようなことをしています
UTF-8Nのcsvファイルを読み込み配列に格納  --- これを?@とする
(配列はカンマと改行(crlf)で区切った2次元配列に格納)
(読み込む際REGEXPを使用し"^\s+|\s+$"を""に置換しているその際MultiLineのみtrueとしている)
OracleDB内のテーブルを読み込み配列に格納 --- これを?Aとする
上二つを比較し?@の特定の文字列がある場所を?Aで置換する --- これを?Bとする
?Bの2次元目?をカンマでjoinして1次元の配列にする --- これを?Cとする
?Cをjoinして文字列にする --- これを㋐とする
㋐のvbcrをvbcrlfに、vblfをvbcrlfに置換する --- これを㋑とする
㋑をFileSystemObjectのOpenTextFileのWriteLineを使用して書き出す

ちなみに現在はADODB.StreamをしようしてUTF-8Nとして出力しようと試行しています

< 使用 Excel:Office365、使用 OS:Windows10 >


>ADODB.Streamをしようして
Excel と関係ない質問ですね。
そのサイトで聞いたらどうですか。
(・・・) 2022/08/10(水) 11:15

OpenTextFile メソッド (Visual Basic for Applications) | Microsoft Docs
https://docs.microsoft.com/ja-jp/office/vba/language/reference/user-interface-help/opentextfile-method

 ↑によると、
 =============================================================================================
 構文
 object.OpenTextFile (filename, [ iomode, [ create, [ format ]]])

 format
 省略可能。 開くファイルの形式を示す Tristate の 3 つの値のいずれかです。 
 省略すると、ASCII 形式でファイルが開きます。

 format引数には、次のいずれかを設定できます。
 TristateUseDefault -2 システムの既定の設定でファイルを開きます。
 TristateTrue       -1 Unicode 形式でファイルを開きます。
 TristateFalse       0 Ascii 形式でファイルを開きます。
 =============================================================================================

 って事だそうです。

 引数[format]が「TristateTrue」だった場合だけUTF16(LE)で保存されます。
 (バイナリエディタで確認しましたが、先頭(BOM)が[FF][FE]になってました)
 引数[format]を省略した場合や他の値にした場合はいずれも「システムの既定の設定」なので
 UTF16(LE)にはならないだろうなと思います。

 ご提示の処理の流れから言えば、最後の
 >FileSystemObjectのOpenTextFileのWriteLineを使用して書き出す
 ココにしか怪しそうな箇所は無さそうですが...
 実際ココの記述はどうなってるか確認済みでしょうか?

(白茶) 2022/08/10(水) 11:15


 おや? よく見てなかった。
 >普段UTF-8Nでテキストが作成されるのにUTF-16LEでデータが作成されてしまいました
 >普段UTF-8Nでテキストが作成される
 >  UTF-8Nでテキストが作成
         ↑って事は、
              普段はFileSystemObjectのOpenTextFileは使ってないハズですよね?
              FileSystemObjectでUFT-8エンコードは無理っしょ?

  >㋑をFileSystemObjectのOpenTextFileのWriteLineを使用して書き出す
 って書いてますけど...?

(白茶) 2022/08/10(水) 11:37


白茶さんありがとうございます
そのあたりのソースはこんな感じになっていて引数はデフォルトなんですけどね・・・
自作クラスからvalueで呼び出す際配列をjoinしてstring型の文字列で返してるんですけど頭にFFFEが入るような余地はないと思うんですよね・・・
 Public Function ConvertLineEnding(ByVal Text As String, Optional LineEnding As String = vbLf) As String
    ConvertLineEnding = Replace(Replace(Replace(Text, vbCrLf, vbLf), vbCr, vbLf), vbLf, LineEnding)
 End Function
 Public Sub lapMap(ByVal dicSource As Object, ByVal dicLayer As Object, ByVal destination As String)
    Dim key As Variant, m1 As New mapCls, m2 As New mapCls
    For Each key In dicSource.Keys
        If dicLayer.Exists(key) Then
            m1.Value = dicSource(key)
            m2.Value = dicLayer(key)
            Call m1.OverLap(m2)
        End If
        With FSO.OpentextFile(destination, 2, True, True)
            .WriteLine ConvertLineEnding(m1.Value, vbCrLf)
            .Close
        End With

普段もこんな書き方してるんですけどメモ帳等のテキストエディタではUTF-8Nとして認識されてるんでこういう書き方したら自分のPCだとUTF-8Nになるのかなと思っています
(エルモア) 2022/08/10(水) 11:46


 > With FSO.OpentextFile(destination, 2, True, True)
 これが「普段」のコードでしたら 生成されたファイルはやっぱりUTF16(LE)の筈なんですよ。

 >普段UTF-8Nでテキストが作成される
 ってのが誤解だったかもです。
 メモ帳はWin10以降、既定の文字コードがUTF-8になってるからその辺で見誤ってるかも知れませんね。

 いずれにせよ欲しい結果がUTF-8だったら、
 使うのはFileSystemObjectじゃなくってADODB.Streamの方でしょうね。

Excel VBAでBOM無しのUTF-8ファイルを作成する方法
https://excel-excel.com/tips/vba_490.html

エクセルVBAでBOM無しのUTF-8でCSVファイルなどを出力する方法
https://tonari-it.com/excel-vba-utf8n-bom/

文字コードをUTF-8 BOMなし(UTF-8N)でファイル保存をする方法
https://www.1-firststep.com/archives/2258

(白茶) 2022/08/10(水) 12:07


 >> With FSO.OpentextFile(destination, 2, True, True)
 >これが「普段」のコードでしたら 生成されたファイルはやっぱりUTF16(LE)の筈なんですよ。
そうだったんですね
でも普段作ったものと今回作ったもので違いがあるのはなんでなんですかね・・・?
両方半角英数と記号でハイフン[-]プラス[+]カンマ[,]crlfくらいしか使ってないんですけど・・・
とりあえずUTF-8で出力したいときはFileSystemObjectの使用はやめてADODB.Streamを使用します

ありがとうございました
(エルモア) 2022/08/10(水) 13:02


ちなみに普段With FSO.OpentextFile(destination, 2, True, True)で作成した際はFF FEは頭につかないです(バイナリエディタで確認済み)
(エルモア) 2022/08/10(水) 13:05

 へぇー。そうなんですか...

  '参照設定 =================================================================
  'Microsoft Scripting Runtime
  'Microsoft ActiveX Data Objects 2.8 Library
  '==========================================================================

    Sub ADO_ReadBin(FilePath As String)
        Dim r As Long, b() As Byte, v
        With New ADODB.Stream
            .Open
            .Type = adTypeBinary
            .LoadFromFile FilePath
            b = .Read(-1)
            For Each v In b
                Debug.Print IIf(v < &H10, "0", "") & Hex(v)
            Next
            .Close
        End With
    End Sub
    Sub FSO_WriteText(FilePath As String, Mode As Scripting.Tristate)
        Dim r As Range
        With New Scripting.FileSystemObject
            With .OpenTextFile(FilePath, ForWriting, True, Mode)
    '            .WriteLine "123" '何も書かない
                .Close
            End With
        End With
    End Sub

    Sub Test()
        Const FILE_PATH = "C:\xxx\test_UTF16.log"
        FSO_WriteText FILE_PATH, TristateTrue
        ADO_ReadBin FILE_PATH
    End Sub

 当方の実験結果では↓になりました。(イミディエイト)

 FF
 FE

(白茶) 2022/08/10(水) 15:00


 すみません自分のコード見直していつもと違う点(間違い)見つけました
 FSO.OpentextFile(destination, 2, True)いつもはformat指定してなかったです(というか今回引数が保存先, 書き込みモード, ファイルの新規作成, 上書きの可否, formatと勘違いしていました)
 最後の引数を消したらUTF-8Nで出てきましたお騒がせしました
(エルモア) 2022/08/10(水) 15:24

 >format指定してなかったです
 なら、Shift-JISだと思いますが...

 >最後の引数を消したらUTF-8Nで出てきました
 あれい?
               ...ま、いっか ^^;

(白茶) 2022/08/10(水) 16:39


コメント返信:

[ 一覧(最新更新順) ]


YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki. Modified by kazu.