【あるあるbot連動企画】フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?

2つのCSVを比較して一致していないものを検出したいのですがヒントをいただけないでしょうか?

<AのCSV>
"AAAAA","BBB","CC"
"DDDDD","EEE","FF"
"GGGGG","HHH","II"
"MMMMM","NNN","OO"





<BのCSV>
"AAAAA","BBB","CC"
"DDDDD","EEE","F8"
"GGGGG","HHH","II"
"JJJJJJ","KKK","ll"
"MMMMM","NNN","OO"




ベースになるCSVはBのほうです。
まず、
BのCSVの「A列の値+B列の値」がおなじものをAのCSVから探します。
同じものを見つけたらBのCSVの同じ行のC列の値が一致しているか検索します。
一致していなかったら別テキストに書き出します。
また、BのCSVの「A列の値+B列の値」と同じものがAのCSVに存在しなかったら動揺に別テキストに書き出したいのですがどのようにすればいいでしょうか???

VBすくりぷとで考えています。

A 回答 (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
    • good
    • 0
この回答へのお礼

ありがとうございました。
こういう使い方は思いつきもしませんでした。
要件も問題なくクリアしており大変助かりました。
参考になりました

お礼日時:2010/09/14 21:20

●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
    • good
    • 0
この回答へのお礼

ありがとうございました。
若干レスポンスに問題はありましたが、要件も問題なくクリアしており大変助かりました。
参考になりました

お礼日時:2010/09/14 21:21

こういうときは同じく「マッチング」のアルゴリズムなのですが、


質問が出ているということはこれは知らない(=作れない、使ったことない)と解釈します。残念ですが・・・。


<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行になっていれば重複となります。
    • good
    • 0
この回答へのお礼

ありがとうございました。
参考になりました

お礼日時:2010/09/14 21:22

>ヒントをいただけないでしょうか?



では、ヒントだけ。。。

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のデータを全て読み込ませた後、オブジェクトに搭載された検索機能を用いて検索したりマッチングさせたり、それは使うオブジェクトによって異なります。
    • good
    • 0
この回答へのお礼

ありがとうございました。

参考になりました

お礼日時:2010/09/14 21:22

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


おすすめ情報