ここから本文です

VBSの質問です。 a.csvとb.csvを比較して差分があればc.csvに追記していくという...

goo********さん

2018/1/1815:17:17

VBSの質問です。
a.csvとb.csvを比較して差分があればc.csvに追記していくという処理がしたいです。

コードをキーにしてその行の差分を出力する

「a.csv」
コード,氏名(姓),氏名(名),メールアドレス
001,田中,太郎,xxxxx@xxx.jp

「b.csv」
コード,氏名,所属,メールアドレス
001,山田 太郎,総務部,yyyyy@xxx.jp

「c.csv」※差分があればa.csvの値を出力
コード,氏名,メールアドレス

わかりにくくてすみません。
よろしくお願いします。

閲覧数:
121
回答数:
3
お礼:
100枚

違反報告

ベストアンサーに選ばれた回答

nip********さん

2018/1/1908:43:04

なんか投稿できなくなってて。

----------

念のため『a.csvのコードに重複があった場合でも対応できる』と思います。

Dim dic
Dim FSO
Dim PathName
Dim data_a, data_b, data_c
Dim a, b, c, v, key

Set dic = CreateObject("Scripting.Dictionary")
Set FSO = CreateObject("Scripting.FileSystemObject")
' データが保存されているフォルダ
' そちらで修正して下さい
PathName = "D:\test\"
data_a = "a.CSV"
data_b = "b.CSV"
data_c = "c.CSV"

Set b = FSO.OpenTextFile(PathName & data_b, 1)
key = b.ReadLine
Do Until b.AtEndOfStream
v = Split(b.ReadLine, ",")
v(1) = Replace(v(1), " ", ",") ' " "の中は全角ですからね
key = v(0) & "," & v(1) & "," & v(3)
dic.Add key, ""
Loop
b.Close
Set b = Nothing

Set a = FSO.OpenTextFile(PathName & data_a, 1)
Set c = FSO.OpenTextFile(PathName & data_c, 8, True)
key = a.ReadLine
Do Until a.AtEndOfStream
key = a.ReadLine
If Not dic.Exists(key) Then c.WriteLine key
Loop

c.Close
a.Close

Set c = Nothing
Set a = Nothing
Set FSO = Nothing
Set dic = Nothing

返信を取り消しますが
よろしいですか?

  • 取り消す
  • キャンセル

ベストアンサー以外の回答

1〜2件/2件中

並び替え:回答日時の
新しい順
|古い順

zzr********さん

2018/1/1906:05:47

回答はついているようで何ですが。

質問者さんの気にしていた

・氏名(姓),氏名(名) と 氏名 の比較

が漏れているのではないのかな。
個人的には、コードを基に【氏名】と【メアド】が比較対象ではないかなと思ったのですけど・・・

返信を取り消しますが
よろしいですか?

  • 取り消す
  • キャンセル

プロフィール画像

カテゴリマスター

lin********さん

2018/1/1821:33:13

「a.csv」の2行目

001,田中,太郎,xxxxx@xxx.jp

「b.csv」の2行目

001,山田 太郎,総務部,yyyyy@xxx.jp

「コードをキーにして」ということなので、「001」で、一致します。

しかし、それ以外は全く異なりますから、「a.csv」の2行目を、「c.csv」に「追記してゆ」きますが、今回は、「コードが一致して」「メールアドレス(=一番最後の項目)が不一致なら」、「c.csv」に追記してゆきます。

最後に、プログラムの説明をしますので、質問者の環境に合わせてください。

特に、4行目の「f = "D:\Programming\"」は、私の環境のままですので、必ず変更してください。

Option Explicit
Dim a, b, ca, cb, cc, f, m, n, so
Set so = CreateObject("Scripting.FileSystemObject")
f = "D:\Programming\pdf\新しいフォルダー\"
Set ca = so.OpenTextFile(f & "a.csv", 1)
Set cc = so.OpenTextFile(f & "c.csv", 8, True)
m = ca.ReadLine
Do Until ca.AtEndOfStream
n = ca.ReadLine
Set cb = so.OpenTextFile(f & "b.csv", 1)
m = cb.ReadLine
a = Split(n, ",")
Do Until cb.AtEndOfStream
b = Split(cb.ReadLine, ",")
If a(0) = b(0) Then
If a(UBound(a)) <> b(UBound(b)) Then
cc.WriteLine n
Exit Do
End If
End If
Loop
cb.Close
Set cb = Nothing
Loop
ca.Close
cc.Close
Set ca = Nothing
Set cc = Nothing
Set so = Nothing
MsgBox("Finished!")

