VBA バイナリのデータを1byteずつファイルに書き出すには?(ADO使用)

解決


かん  2003-11-12 16:03:40  No: 80386  IP: [192.*.*.*]

Public Sub WriteTest(sReadFile As String, sWriteFile As String)

    Dim StmRead As Object
    Dim vReadData As Variant
    Dim StmWrite As Object
  Dim b As Variant
    Const adTypeBinary = 1
    Const adSaveCreateOverWrite = 2

    '読み込むファイルの設定
    Set StmRead = CreateObject("ADODB.Stream")
    StmRead.Open
    StmRead.Type = adTypeBinary
    StmRead.LoadFromFile sReadPath
    vReadData = StmRead.Read  '一気に読み込む

    
    For i = 0 To Ubound(vReadData)
        
        b = vReadData(i)  '1byteずつ取得
        
    If (b = &H0A) then
      '〜 bを解析する処理 〜
    End If
    
      StmWrite.Write b  '1biteずつ書き込む
    
    Next i
    
    '一気にファイルに書き出す
    StmWrite.SaveToFile sWritePath, adSaveCreateOverWrite

    'StmReadを閉じる
    StmRead.Close
    Set StmRead = Nothing

    'StmReadを閉じる
    StmWrite.Close
    Set StmWrite = Nothing

End Sub

で、
”StmWrite.Write b”
のところでエラーになってしまいます。
ADOのWriteメソッドの使用方法がいまいちつかめてません。

どうかご教授願います。

編集 削除
かん  2003-11-12 16:05:49  No: 80387  IP: [192.*.*.*]

上記関数に抜けがありました。
訂正します。

Public Sub WriteTest(sReadFile As String, sWriteFile As String)

    Dim StmRead As Object
    Dim vReadData As Variant
    Dim StmWrite As Object
  Dim b As Variant
    Const adTypeBinary = 1
    Const adSaveCreateOverWrite = 2

    '読み込むファイルの設定
    Set StmRead = CreateObject("ADODB.Stream")
    StmRead.Open
    StmRead.Type = adTypeBinary
    StmRead.LoadFromFile sReadPath
    vReadData = StmRead.Read  '一気に読み込む

    '作成するファイルの設定
    Set StmWrite = CreateObject("ADODB.Stream")
    StmWrite.Open
    StmWrite.Type = adTypeBinary
    
    For i = 0 To Ubound(vReadData)
        
        b = vReadData(i)  '1byteずつ取得
        
    If (b = &H0A) then
      '〜 bを解析する処理 〜
    End If
    
      StmWrite.Write b  '1biteずつ書き込む
    
    Next i
    
    '一気にファイルに書き出す
    StmWrite.SaveToFile sWritePath, adSaveCreateOverWrite

    'StmReadを閉じる
    StmRead.Close
    Set StmRead = Nothing

    'StmReadを閉じる
    StmWrite.Close
    Set StmWrite = Nothing

End Sub

編集 削除
かん  2003-11-12 17:17:18  No: 80388  IP: [192.*.*.*]

http://www.roy.hi-ho.ne.jp/mutaguchi/bbs/list84.shtml
に全く同じ悩み事がかかれていましたが,
解決していないようです。

----------------------------
抜粋:

じゅん さん 2003年 06月 13日 10時 28分 51秒 

>Nomuさん
レスどうもありがとうございます。少し説明が足りませんでした。
WriteやSaveToFileはわかっていたですが、16進ダンプデータのバイト配列
をどう書いたらいいのかがわかりません。
下記のようにやってみたのですが、
objADOStream.Write Buffer  のところで
引数が間違った型、許容範囲外、または競合しています。
となってエラーになります。

Set objADOStream = WScript.CreateObject("Adodb.Stream")
Buffer = "&H01,&H02,&H03"
Const adTypeBinary = 1 
Const adSaveCreateOverWrite = 2 
objADOStream.Type = adTypeBinary
objADOStream.Open
objADOStream.Write Buffer
objADOStream.SaveToFile "test.bin", adSaveCreateOverWrite
objADOStream.Close

2行目のBufferのところはどう記述すればいいのでしょうか?
よろしくお願いします。

編集 削除
魔界の仮面弁士  2003-11-12 21:30:29  No: 80389  IP: [192.*.*.*]

・『Option Explicit』宣言を行っていますか? (念のため)

・プロシージャの引数は「sReadFile」ですが、
  LoadFromFileの引数は「sReadPath」になっています。

・プロシージャの引数は「sWriteFile」ですが、
  SaveToFile の引数は 「sWritePath」になっています。

・Writeメソッドの引数に「Byte型」の値は指定できません。
  指定できるのは、「Byte型の配列」です。

・「1byteずつ書き込む」が「1biteずつ書き込む」になっています。(噛)

編集 削除
かん  2003-11-13 09:37:41  No: 80390  IP: [192.*.*.*]

ご指摘の通りです。
すいません。。。

> ・『Option Explicit』宣言を行っていますか? (念のため)
やっています。

