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.3ベストアンサー
- 回答日時:
> VBAだとForだとできないとしてVBやC言語などは
> Forを使わずに全検索する機能があるのでしょうか?
ファイルに保存されているシーケンシャルなデータを検索するのですから、言語によらず頭から順にチェックしていくしかないはずです。組み込みの検索関数などの機能があって多少の最適化アルゴリズムを使用しているかもしれませんが、結局は同じことではないでしょうか?
あと、速度を気にされるのでしたらVBAよりも、いずれかのコンパイル言語を使用したほうが良いと思います。
> あと、Unicodeだと一文字2バイトのはずなので
> ANSI形式で読み込まれているということでしょうか?
たしかに内部表現ではUnicodeを使用しているかもしれませんが、そもそもファイルをbinaryモードでオープンしている時点で適切なエンコードは行われないと思います。
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.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
お探しの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ランキング
-
バイト型のデータを16進表記で...
-
Cで2次元配列にCSVファイルを...
-
テキストファイルを後ろから読...
-
VBSにてCSV読み込みし比較
-
VBAでテキストファイルの改行を...
-
C言語でのファイル読み込み
-
掲示板の編集機能
-
DXFファイルをVBで取り込み、図...
-
fread関数の使い方がわかりませ...
-
[VBS] 16進数でバイナリファイ...
-
バイナリデータの書き換え
-
数値から画像を作りたい
-
ファイルのアクセス回数について
-
エクセルのプロパティーでセキ...
-
バッチファイル 二つ上のディ...
-
エクセルで複数のコメントのサ...
-
現在のブックを閉じないで、マ...
-
エクセルvbaでdocuworksprinter...
-
バッチファイル XCOPYで上書き...
-
A列に記載されているフォルダ...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
バイト型のデータを16進表記で...
-
VBAでテキストファイルの改行を...
-
テキストファイルを後ろから読...
-
VBAでテキストファイルを複数開...
-
バイナリファイルでOutOfMemory...
-
DXFファイルをVBで取り込み、図...
-
RGBのバイナリデータをCImageに...
-
CFileの使い方を教えてください
-
datagridviewでドラッグ操作が...
-
Excel VBAで画像解析
-
バイナリの読み込みから出力まで
-
bmpファイルの明暗の数値化の方法
-
fread関数の使い方がわかりませ...
-
SDKにて。
-
日本語を配列に収め、そして表...
-
バイナリ出力
-
VBSにてCSV読み込みし比較
-
ファイル内の(&H0A)を(&H0D0A)...
-
Cで2次元配列に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を使っていると思ったのですが・・・
なぜでしょうか?
もうしばらく質問をあげておきますので
もしご回答があればよろしくお願いいたします。
ありがとうございます。
コードまで書いて下さり助かりました。