プロが教えるわが家の防犯対策術!

【VBA EXCEL データ有無 行 判定】

エクセルの勉強をしていて行き詰まってしまったので相談させて下さい。

大まかな概要としては、シートAにあるデータがシートBにあればシートAのD列に○、なければ×と、出力する処理をしたいです。

シートAにあるデータがシートBにあるかただ検索して判定するのであれば自分で関数などを使用し処理ができたのですが、
①両シートのデータ数は毎回可変
②シートAにあるデータが必ずしもシートBにあるとは限らない
③データ数が膨大
④シートBには重複するデータもある
なことから処理方法がわからず完全に手が止まっている状況です。


<シートA>
A列 B列 C列 D列
りんご 青森 300 ○
りんご 青森 400 ○
りんご 岩手 500 ×
みかん 山形 1000 ○
みかん 山形 5000 ×

<シートB>
A列 B列 C列
りんご 青森 300
りんご 青森 400
りんご 岩手 400
みかん 山形 1000
ぶどう 山梨 500
ぶどう 山形 1000



みかん 山形 500


うまく説明が出来ず大変申し訳ありませんが、お助けいただけないでしょうか。
周りにスキルのある方がおらず、自力で学習するしかありません。
不足部分については補足させて頂きますのでどうぞよろしくお願い致します。

A 回答 (6件)

No.1・2です。



No.1の件について・・・
↓の画像のように「B」シートのD列に通番が入っているというコトでしょうか?
そして「A」シートの「○」の行のE列にその通番を表示したい!と解釈しました。

VBAでやってみました。
「A」シートのデータ数が最大300件程度というコトなので今回はループさせる方法です。
前回のコードは消去し、↓のコードにしてみてください。

Sub Sample2()
Dim i As Long, lastRow1 As Long, lastRow2 As Long
Dim c As Range, myStr As String, wS As Worksheet
Set wS = Worksheets("B")
Application.ScreenUpdating = False
lastRow2 = wS.Cells(Rows.Count, "A").End(xlUp).Row
wS.Range("E:E").Insert
Range(wS.Cells(2, "E"), wS.Cells(lastRow2, "E")).Formula = "=A2&B2&C2"
With Worksheets("A")
lastRow1 = .Cells(Rows.Count, "A").End(xlUp).Row
Range(.Cells(2, "D"), .Cells(lastRow1, "E")).ClearContents
For i = 2 To .Cells(Rows.Count, "A").End(xlUp).Row
myStr = .Cells(i, "A") & .Cells(i, "B") & .Cells(i, "C")
Set c = wS.Range("E:E").Find(what:=myStr, LookIn:=xlValues, lookat:=xlWhole)
If c Is Nothing Then
.Cells(i, "D") = "×"
Else
With .Cells(i, "D")
.Value = "○"
.Offset(, 1) = c.Offset(, -1)
End With
End If
Next i
End With
wS.Range("E:E").Delete
Application.ScreenUpdating = True
MsgBox "完了"
End Sub

こんな感じではどうでしょうか?m(_ _)m
「【VBA EXCEL データ有無 行 判」の回答画像5
    • good
    • 1
この回答へのお礼

作ってくださったんですね、ありがとうございます。

作ってくださったイメージそのものです。

お手数おかけしますが教えていただけるととてもうれしいです。
よろしくお願い致します。

お礼日時:2017/10/04 11:12

続けてお邪魔します。



>作ってくださったイメージそのものです
というコトなので解決ではないのでしょうか?

>教えていただけるととてもうれしいです。
>よろしくお願い致します。

とは何をお答えすれば良いのかちょっと判りかねます。

① VBAそのものの操作方法
② コードの意味

①の場合は基本的なコトなので、
失礼にあたると思いNo.2に「標準モジュールにしてください。」としか記載していません。

②VBAのコードそのものの説明が必要なのでしょうか?

などが判ればお答えできる範囲で可能です。m(_ _)m
    • good
    • 0
この回答へのお礼

アプリで確認していたため、続きの表示があるにも関わらず確認が漏れておりました。

詳しく教えてくださり、また何度もお答えをありがとうございました。

教えていただいたコードを応用して、作成シートで実施したところ望む処理ができました。

tom04さんのお力添えのお陰です。
ご親切に本当にありがとうございました。
大変助かりました。

お礼日時:2017/10/04 18:48

>シートAで最大300件程度です。


>シートBはちなみに1500件程度です。
それならNo2のかたの方法で問題ないかと思います。
データが10万行以上であれば、他の方法を提示するつもりでしたが、そこまでのデータ量ではないので、No2の方の方法を採用してください。
    • good
    • 0
この回答へのお礼

かしこまりました。
ご教授ありがとうございます。
大変助かりました。

お礼日時:2017/10/03 22:54

「データ数が膨大」とのことですが、シートAでおよそ何行ありますか。

    • good
    • 0
この回答へのお礼

回答ありがとうございます。

シートAで最大300件程度です。
シートBはちなみに1500件程度です。

お礼日時:2017/10/03 22:23

No.1です。



どうも失礼しました。
VBAでの方法をご希望なのですね?

ループする方法もありますが、データ量が膨大!というコトですので
ワークシート関数を使う方法にしてみました。
尚、両シートとも1行目は項目行でデータは2行目以降にあるという前提です。
標準モジュールにしてください。

Sub Sample1()
Dim lastRow1 As Long, lastRow2 As Long, wS As Worksheet
Set wS = Worksheets("B")
Application.ScreenUpdating = False
lastRow2 = wS.Cells(Rows.Count, "A").End(xlUp).Row
wS.Range("D:D").Insert
Range(wS.Cells(2, "D"), wS.Cells(lastRow2, "D")).Formula = "=A2&B2&C2"
With Worksheets("A")
lastRow1 = .Cells(Rows.Count, "A").End(xlUp).Row
With Range(.Cells(2, "D"), .Cells(lastRow1, "D"))
.Formula = "=IF(COUNTIF(B!D:D,A2&B2&C2),""○"",""×"")"
.Value = .Value
End With
End With
wS.Range("D:D").Delete
Application.ScreenUpdating = True
End Sub

※ シート名は「A」と「B」にしています。
こんな感じではどうでしょうか?m(_ _)m
    • good
    • 1
この回答へのお礼

ご回答ありがとうございます。
こんなに早くお答えがもらえると思っていなかったのでとても驚いています。

ありがとうございます。
頂いた回答を参考に明日一度やってみます。

また分からなければご質問させていただけると幸いです。( ; _ ; )

お礼日時:2017/10/03 22:01

こんばんは!



シートBは「Sheet2」とし、シートAの1行目は項目行でデータは2行目以降にあるとします。
D2セルに
=IF(COUNTIFS(Sheet2!A:A,A2,Sheet2!B:B,B2,Sheet2!C:C,C2),"○","×")
という数式を入れフィルハンドルでダブルクリックしてみてください。

※ データ量が極端に多く、上記数式では計算速度が遅い場合は
作業用の列を設けた方が良いかもしれません。m(_ _)m
    • good
    • 0
この回答へのお礼

何度もすみません。
追加でご質問させてください。

シートAのE列に、(シートBのD列に実際はある)見つかったシートBデータの通番をシートAのE列に振るとすれば、offsetを使用すればいいのでしょうか??

お礼日時:2017/10/04 07:16

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