簡単な説明です。

Option Explicit

「厳密に」とか「明確に」というような意味ですが、このオプションを設定すると、変数は、その使用の前に、必ず「Dim」等によって宣言しておかなければなりません。

Set so = CreateObject("Scripting.FileSystemObject")

ファイルやフォルダを扱えるようにしていますが、今回は特に、「csv」ファイルという、テキストファイルを扱うのにも必要です。

f = "D:\Programming\"

「a.csv」「b.csv」「c.csv」が存在するフォルダを「f」に入れています。

Set ca = so.OpenTextFile(f & "a.csv", 1)

「a.csv」を「読み込み専用(=最後の「1」)」で開いています。

Set cc = so.OpenTextFile(f & "c.csv", 8, True)

「c.csv」を、「追記型(=「8」)」で、「新規作成許可(=「True」)」で開いています。

すなわち、今回が初めてなら、「c.csv」ファイルを新規作成します。

m = ca.ReadLine

「a.csv」を1行読み飛ばしています(項目行)。

Do Until ca.AtEndOfStream

「a.csv」ファイルのファイルの終端まで処理。

n = ca.ReadLine

「a.csv」ファイルから1行読み込んでいます。

Set cb = so.OpenTextFile(f & "b.csv", 1)

「b.csv」ファイルを、「読み込み専用」で開いています。

すなわち、「a.csv」ファイルを1行読み込むごとに、「b.csv」ファイルを開き直しています。

m = cb.ReadLine

「b.csv」ファイルの1行読み飛ばし(項目行)。

a = Split(n, ",")

「a.csv」ファイルで読み込んだ1行(「n」)を、区切り記号(「,」)を使って、配列変数に格納しています。

すなわち、読み込んだ1行が、「001,田中,太郎,xxxxx@xxx.jp」なら、「a(0) = "001"」、「a(1) = "田中"」、「a(2) = "太郎"」、「a(3) = "xxxxx@xxx.jp"」となります。

Do Until cb.AtEndOfStream

「b.csv」のファイルの終端まで処理。

b = Split(cb.ReadLine, ",")

今度も、1行読み込んで、区切り記号を使って配列変数に格納しています。

If a(0) = b(0) Then

「a.csv」と「b.csv」の「コード」が一致したら、

If a(UBound(a)) <> b(UBound(b)) Then

「UBound()」は、配列変数の添え字(「()」)内の数字、最大値を返します。

すなわち、上記の例でいえば、「a(3) = "xxxxx@xxx.jp"」の「3」です。

要するに、項目の個数が違うものの、最初と最後は「コード」と「メールアドレス」と同じ項目なので、それで一致するか調べているのです。

結果的に、「コード」が一致して、「メールアドレス」が不一致なら、となります。

cc.WriteLine n

「c.csv」ファイルに追記しています。

Exit Do

もう、見つかったので、「Do Until cb.AtEndOfStream ~ Loop」から抜け出しています。

End If
End If
Loop

を、「b.csv」について、ファイルの終端まで繰り返しています。

cb.Close
Set cb = Nothing

「b.csv」ファイルを閉じています。

Loop

を、「a.csv」ファイルの終端まで繰り返しています。

ca.Close
cc.Close

「a.csv」、「c.csv」ファイルを閉じています。

Set ca = Nothing
Set cc = Nothing
Set so = Nothing

「Set」で使った変数は、使い終わったあと、「Nothing」で解放しておきます。

MsgBox("Finished!")

最後に、「Finished!」と表示しています。

あわせて知りたい

この質問につけられたタグ

みんなで作る知恵袋 悩みや疑問、なんでも気軽にきいちゃおう!

Q&Aをキーワードで検索:

Yahoo! JAPANは、回答に記載された内容の信ぴょう性、正確性を保証しておりません。
お客様自身の責任と判断で、ご利用ください。
本文はここまでです このページの先頭へ

「追加する」ボタンを押してください。

閉じる

※知恵コレクションに追加された質問は選択されたID/ニックネームのMy知恵袋で確認できます。

不適切な投稿でないことを報告しました。

閉じる