アプリ版:「スタンプのみでお礼する」機能のリリースについて

大きなファイル2個(aとb)を1バイトずつ比較し、
相違の在る箇所とそれぞれの中身をファイル(c)に出力したいのですが、
サイトで調べたら『配列でやると速い』と出ていました。

具体的なコードが出ていませんでしたが、本当なのでしょうか。
また、単純に考えれば頭から1バイトずつの比較ですが、
何かいい方法があるのでしょうか。

なお、大きなファイルとは、最大で3,000,000バイトです。
また、excelはexcel2003しか保有していません。
こんな大きなものが配列に取り込めるのでしょうか。

そこら辺を具体的に教えて貰えると嬉しいのですが。


考えているイメージは以下の通りです。
まず、それぞれのファイルを配列に取り込み、
頭から1バイトずつ比較する。

ファイルa;abcdefghijklmnopqr,,,,,,,,,,,,
ファイルb;abcdefqhijkmnlopqr,,,,,,,,,,,,
ファイルc(配列);
7,g,q
12,l,m
13,m,n
14,n,l
,
,
,
,

宜しくお願いします。

A 回答 (5件)

No1です。


バイナリーファイルということで、理解しました。
以下は、読み込み領域を1バイトの配列で格納し、その領域に一気に読み込む
方法です。書き込みは、1バイトずつ、書き込んでいます。
500Mバイトのファイルを処理すると、読み込みは、できますが、
書き込みにかなり時間がかかります。(終わりません)
提示されたサイズが3Mバイトということなので、問題なく実行できます。
約5Mバイトのファイルで読み書きを行った時、2分ほどかかりました。

標準モジュールに登録してください。

Option Explicit
Public Sub バイナリーファイル読み書き()
Dim fname As String
Dim ofname As String
fname = "D:\goo\data\data1.mp4"
ofname = "D:\goo\data\odata1.mp4"
Dim bbuf() As Byte
Dim fsize As Long
Dim fn As Long
Dim ofn As Long
Dim i As Long
fn = FreeFile
Open fname For Binary Access Read As #fn
fsize = LOF(fn)
ReDim bbuf(fsize)
Get #fn, , bbuf
ofn = FreeFile
Open ofname For Binary Access Write As #ofn
For i = 0 To fsize - 1
Put #ofn, , bbuf(i)
Next
Close #fn
Close #ofn
MsgBox ("完了")
End Sub
    • good
    • 0
この回答へのお礼

何回も有難うございました。
バッチリです。
テストは1.6MBの写真でやってみましたが、
10秒掛かりませんでした。

取り敢えずやってみただけなので、
これからじっくり内容を見させていただきます。

すぐさまベストアンサーなのですが、
このサイトのアホさ故選べません。
後ほど押させていただきます。
大変お世話になりました。

お礼日時:2023/04/18 11:56

こんにちは



やりとりを見ていても、「ファイルの差分比較」をしたいのか「エクセルのデータの比較」をしたいのかよくわかりません。
また、「差分抽出ツール」を作る事が最終目的なのか、単に「ファイルの比較をする」ことが目的なのかもよくわかりません。

仮に、ファイルそのもののバイナリ比較を行いたいのだとするなら、既存のDiffツールやMergeツールを利用するのがてっ取り早いと思います。
バイナリだけでなくエクセル等に対応しているものもあります。
これから、ツールを自作して検証して、その上で比較することを考えれば、遥かに短時間で済むことでしょう。
検索すればツール自体はいろいろ見つかると思います。
以下は、一例です。
https://hep.eiz.jp/winmerge/
https://bashalog.c-brains.jp/18/04/03-180000.php

>excelvbaで対応する必要があります。
VBAで処理したいということなら、「バイナリ」や「バイト単位」での比較は関係なく、単にデータの比較をしたいだけではないのかと想像されますけれど・・・?
「データの比較をしたい」だけであるなら、上記のようなツールでも充分に対応可能と思います。


一方で、「自作なさる」ことが目的なら・・
>こんな大きなものが配列に取り込めるのでしょうか。
VBAで使用できるメモリは、PCのメモリ依存です。
メモリに余裕があれば、配列に読み込めるでしょう。
余裕が全くなければ、二つのブックを同時に開くことすら難しいかもしれません。