> ・プロシージャの引数は「sReadFile」ですが、
>   LoadFromFileの引数は「sReadPath」になっています。
> ・プロシージャの引数は「sWriteFile」ですが、
>   SaveToFile の引数は 「sWritePath」になっています。
間違えです。
ソースの方はsReadPathで統一していますので
sReadPathでお願いします。

> ・Writeメソッドの引数に「Byte型」の値は指定できません。
>   指定できるのは、「Byte型の配列」です。
Writeメソッドの引数には、Variantを指定しています。
それでエラーが出てしまいます。
Variantに1byteデータを1つ入れて1byteずつWriteしても、
Variantに1byteデータを複数入れて(配列)一気にWriteしても、
だめでした。

> ・「1byteずつ書き込む」が「1biteずつ書き込む」になっています。(噛)
すいません。ミスです。。。

編集 削除
魔界の仮面弁士  2003-11-13 09:51:08  No: 80391  IP: [192.*.*.*]

> Writeメソッドの引数には、Variantを指定しています。
> Variantに1byteデータを1つ入れて1byteずつWriteしても、
> Variantに1byteデータを複数入れて(配列)一気にWriteしても、
> だめでした。
う〜む、何故でしょう……。
そのVariantには、何を格納していますか?

本来は、Byte型の配列(もしくは、Byte配列を格納したVariant)を
渡すことで、書き込めると思うのですが。。。

  Dim B(0) As Byte
  B(0) = バイト値
  objADOStream.Write B

編集 削除
かん  2003-11-13 10:03:34  No: 80392  IP: [192.*.*.*]

> ・Writeメソッドの引数に「Byte型」の値は指定できません。
>   指定できるのは、「Byte型の配列」です。
が気になって、Writeメソッドの引数を、
Variantを指定から、Byte型配列にしてみたら解決いたしました。

魔界の仮面弁士様、
ありがとうございました。


Public Sub WriteTest()
    Dim sReadPath As String     '読み込みファイルパス
    Dim StmRead As Object       '読み込み用
    Dim vReadData As Variant    '読み込んだデータ格納
    Dim lReadIdx As Long        'vReadData()のインデックス
    Dim sWritePath As String    '書き込みファイルパス
    Dim StmWrite As Object      '書き込み用
    Dim bWriteData() As Byte      '書き込んだデータ格納
    Dim lWriteIdx As Long       'bWriteData()のインデックス
    Const adTypeBinary = 1
    Const adSaveCreateOverWrite = 2
    
    '変数初期化
    ReDim bWriteData(0)
    lWriteIdx = 0
    sReadPath = "G:\usr\kato\gui_tool\test.txt"
    sWritePath = "G:\usr\kato\gui_tool\test2.txt"
    
    '読み込むファイルの設定
    Set StmRead = CreateObject("ADODB.Stream")
    StmRead.Open
    StmRead.Type = adTypeBinary
    StmRead.LoadFromFile sReadPath
    vReadData = StmRead.Read    '一気に読み込む

    '作成するファイルの設定
    Set StmWrite = CreateObject("ADODB.Stream")
    StmWrite.Open
    StmWrite.Type = adTypeBinary
    
    For lReadIdx = 0 To UBound(vReadData)
        
        If (vReadData(lReadIdx) = &HA) Then
            '〜 vReadData(lReadIdx)を解析する処理 〜
        End If
        
        ReDim Preserve bWriteData(lWriteIdx)       'バッファ更新
        bWriteData(lWriteIdx) = vReadData(lReadIdx)
        lWriteIdx = lWriteIdx + 1
    
    Next lReadIdx
    
    '一気にファイルに書き出す
    StmWrite.Write bWriteData
    StmWrite.SaveToFile sWritePath, adSaveCreateOverWrite

    'StmReadを閉じる
    StmRead.Close
    Set StmRead = Nothing

    'StmReadを閉じる
    StmWrite.Close
    Set StmWrite = Nothing

End Sub

編集 削除
かん  2003-11-13 10:06:22  No: 80393  IP: [192.*.*.*]

〜追記〜

でも
Variantにはバイト型のデータを格納していたのですが、
それではできなかったです。
VariantをByte()に変えたらそのままできました。

編集 削除
魔界の仮面弁士  2003-11-13 13:13:05  No: 80394  IP: [192.*.*.*]

> Variantにはバイト型のデータを格納していたのですが、
> それではできなかったです。
うぅむ。当方では、問題なくVariantで制御できるのですけれども……。
          :
    V(4) = CByte(&H94)
    V(5) = CByte(&HCC)
          :
    objStream.Write V


>        If (b = &H0A) then
>            '〜 bを解析する処理 〜
>        End If
この部分で、配列中の一部のデータが、Byteではなく
IntegerやLongになってしまっていた……なんて事はありませんか?

編集 削除
かん  2003-11-13 13:57:30  No: 80395  IP: [192.*.*.*]

>        If (b = &H0A) then
>            '〜 bを解析する処理 〜
>        End If
では
bがどんな値かを見て、それをファイルに書くか否かを決めているだけで、
bそのものはいじっていないのです。

編集 削除