No.6ベストアンサー
- 回答日時:
追加分の場合を少し変更
Sub test()
Dim fso As New FileSystemObject
Dim file1 As String
Dim file2 As String
Dim size1 As Long
Dim buf As String
file1 = "C:\file1.txt" '旧ファイル
file2 = "C:\file2.txt" '新ファイル
'旧ファイルのサイズ(文字数、バイト数ではない)を取得
With fso.GetFile(file1).OpenAsTextStream
size1 = Len(.ReadAll)
.Close
End With
'新ファイル読み込み
With fso.GetFile(file2).OpenAsTextStream
.Skip size1 '読み込みスキップ
buf = .ReadAll '追加分読み込み
.Close
End With
Set fso = Nothing
MsgBox buf
'配列にするなら、
'Dim d() As String
'd = Split(buf, vbCrLf)
End Sub
ADODB.Streamを使って、file1を読まない場合
Sub test()
Dim strm As New ADODB.Stream
Dim fso As New FileSystemObject
Dim file1 As String
Dim file2 As String
Dim size1 As Long
Dim buf() As Byte
Dim s As String
file1 = "C:\file1.txt"
file2 = "C:\file2.txt" '新ファイル
'旧ファイルのサイズ(バイト数)を取得
size1 = fso.GetFile(file1).Size
Set fso = Nothing
'新ファイル読み込み
With strm
'バイナリで増えた分を読み込み
.Open
.Type = adTypeBinary
.LoadFromFile file2
.Position = size1
buf = .Read(adReadAll)
.Close
'文字列に変換
.Open
.Type = adTypeBinary
.Write buf
.Position = 0
.Type = adTypeText
.Charset = "shift_jis"
s = .ReadText(adReadAll)
.Close
End With
set strm = Nothing
MsgBox s
'配列にするなら、
'Dim d() As String
'd = Split(s, vbCrLf)
End Sub
fumufumuさん、たびたびすみません。
現在の方法でも遅れた時に手動で流れを一時ストップすれば動くことは動くんです。
ただ、それでは不完全なのでお聞きしました。
教えていただいたコードを自分でチェックしながらやってみます。
新回答が次々増えると困るので、一度これで締め切ります。
有り難うございました。
No.5
- 回答日時:
追加という条件なら
Sub test()
Dim fso As New FileSystemObject
Dim file1 As String
Dim file2 As String
Dim buf As String
file1 = "C:\file1.txt"
file2 = "C:\file2.txt" '新ファイル
With fso.GetFile(file1).OpenAsTextStream
buf = .ReadAll
.Close
End With
With fso.GetFile(file2).OpenAsTextStream
buf = .Read(Len(buf))
buf = .ReadAll
.Close
End With
MsgBox buf
Set fso = Nothing
End Sub
file1は、.sizeでサイズだけ読んで、その分offsetする方がいいので、本当はADODB.Stream使った方がいいかもしれない。
途中をチェックするなら、追加部分に重複がない条件だけれどinstrでvbに任せた方が早いかも。
Sub TestDiffShowing()
Dim fso As New FileSystemObject
Dim file1 As String
Dim file2 As String
Dim buf1 As String
Dim buf2() As String
Dim i As Integer
file1 = "C:\file1.txt"
file2 = "C:\file2.txt" '新ファイル
With fso.GetFile(file1).OpenAsTextStream
buf1 = .ReadAll
.Close
End With
With fso.GetFile(file2).OpenAsTextStream
buf2 = Split(.ReadAll, vbCrLf)
.Close
End With
buf1 = vbCrLf & buf1 & vbCrLf
For i = 0 To UBound(buf2)
If InStr(buf1, vbCrLf & buf2(i) & vbCrLf) = 0 Then
MsgBox buf2(i)
End If
Next
Set fso = Nothing
End Sub
p.s.
とりあえず、ファイルは読まないか、読むなら一発で読んだ方が早いと思う
No.4
- 回答日時:
こんばんは。
>コンマ秒単位の各ファイル処理をしなければならない
たぶん、BDiff のようなツールのことをおっしゃっていると思いますが、VBA では、オーバーヘッドが大きすぎて、どの方法を取っても、そういう話は、かなり厳しいと思いますね。たとえば、CommandLine のFC コマンドでも、一旦、VBAを抜け出てしまうので、行き帰りではコンマ秒単位は無理かもしれません。
ためしに考えてみましたが、無理かもしれませんね。
'一括で取るなら、こういう方法は考えられます。出力は、今は、MsgBox にしていますが、適当に、Debug.Print や、セルなどに出力してください。
'--------------------------------------------------------------
Sub TestDiffShowing()
'オーバーヘッドが気になるようなら、参照設定要
'Microsoft Scripting Runtime
Dim objFS As Object 'FileSystemObject
Dim objText As Object 'TextStream
Dim fnA As String
Dim fnB As String
Dim mText As String
Dim mDiff As String
Dim LastLine As Long
Dim i As Long
fnA = "C:\Test1.txt"
fnB = "C:\Test1N.txt" 新ファイル
Set objFS = CreateObject("Scripting.FileSystemObject")
Set objText = objFS.OpenTextFile(fnA)
mText = objText.ReadAll
LastLine = objText.Line
objText.Close
Set objText = objFS.OpenTextFile(fnB)
For i = 1 To LastLine - 1
objText.SkipLine
Next i
Do While objText.AtEndOfLine <> True
mDiff = mDiff & objText.ReadLine & vbCrLf
Loop
MsgBox mDiff
'Debug.Print mDiff
objText.Close
Set objText = Nothing
Set objFS = Nothing
End Sub
Wendyさん、こんばんは。 m(_ _)m
ごく基本的なステートメントでやったんですが(それしか知らないもので・・)、早く動かすとなるとやはり高度な処理が必要なんですね。
インスタンスとか使ってるんでしょうか。教えていただいたマクロ、調べながらやってみます。
ありがとうございます。
No.3
- 回答日時:
> リアルタイムでコンマ秒単位の各ファイル処理をしなければならない
かなりシビアな要求ですね...VBA では厳しい(無理?)と思います。
> Line Inputで文字列を入れた変数Xがあります
少しでも高速でテキストファイルを読み込みたいなら、Binary モードで
まず全体をバッファ用変数に読み込み、Split (区切り文字:改行コード)
で配列にばらすのはどうですか?
その配列内を WorksheetFunction の Match とか Vlookup で比較します。
下記に一例を書いてみます。ただし、実際にテストしたわけではありま
せんが、先述のとおりコンマ秒という要求に追従できるかは疑問です^^;
少なくとも Line Input で行単位で読み込む、行単位で逐次比較していく
よりは高速なはずですが...
# 1つのテキストファイル内に全く同一の行が無いことが前提です
ご参考までに。
Sub SampleProc()
Dim n As Integer
Dim sBuffer As String
Dim X As Variant
Dim Y As Variant
Dim i As Long
' // ※ 注意
' // 変数 sInFile1, sInFile2 にはテキストファイルの
' // フルパスを代入しておいて下さい
' // テキスト1 をバイナリモードで読み込み、変数 X に
' // 改行コードで行単位にばらした配列を作成
n = FreeFile()
Open sInFile1 For Binary Lock Read Write As #n
sBuffer = Space$(LOF(n))
Get #n, , sBuffer
Close #n
X = Split(sBuffer, vbCrLf)
' // テキスト2 も同様の処理
n = FreeFile()
Open sInFile2 For Binary Lock Read Write As #n
sBuffer = Space$(LOF(n))
Get #n, , sBuffer
Close #n
Y = Split(sBuffer, vbCrLf)
' // イミディエイトウインドウに差分抽出の結果を表示
For i = 0 To UBound(Y)
' // Match 関数の結果でエラー値が返るようなら
' // テキスト2(Y) にあって、テキスト1(X) には無い
If IsError(Application.Match(Y(i), X, 0)) Then
' // Split は 0 オリジンの配列を返すので
' // 行番号は+1になる
Debug.Print Format$(i + 1, "0000") & ": ";
Debug.Print Y(i)
End If
Next i
End Sub
お礼が遅れすみません。
作業の対象はかなりレベルが高いんですが、自分の持ってる知識は極わずかなのでギャップが大きいです。
Matchなど使ってみます。
ただ、たまに同一行が出てきます。それとバイナリだと他からアクセスされるとエラーが出るんではなかったでしたっけ? たぶんLock出来ないです。
あいまいな知識なんですが・・
回答有り難うございます。
No.2
- 回答日時:
根本的に違いはないのですが、Vlookupではなく、Match関数を使ってVBAで比較します。
Dim dmy As String
Dim er As Integer
Dim i As Integer
For i = 0 To UBound(y)
On Local Error Resume Next
dmy = Application.WorksheetFunction.Match(y(i), x, 0)
er = Err
On Local Error GoTo 0
If er <> 0 Then MsgBox y(i)
Next
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・街中で見かけて「グッときた人」の思い出
- ・「一気に最後まで読んだ」本、教えて下さい!
- ・幼稚園時代「何組」でしたか?
- ・激凹みから立ち直る方法
- ・1つだけ過去を変えられるとしたら?
- ・【あるあるbot連動企画】あるあるbotに投稿したけど採用されなかったあるある募集
- ・【あるあるbot連動企画】フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
- ・映画のエンドロール観る派?観ない派?
- ・海外旅行から帰ってきたら、まず何を食べる?
- ・誕生日にもらった意外なもの
- ・天使と悪魔選手権
- ・ちょっと先の未来クイズ第2問
- ・【大喜利】【投稿~9/7】 ロボットの住む世界で流行ってる罰ゲームとは?
- ・推しミネラルウォーターはありますか?
- ・都道府県穴埋めゲーム
- ・この人頭いいなと思ったエピソード
- ・準・究極の選択
- ・ゆるやかでぃべーと タイムマシンを破壊すべきか。
- ・歩いた自慢大会
- ・許せない心理テスト
- ・字面がカッコいい英単語
- ・これ何て呼びますか Part2
- ・人生で一番思い出に残ってる靴
- ・ゆるやかでぃべーと すべての高校生はアルバイトをするべきだ。
- ・初めて自分の家と他人の家が違う、と意識した時
- ・単二電池
- ・チョコミントアイス
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
window.open でのファイル指定方法
-
XML::Parserの parsefileの結果...
-
fgets で値が取得できない
-
圧縮された.tgzファイルの一部...
-
cgi.pm を使用してファイルUP時...
-
行を指定して削除する方法PERL
-
Firefox で file:// で始まる U...
-
区切りファイルの列ソートについて
-
ファイルの存在の有無を確かめ...
-
foreach内での変数の扱い?
-
ExcelをCSV書き出す場合のシー...
-
エクセルVBA コードが同じでも...
-
vba dir の相対パス
-
close()で例外が投げられる理由
-
batファイルでrenameができませ...
-
VBAでCSVファイルを途中行まで...
-
バッチファイルの作り方(CSV→...
-
VBAで巨大なファイルの途中から...
-
VBAでCSVファイルの特定行を書...
-
ADOによるCSVファイルからのデ...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
python renameについて
-
window.open でのファイル指定方法
-
MATLABのm-fileについて
-
fgets で値が取得できない
-
csvファイルの横方向への改行に...
-
巨大なテキストの最終行を取得...
-
Firefox で file:// で始まる U...
-
JSP URLに表示される拡張子 .jsp
-
重複ファイル名ある場合ファイ...
-
ファイルの存在の有無を確かめ...
-
ファイル全てを .xlsm に変更し...
-
PerlでのUseless use...
-
行を指定して削除する方法PERL
-
VBA テキストファイルを読み取...
-
HTMLのフォームで画像と文...
-
perl ファイルが開かない
-
並び方、
-
read() on unopened filehandle...
-
drtファイルはどうしたら開...
-
VBAコードを張り付け後のエクセ...
おすすめ情報