VBAを使って、
あるバイナリファイルを読み込み
5000バイト~5100バイトの部分だけをカットして
ファイルを出力するプログラムを作りたいと考えています。
Dim buf As String
Dim buf2 As String
Open filepath For Binary As #1
buf = Space(5000)
buf2 = Space(FileLen(filepath(j)) - 5100)
Get #1, , buf
Get #1, 5100, buf2
Close #1
intFileNumber = FreeFile 'ファイルの空き番号を得る
Open Strpath For Binary As intFileNumber
Put intFileNumber, , buf
Put intFileNumber, 5000, buf2
Close intFileNumber '必ず、最後にcloseする必要がある
この方法で作成すると元が64.5kBだったファイルが76.5kBとなり、
元よりも大きなサイズになってしまいます。
恐らく、bufをbyteで定義して
for文で一つずつ回していけばうまくいくのではないかと思うのですが
この方法だと時間がかかってしまいます。
for文を使わずに一度にまとめてファイルを読み込んで
入出力したいのですがどうすれば良いでしょうか?
No.1
- 回答日時:
byte型の配列を使えば良いと思います。
Option Explicit
Sub foo()
Dim buf(5000 - 1) As Byte
Dim buf2() As Byte
Dim infile As String
Dim intFileNumber As Integer
Dim size As Integer
infile = "path\test.bin"
ReDim buf2(FileLen(infile) - 5100)
Open infile For Binary As #1
Get #1, , buf()
Get #1, 5100, buf2()
Close #1
intFileNumber = FreeFile 'ファイルの空き番号を得る
Open "C:\work\excel\out.bin" For Binary As intFileNumber
Put intFileNumber, , buf()
Put intFileNumber, 5000, buf2()
Close intFileNumber '必ず、最後にcloseする必要がある
End Sub
No.2
- 回答日時:
No.1です。
私もそんなに詳しくないのですが……検索は、数十KB程度のファイルなら、byte型配列をループで行ってもそんなに時間はかからないのではないでしょうか?
検索対象1文字目だけをチェックしてヒットしたら2~4文字目の確認を行えばよいと思います。
Sub bar()
Dim filename As String
filename = "path\file.bin"
Dim MAXSIZE As Integer
MAXSIZE = FileLen(filename) - 1
Dim buf() As Byte
ReDim buf(MAXSIZE)
Dim index As Integer
Open filename For Binary As #1
Get #1, , buf()
Close #1
index = 0
Do While index <= MAXSIZE - 3
If buf(index) = &H63 Then '1文字目チェック
If buf(index + 1) = &H48 And buf(index + 2) = &H52 And buf(index + 3) = &H4D Then
Exit Do
End If
End If
index = index + 1
Loop
MsgBox index
End Sub
> 文字列型で読み込んだ時とバイト型で読み込んだ時で
> 出力されるファイルサイズが異なるかも教えていただけないでしょうか?
こちらも再現確認したわけではないので憶測ですが、そもそもstring型の1文字は、1byteとは限らないのではないでしょうか?
なので、サイズ計算に齟齬が生じるのではないかと思います。
No.3ベストアンサー
- 回答日時:
> VBAだとForだとできないとしてVBやC言語などは
> Forを使わずに全検索する機能があるのでしょうか?
ファイルに保存されているシーケンシャルなデータを検索するのですから、言語によらず頭から順にチェックしていくしかないはずです。組み込みの検索関数などの機能があって多少の最適化アルゴリズムを使用しているかもしれませんが、結局は同じことではないでしょうか?
あと、速度を気にされるのでしたらVBAよりも、いずれかのコンパイル言語を使用したほうが良いと思います。
> あと、Unicodeだと一文字2バイトのはずなので
> ANSI形式で読み込まれているということでしょうか?
たしかに内部表現ではUnicodeを使用しているかもしれませんが、そもそもファイルをbinaryモードでオープンしている時点で適切なエンコードは行われないと思います。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Excel(エクセル) Excelにて、フォルダ内のTextファイルをマクロで統合すると文字化けしてしまう時の解消コード 4 2023/01/01 07:32
- Excel(エクセル) 2つのVBAを一緒にしたら機能しなくなりました(エクセル) 7 2022/06/02 12:41
- Visual Basic(VBA) Excel-VBAでのファイルの開き方 4 2023/02/14 11:01
- Excel(エクセル) VBA フォルダ見える化のコードについて 2 2023/06/19 15:04
- Visual Basic(VBA) エクセルのマクロについて教えてください。 2 2023/07/15 15:48
- Excel(エクセル) エクセル VBA For Next 繰り返しの書き方を教えてください 6 2022/09/01 14:11
- Visual Basic(VBA) フォルダの場所を可変にしたいです(マクロ) 4 2023/05/11 10:00
- Visual Basic(VBA) 複数csvを横に追加していくマクロについて 2 2023/04/25 09:19
- Visual Basic(VBA) VBAのユーザーフォームのテキストボックスに入力制限をしたい 6 2022/11/15 08:28
- Visual Basic(VBA) エクセルのマクロについて教えてください。 4 2023/02/05 09:55
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
テキストファイルを後ろから読...
-
C言語でのファイル読み込み
-
CSVファイルによる検索の高速化
-
Mscomm を使用してバイナリでデ...
-
バイト型のデータを16進表記で...
-
グレースケール画像の画素値を得る
-
awk getlineをもう一度ファイル...
-
Unicodeのファイル読み込みがう...
-
日本語を配列に収め、そして表...
-
VBScriptの配列は、要素数を指...
-
VBAでテキストファイルの改行を...
-
隣接行列プログラム
-
掲示板の編集機能
-
ファイルのアクセス回数について
-
バッチファイル 二つ上のディ...
-
エクセルで複数のコメントのサ...
-
エクセルvbaでdocuworksprinter...
-
エクセルのプロパティーでセキ...
-
バッチファイル XCOPYで上書き...
-
Windows10でコマンドプロンプト...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
バイト型のデータを16進表記で...
-
VBAでテキストファイルを複数開...
-
RGBのバイナリデータをCImageに...
-
VBAでテキストファイルの改行を...
-
DXFファイルをVBで取り込み、図...
-
[VBS] 16進数でバイナリファイ...
-
ファイル内の(&H0A)を(&H0D0A)...
-
ファイルをメモリに出力する方法
-
テキストファイルを後ろから読...
-
Cで2次元配列にCSVファイルを...
-
ファイル入力のデータを構造体...
-
Excel VBAで画像解析
-
VBScriptの配列は、要素数を指...
-
ファイルからビット単位での読...
-
fread関数の使い方がわかりませ...
-
awk getlineをもう一度ファイル...
-
バイナリファイルでOutOfMemory...
-
VBSにてCSV読み込みし比較
-
バイナリファイルの一部分をカ...
-
日本語混じりのファイルをラン...
おすすめ情報
ありがとうございます。
パーフェクトでした。
あともう一つお聞きしたいのですが
文字列で「cHRM」、16進数で「6348524D」のバイト位置を検索して調べたいのですが
どうするのがもっとも高速でしょうか?
bufをstringとして定義しておいて、
ファイルを文字列として読み込み
「cHRM」をInstrで検索する。
しかしこの方法だと「cHRM」のバイト単位での正確な位置は特定できませんよね?
となると、
「6348524D」を一度10進数に変換してから
教えてくださったbyte型の配列に取り込む方法で
取り込み
For文を使って、一つ一つ適合する箇所を探すしかないでしょうか?
For文は回数が多くなると時間がかかるので
もっと良い方法があれば教えてください。
そもそもなぜ
文字列型で読み込んだ時とバイト型で読み込んだ時で
出力されるファイルサイズが異なるかも教えていただけないでしょうか?
ありがとうございます。
一つのファイルは
数十KB程度なのですが数百とか数千個読み込むのでできる限り高速にしたいと考えています。
VBAだとForだとできないとしてVBやC言語などは
Forを使わずに全検索する機能があるのでしょうか?
あと、Unicodeだと一文字2バイトのはずなので
ANSI形式で読み込まれているということでしょうか?
でもUnicode形式をANSIに変換してみるとVBA上で文字を読むことができなくなるので
Unicodeを使っていると思ったのですが・・・
なぜでしょうか?
もうしばらく質問をあげておきますので
もしご回答があればよろしくお願いいたします。
ありがとうございます。
コードまで書いて下さり助かりました。