No2様のご指摘にもありますが、シート上のセルを全部使っているような場合には、まとめて配列に読み込むのは難しそうに思います。
>サイトで調べたら『配列でやると速い』と出ていました
速度向上が目的なら、まとめて全部を読み込む必要はないでしょう。
適当なセル範囲を単位として、配列で比較するだけでも相応の効果が期待できます。

例えば、シートの UsedRange の行数をnとすれば、INT(10000/n)列ずつ処理すようにしておけば、10000セル以下を1単位として順に処理することが可能になると考えられます。
10000は例示なので、セル内の文字数や、PCのメモリの余裕から上限を決めることになるでしょう。
(実際には、10000行を超える利用もあり得るので、単純に上記だけではうまくいきません。)

ただし、配列で比較できるのはセルの値のみです。
各セルの書式や関数設定状態、あるいは図形等のオブジェクト、更にはブックに設定されているマクロ等も比較するとなると、それなりに面倒になります。
この辺りをどうなさりたいのかも考慮しておく必要があるように思います。
    • good
    • 1

No3です。


追伸:
入力ファイルは、fname = "D:\goo\data\data1.mp4" です。
出力ファイルは、ofname = "D:\goo\data\odata1.mp4" です。
上記は、あなたの環境にあわせて、適切に設定してください。
尚、下記URLを参考にしています。
https://vbabeginner.net/read-binary-file/
http://www.cocoaliz.com/excelVBA/index.php/47/
    • good
    • 0

ご質問とNo1回答、及びそれに対するお礼は、何だか話が通じていない様に思われます。

私が考えるにご質問者様はMicrosoft Excel 2003の関数機能、具体的には『配列数式』を使って問題を解決したいのだと理解しました。
さて、ご質問者様も何回も指摘されているように、Excel 2003の セルの最大値(行の最大値)が65,536 個のようです(たしかに昔のExcelはそうだったはずです。)。

注意
Microsoft Office Excel 2003 および以前のバージョンの Excel の列には、65,536 個のセルがあります。 Microsoft Office Excel 2007 の列には、1,048,576 個のセルがあります。

ご質問がどうもはっきりしないのですが、一文字1セルと仮定すれば、3,000,000セル(行)が必要となり、たとえExcel 2007でもファイルを全て読み取れない事になります。
ご質問者としては最初に問題のファイルがExcel 2003でちゃんと読み取れるかどうか確認すべきでしょう。
    • good
    • 1
この回答へのお礼

ありがとうございます。
セルの数の制限について言われていますが、
どこに関係するのでしょうか、分かりません。

ファイルを一度セルに読み込む必要があるということでしょうか。
直接配列に取り込み配列間で比較する、
というイメージなのですが。

確かにファイルを読んで1バイトずつの比較では時間が掛かりました。
それを配列でという質問です。
ただ、私が配列の扱いを知らないので、
このような質問になっています。

お礼日時:2023/04/18 10:28

1.読み込むファイルは、テキストファイルなのでしょうか。

それともバイナリーファイルなのでしょうか。

2.テキストファイルの場合、漢字の文字もあるのでしょうか。
漢字の場合、2~3バイトで1文字なので、1バイトを出力しても、その1バイトが意味のある文字にはなりません。
又、テキストファイルの場合、その文字コードについても、決まっているのでしょうか。
シフトJIS
UTF-8(BOM有、BOM無)
EUC
等が考えられます。


3.ファイルの違いを検出するだけなら、compコマンドが提供されています。どうしても、VBAでファイルの比較を行うマクロを作りたいということでしょうか?
    • good
    • 0
この回答へのお礼

早速ありがとうございました。
いろいろと抜けていましたね。

文字はバイナリーです。
なので、漢字等は気にせず単純に1バイトの比較です。

また、一度dosコマンドのcompで
どんな風に入っているのかを見てみましたが、
10個のエラーに達成しましたという理由で終わってしまいます。

最終的には、相違の個所を配列で使いたいので、
excelvbaで対応する必要があります。

質問のように、
配列でファイルが作れさえすれば
どんなやり方でも構わないのですが、
excel2003しか保有していないのです。

宜しくお願いします。

お礼日時:2023/04/18 09:17

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!