- ベストアンサー
2つのCSVを比較して一致していないものを検出する方法
- 2つのCSVを比較して一致していないデータを検出する方法について教えてください。
- 特定の条件に基づいて、2つのCSVファイルの一致していないデータを抽出する方法を教えてください。
- VBスクリプトを使用して、2つのCSVファイルを比較し、一致していないデータを見つける方法を教えてください。
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
AccessのクエリをVBSに載せ替えてみたという、実験的なコードで、実用性は疑問ですが、ご参考まで。(自分自身Accessの助け無しにこのSQLを書く才覚はありませんので) 最初の課題に沿っているつもりですが、実行例もご質問に書いていただけると助かります。二つ目の課題もAccess上ではやってみましたが... VBSは滅多に使わないので、お作法に則っておりませんが、ご容赦下さい。 Dim cn Dim rs Dim connectionString Dim csvFilePath Dim item Dim mySQL Dim fso, dstFile Dim buf Set cn = CreateObject("ADODB.Connection") Set fso = CreateObject("Scripting.FileSystemObject") Set dstFile = fso.CreateTextFile("c:\testfile.txt", True) csvFilePath = "C:\" 'CSVファイルにラベル(フィールド名)が無いとする connectionString = "Provider=Microsoft.Jet.OLEDB.4.0;" _ & "Data Source=" & csvFilePath & ";" _ & "Extended Properties=""Text;HDR=NO;FMT=Delimited""" cn.Open connectionString mySQL = "SELECT tableA.F1, tableA.F2, tableA.F3" _ & " FROM A.csv AS tableA LEFT JOIN B.csv AS tableB ON (tableA.F3=tableB.F3) AND (tableA.F2=tableB.F2) AND (tableA.F1=tableB.F1)" _ & " WHERE (((tableB.F3) Is Null));" Set rs = cn.Execute(mySQL) Do While rs.EOF = False buf= chr(34) & rs.fields(0) & """,""" & rs.fields(1) & """,""" & rs.fields(2) & chr(34) dstFile.WriteLine buf rs.MoveNext Loop dstFile.Close rs.Close cn.Close Set rs = Nothing Set cn = Nothing Set fso = Nothing
その他の回答 (3)
- DOUGLAS_
- ベストアンサー率74% (397/534)
●VBScriptでテキストファイルの内容の間違い探しは出来るでしょうか? http://okwave.jp/qa/q6138246.html の続きかと存じますが、No.2 nda23 さんがお書きの >(1)データを読み込んで配列に溜め、比較を行う。 >(1)はまぁ、コテコテとプログラムすることになります。 に近い方法をお一つ。 ------------------------------------ >BのCSVの「A列の値+B列の値」がおなじものをAのCSVから探し >同じものを見つけたらBのCSVの同じ行のC列の値が一致しているか検索 とのことですが、その順序で コード を書くと、冗長になりますので、 1)「BのCSV」の中から「AのCSV」に存在しない行を探し 2)BのCSVのその行の「A列の値+B列の値」を、再度「AのCSV」から探す という順序で考えてみました。 ------------------------------------ [1]「AのCSV」("D:\hoge\A.CSV")の全文を strCsvA に格納します。 [2]「BのCSV」("D:\hoge\B.CSV")を 1レコード ずつ読み込み、[1] から検索します。 [3] 見つからなかった場合は、今度は、「A列の値+B列の値」だけを [1] から検索します。 [4] [3] の結果が、 ・「見つかった」場合は(C列の値だけ)「一致しない」 ・「見つからなかった」場合は(「A列の値+B列の値」自体が)「存在しない」 という文字列を付して、「別テキスト」("D:\hoge\C.CSV")に書き出します。 ------------------------------------ >VBすくりぷとで考えています。 とのことですので、 ・メモ帳を起動し、下記コード を コピペ します。 ・全角スペース を 半角スペース 2個 に置換します。 ・これを適当な名前で、拡張子「VBS」で保存します。 ・この VBS ファイル を実行します。 以上です。 '----------------------------------- Option Explicit Const ForReading = 1 Const ForWriting = 2 Const ForAppending = 8 Dim objFSO Dim objCsvA, objCsvB, objCsvC Dim strCsvA, strCsvB, strCsvC Dim arrCsvB '//FileSystemObject を使って 値を読み書きします。 Set objFSO = CreateObject("Scripting.FileSystemObject") Set objCsvA = objFSO.OpenTextFile("D:\hoge\A.CSV", ForReading) Set objCsvB = objFSO.OpenTextFile("D:\hoge\B.CSV", ForReading) '//追加書込の場合は、下の「ForWriting」を「ForAppending」に変えてください。 Set objCsvC = objFSO.OpenTextFile("D:\hoge\C.CSV", ForWriting) strCsvA = vbCrLf & objCsvA.ReadAll '[1] Do While objCsvB.AtEndOfStream <> True '[2] strCsvB = vbCrLf & objCsvB.ReadLine arrCsvB = Split(strCsvB, ",") If InStr(strCsvA, strCsvB) = 0 Then If InStr(strCsvA, arrCsvB(0) & "," & arrCsvB(1)) = 0 Then '[3]・[4] objCsvC.writeline """存在しない""," & Replace(strCsvB, vbCrLf, "") Else objCsvC.writeline """一致しない""," & Replace(strCsvB, vbCrLf, "") End If End If Loop objCsvA.Close objCsvB.Close objCsvC.Close Set objCsvA = Nothing Set objCsvB = Nothing Set objCsvC = Nothing Set objFSO = Nothing
お礼
ありがとうございました。 若干レスポンスに問題はありましたが、要件も問題なくクリアしており大変助かりました。 参考になりました
- layy
- ベストアンサー率23% (292/1222)
こういうときは同じく「マッチング」のアルゴリズムなのですが、 質問が出ているということはこれは知らない(=作れない、使ったことない)と解釈します。残念ですが・・・。 <AのCSV>において "AAAAA","BBB","CC" "DDDDD","EEE","FF" "GGGGG","HHH","II" "GGGGG","HHH","II"・・・・・・・・・・確認です、同じものは存在しますか?。 "MMMMM","NNN","OO" エクセルらしくやるには、 "A","AAAAA","BBB","CC" "A","DDDDD","EEE","FF" "A","GGGGG","HHH","II" "A","MMMMM","NNN","OO" "B","AAAAA","BBB","CC" "B","DDDDD","EEE","F8" "B","GGGGG","HHH","II" "B","JJJJJJ","KKK","ll" "B","MMMMM","NNN","OO" として 並べ替える。 "A","AAAAA","BBB","CC" "B","AAAAA","BBB","CC" "A","DDDDD","EEE","FF" "B","DDDDD","EEE","F8" "A","GGGGG","HHH","II" "B","GGGGG","HHH","II" "B","JJJJJJ","KKK","ll"・・・・・・・前の行に"A"がないので重複していない "A","MMMMM","NNN","OO" "B","MMMMM","NNN","OO" 同じ次元にして区別できるものを用意します。 "A""B"と2行になっていれば重複となります。
お礼
ありがとうございました。 参考になりました
- webuser
- ベストアンサー率33% (372/1120)
>ヒントをいただけないでしょうか? では、ヒントだけ。。。 1.比較の処理パターンを「マッチング処理」といいます。検索すれば流れ図などがいくらでも出てくると思います。 2.マッチングするには入力データがソート済である事が前提になります。 3.比較の対象項目の事を「マッチング・キー」と言います。 4.データのキーに重複が無い事を「1対」、重複がある事を「n対」と表現します。 5.「1対1」のマッチングは比較的簡単です。「1対n」や「n対n」になると少し面倒になります。しかし、基本は同じです。 6.「1対1のマッチング処理」とは、ソート済の2つのデータをまずは1件読み、データ1のキーが小さければデータ1を、データ2が小さければデータ2を、同じなら両方を読む、これを両方のデータの最後まで繰り返すという処理です。 その過程で、データ1のみに存在する、データ2のみに存在する、両方に存在するを判定できます。 7.キーが重複する場合、マッチングと同時に「キーブレイク処理」を行う必要があります。 8.入力データがソートされていないなら、「バブルソート」などで、一旦ソート済データにする必要があります。 これが、どんな言語ツールでも通用する、何も無い状態からイチから作る方法です。 既存のオブジェクトを利用して簡易的に作る方法もあります。 表の形式のオブジェクトにCSVのデータを全て読み込ませた後、オブジェクトに搭載された検索機能を用いて検索したりマッチングさせたり、それは使うオブジェクトによって異なります。
お礼
ありがとうございました。 参考になりました
お礼
ありがとうございました。 こういう使い方は思いつきもしませんでした。 要件も問題なくクリアしており大変助かりました。 参考になりました