- ベストアンサー
VLOOKUPを使用した値の照合マクロの作成方法
- VLOOKUP関数を使用してシート1とシート2の値を照合するマクロを作成していますが、判定1、2、3の転記がうまくできない問題があります。
- また、VLOOKUP関数の処理が遅く、速く処理できる方法を探しています。
- シート1のA列、B列、C列の値とシート2のF列、G列、B列の値を連結して照合し、結果に応じてシート2のAF列に1、2、3を転記するマクロの記述方法を教えてください。
- みんなの回答 (15)
- 専門家の回答
質問者が選んだベストアンサー
おはようございます。 見直してみたら無駄な箇所があったので修正しました。 これで同一データで0.4秒でした。 それから「非対称」って、かたっぽが「対象」なら「非対象」じゃないですか? Sub test06() ‘ Dim t As Single ‘ t = Timer Dim myDic As Object Dim myV, myV2, myW, myX, myY Dim i As Long, uw As Long, uv As Long With Sheets("Sheet1") myV = .Range("A2", .Cells(Rows.Count, "C").End(xlUp)).Value End With With Sheets("Sheet2") myW = .Range("B2", .Cells(Rows.Count, "G").End(xlUp)).Value End With uv = UBound(myV) uw = UBound(myW) ReDim myV2(1 To uv, 1 To 1) As String ReDim myX(1 To uw, 1 To 1) As String ReDim myY(1 To uv, 1 To 1) As String Set myDic = CreateObject("Scripting.Dictionary") For i = 1 To uv myV2(i, 1) = myV(i, 1) & "!" & myV(i, 2) & "!" & myV(i, 3) Next i For i = 1 To uw myDic(myW(i, 5) & "!" & myW(i, 6) & "!" & myW(i, 1)) = i myX(i, 1) = "非対象" Next i For i = 1 To uv If Not myDic.Exists(myV2(i, 1)) Then myY(i, 1) = "再発行" Else myX(myDic(myV2(i, 1)), 1) = "対象" End If Next i Application.ScreenUpdating = False Sheets("Sheet2").Range("AF2").Resize(uw, 1).ClearContents Sheets("Sheet2").Range("AF2").Resize(uw, 1).Value = myX Sheets("Sheet1").Range("G2").Resize(uv, 1).ClearContents Sheets("Sheet1").Range("G2").Resize(uv, 1).Value = myY Application.ScreenUpdating = True ‘ Debug.Print Timer - t End Sub
その他の回答 (14)
- ki-aaa
- ベストアンサー率49% (105/213)
補足読みました。 Sheet2のキーの順番が違うのだと思います。 質問では次のように成っています。 >シ-ト2 >B2=1234 >F2=XXXX >G2=5678 >シート1の値=XXXX12345678 >シート2の値=XXXX12345678 それで、Sheet1のきーは、A列→ B列→ C列 それで、Sheet2のきーは、F列→ B列→ G列 このようになっているか、確認してください。 merlionXX さんも同じ質問をやっているんですよね。 回答番号10のtest04を流しました。 まったく違う結果になりましたので、見直してみるとキーの順番が違いました。 それで次のように変更して流すと、同じ結果になりました。 For i = 1 To uw myW2(i, 1) = myW(i, 5) & "-" & myW(i, 1) & "-" & myW(i, 6) Next i では、よろしくお願いします。
お礼
お手数かけました。 どうもありがとうございました。
補足
>このようになっているか、確認してください。 はいそうのとうりです。 お手数かけて申し訳ありません。
- merlionXX
- ベストアンサー率48% (1930/4007)
実際にどれくらい時間がかかるか大量のデータでテストしてみました。 Sheet1に5,000、Sheet2に10,000のデータだとSub test04()のような順列組み合わせでは、いくら配列内の処理でも20秒以上かかってしまい、ストレスを感じますね。 重複するデータがないとわかっているなら、ここはやはり皆さんおやりのようにDictionaryオブジェクトを使わない手はないと痛感しました。 以下のコードでは、同じデータで0.78秒でした。 Sub test05() Dim t As Single t = Timer Dim myDic As Object Dim myV, myV2, myW, myX, myY Dim i As Long, uw As Long, uv As Long With Sheets("Sheet1") myV = .Range("A2", .Cells(Rows.Count, "C").End(xlUp)).Value End With With Sheets("Sheet2") myW = .Range("B2", .Cells(Rows.Count, "G").End(xlUp)).Value End With uv = UBound(myV) uw = UBound(myW) ReDim myV2(1 To uv, 1 To 1) As String ReDim myX(1 To uw, 1 To 1) As String ReDim myY(1 To uv, 1 To 1) As String Set myDic = CreateObject("Scripting.Dictionary") For i = 1 To uv myV2(i, 1) = myV(i, 1) & "/" & myV(i, 2) & "/" & myV(i, 3) Next i For i = 1 To uw myDic(myW(i, 5) & "/" & myW(i, 6) & "/" & myW(i, 1)) = i Next i For i = 1 To uv If Not myDic.Exists(myV2(i, 1)) Then myY(i, 1) = "再発行" Else myX(myDic(myV2(i, 1)), 1) = "対象" End If Next i For i = 1 To uw If myX(i, 1) = Empty Then myX(i, 1) = "非対称" End If Next i Application.ScreenUpdating = False Sheets("Sheet2").Range("AF2").Resize(uw, 1).ClearContents Sheets("Sheet2").Range("AF2").Resize(uw, 1).Value = myX Sheets("Sheet1").Range("G2").Resize(uv, 1).ClearContents Sheets("Sheet1").Range("G2").Resize(uv, 1).Value = myY Application.ScreenUpdating = True Debug.Print Timer - t End Sub
お礼
ありがとうございます。 別のマクロ作成にはまっていて (もうギブアップ) 実験していません。 本日修正版がupされてましたので そちらで実験いたします。
補足
end-uさんの修正版は1秒かからなかったです。 ki-aaaさんの記述も1秒かからなかったです。 ki-aaaさんの物は私の説明が悪く誤処理でしたが 今修正版をくれました。 多分、修正版も1秒以内は変わらないと思います。 merlionXXさんも修正版をくれました。 これも1秒以内となるとどれを使用しても いいのですね。 お手数かけました。 あれっ。お座敷だったのでは? お忙しいのにすいません。
- ki-aaa
- ベストアンサー率49% (105/213)
補足、ありがとうございます。 意図したものと違う結果が出るデータは大量にあるのでしょうか。 テストデータではうまく行ったのでしょうか。 後考えられるのは、データの型の問題かな・・・。 問題のあるデータをプリントしてみる他ないかな。方法は下に書きます。 '*****ここから '*****ここまで を追加する。 データを目視で調べる。 Set dic = Nothing '*****ここから 'Sheet1の問題のあるデータが、100行目にあったら i = 100 - 1 Debug.Print "@abc @" & a_b_c(i, 1) & a_b_c(i, 2) & a_b_c(i, 3) 'それに対応するSheet2の問題データが220行にあったら i = 220 - 1 Debug.Print "@fbg @" & f_g(i, 1) & b_b(i, 1) & f_g(i, 2) '*****ここまで End Sub この質問とは関係ないですが end-uさんの書かれた、一定間隔で実行する方法も 使っています。感謝しています。
お礼
ありがとうございます。すいません。 説明が下手ですいません。(かえって混乱したらすいません。) シート1(シート2) A列(B列)→型番10桁 B列(F列)→仕入先コード4桁 C列(G列)→メーカーコード4桁 です。 ですから本来、シート1のA列とシート2のB列を照合させればいいのですが 同じ型番でも仕入先が違う、メーカーが違う場合があるので それだけだと重複行が発生します。 AAAAAAAAAA 1111 1111 AAAAAAAAAA 1111 2222 AAAAAAAAAA 3333 1111 これらはA列(B列)が同じでも違う物としてそれぞれ照合したいのです。 で、教えていただいた記述では AAAAAAAAAA 1111 1111の場合 は問題ありません。 AAAAAAAAAA 1111 2222 や AAAAAAAAAA 3333 1111 の時に駄目なのです。 型番ではなく 仕入先コードの4桁と メーカーコードの4桁が違う場合です。 シート1もシート2にも AAAAAAAAAA 1111 2222 があれば同じ値とみなすので、 シート2のAF列には1が転記のはずですが 2(シート1にはない)と転記され シート1のG列は空白のはずが 3(シート2には無い)と転記されます。 5,000行の中で4,000行くらいが このパターン(仕入先とメーカーコードが相違する)の為、 ほとんど駄目でした。 正規の状態例 シート1 AAAAAAAAAA 1111 1111→シート2にある→G列は空白 AAAAAAAAAA 1111 2222→シート2にある→G列は空白 BBBBBBBBBB 2222 2222→シート2にある→G列は空白 CCCCCCCCCC 1111 5555→シート2にない→G列は3 DDDDDDDDDD 6666 6666→シート2にない→G列は3 シート2 AAAAAAAAAA 1111 1111→シート1にある→AF列は1 AAAAAAAAAA 1111 2222→シート1にある→AF列は1 BBBBBBBBBB 2222 2222→シート1にある→AF列は1 EEEEEEEEEE 1111 3333→シート2にない→AF列は2 ↓現在 ●印部分が間違い判定 シート1 AAAAAAAAAA 1111 1111→シート2にある→G列は空白 AAAAAAAAAA 1111 2222→シート2にある→G列は空白→3● BBBBBBBBBB 2222 2222→シート2にある→G列は空白 CCCCCCCCCC 1111 5555→シート2にない→G列は3 DDDDDDDDDD 6666 6666→シート2にない→G列は3 シート2 AAAAAAAAAA 1111 1111→シート1にある→AF列は1 AAAAAAAAAA 1111 2222→シート1にある→AF列は1→2● BBBBBBBBBB 2222 2222→シート1にある→AF列は1 EEEEEEEEEE 1111 3333→シート2にない→AF列は2
- end-u
- ベストアンサー率79% (496/625)
>またシート1ですが >シート1にもシート2にもある物の行以降で >シート2に無い物の行があると、この3の転記の判定をしません。 失礼。 >Sheets("Sheet1").Range("G1").Resize(mx).Value = w この箇所、以下に修正必要です。 Sheets("Sheet1").Range("G1").Resize(UBound(w)).Value = w また、照合結果を文字列にするなら 書き出し用配列の型をString型かVariant型に修正しなければいけません。 Dim w() As String Dim x() As String >まずいです。 1行目か2行目かの違いについては気づいてたのですが、 そこも修正回答必要ですか? そこくらいは自分で修正できないと、 そのマクロは使えないんじゃないかと思いますけど。 失敗してもいいように、コピーしたファイルで色々試してみないと身につかないのでは。 Q6327342では自分で変更したりして、応用されてましたよね。
お礼
>>Sheets("Sheet1").Range("G1").Resize(mx).Value = w >この箇所、以下に修正必要です。 >Sheets("Sheet1").Range("G1").Resize(UBound(w)).Value = w これで正しく動きました。 >また、照合結果を文字列にするなら >書き出し用配列の型をString型かVariant型に >修正しなければいけません。 ありがとうございます。 >そこくらいは自分で修正できないと 申し訳ありません。(泣) 教えていただいた記述の書換恐怖症になっています。(泣) 本当にごめんなさい(泣) Sheets("Sheet1").Range("G1").Resize(UBound(w)).Value = w Sheets("Sheet2").Range("AF1").Resize(mx).Value = x この部分が結果を転記する部分ですよね。 ここを Sheets("Sheet1").Range("G2").Resize(UBound(w)).Value = w Sheets("Sheet2").Range("AF2").Resize(mx).Value = x にしたら 転記開始行は2行目になりましたが1行目の照合結果が 2行目に転記され、結果1行づつずれてデータの無い 最終行からもう1行目にも転記されていました。 という事は 配列をLoopして3つのキーを連結した文字列をDictionaryで照合 した時点ですでにしなくていい1行目の照合結果が 登録されたのだと思い、どこでそれがされているか? 'A列にデータがある範囲を取得し、右に3列広げる。 v = .Range("A1", .Range("A65536").End(xlUp)).Resize(, 3).Value End With 'B列にデータがある範囲を取得し、右に6列広げる。 v = .Range("B1", .Range("B65536").End(xlUp)).Resize(, 6).Value End With ここだと思い、 v = .Range("A2", .Range("A65536").End(xlUp)).Resize(, 3).Value End With 'B列にデータがある範囲を取得し、右に6列広げる。 v = .Range("B2", .Range("B65536").End(xlUp)).Resize(, 6).Value としたら正しく動作しました。 どうもありがとうございました。
補足
シート1が約5,300行 シート2が約5,700行 で1秒かかりませんでした。 どうもありがとうございます。
- merlionXX
- ベストアンサー率48% (1930/4007)
おや、追加リクエストがあったんですね、気づきませんでした。 > また上記の推測もあっていますでしょうか? > 数字は下手に書き換えると行数や列数やセル位置を > 示す場合もあり、怖いです。 ならばテストデータで試してみたらいかがでしょう? こちらもあなたの質問に答えるためにテストデータをわざわざ作成してるのです。 ま、一応回答しておきますね。 今日はなんとお昼からお座敷がかかっています(笑) Sub test04() Dim myV, myV2, myW, myW2, myX, myY Dim i As Long, n As Long, uw As Long, uv As Long With Sheets("Sheet1") myV = .Range("A2", .Cells(Rows.Count, "C").End(xlUp)).Value End With With Sheets("Sheet2") myW = .Range("B2", .Cells(Rows.Count, "G").End(xlUp)).Value End With uv = UBound(myV) uw = UBound(myW) ReDim myV2(1 To uv, 1 To 1) ReDim myW2(1 To uw, 1 To 1) ReDim myX(1 To uw, 1 To 1) ReDim myY(1 To uv, 1 To 1) For i = 1 To uv myV2(i, 1) = myV(i, 1) & "-" & myV(i, 2) & "-" & myV(i, 3) Next i Erase myV For i = 1 To uw myW2(i, 1) = myW(i, 5) & "-" & myW(i, 6) & "-" & myW(i, 1) Next i Erase myW For i = 1 To uv For n = 1 To uw If myV2(i, 1) = myW2(n, 1) Then myX(n, 1) = "対象" myY(i, 1) = "ダミー" End If Next n Next i Erase myV2, myW2 For n = 1 To uw If myX(n, 1) = Empty Then myX(n, 1) = "非対称" End If Next n For n = 1 To uv If myY(n, 1) = Empty Then myY(n, 1) = "再発行" Else myY(n, 1) = Empty '"ダミー"の消去 End If Next n Sheets("Sheet2").Range("AF2").Resize(uw, 1).Value = myX Sheets("Sheet1").Range("G2").Resize(uv, 1).Value = myY Erase myX, myY End Sub
お礼
漢字でいれてもらって、 私の予想とは全然違いました。 どうもありがとうございました。
補足
>ならばテストデータで試してみたらいかがでしょう? >こちらもあなたの質問に答えるためにテストデータを >わざわざ作成してるのです。 本当にごめんなさい。 いつもテストデータで試して駄目だと質問しますが 今回はテストデータで試す所までいけませんでした。 1の転記が分からなくて。(泣) えっつ。お昼から.....(゜o゜) 今別の物もやっていて、 万歳になったらスレッドを立ち上げようと思いましたが 月曜にします。........(-_-;) ずうずうしくてすいません。m(__)m
- merlionXX
- ベストアンサー率48% (1930/4007)
gx9wxさん、おはようございます。 昨夜のコードで成功してよかった。そうですか、1秒かかりませんでしたか。 ところで、Sheet1のA、B、C列の結合データと、Sheet2のF、G、B列の結合データのマッチングをやったわけですが、こんなケースはありますか? 例 Sheet1のA、B、C列→AAA + BBB + CCC Sheet2のF、G、B列→A + AABB + BCCC つまり、それぞれの列ではまったく違うデータなのに、結合させると同じになってしまうケースです。 end-uさんの、その点をちゃんと手当てしているコードをみて、はたと気づきました。 わたしのコードだと、それは想定外なので同じと判定してしまいます。 一応、気になったので修正しておきます。 ついでに何度もUboundの同じ計算をさせていたのを uv = UBound(myV) uw = UBound(myW) と、変数に代入して一度で済ませるようにしました。 Sub test03() Dim myV, myV2, myW, myW2, myX, myY Dim i As Long, n As Long, uw As Long, uv As Long With Sheets("Sheet1") myV = .Range("A2", .Cells(Rows.Count, "C").End(xlUp)).Value End With With Sheets("Sheet2") myW = .Range("B2", .Cells(Rows.Count, "G").End(xlUp)).Value End With uv = UBound(myV) uw = UBound(myW) ReDim myV2(1 To uv, 1 To 1) ReDim myW2(1 To uw, 1 To 1) ReDim myX(1 To uw, 1 To 1) ReDim myY(1 To uv, 1 To 1) For i = 1 To uv myV2(i, 1) = myV(i, 1) & "-" & myV(i, 2) & "-" & myV(i, 3) Next i Erase myV For i = 1 To uw myW2(i, 1) = myW(i, 5) & "-" & myW(i, 6) & "-" & myW(i, 1) Next i Erase myW For i = 1 To uv For n = 1 To uw If myV2(i, 1) = myW2(n, 1) Then myX(n, 1) = 1 myY(i, 1) = 4 End If Next n Next i Erase myV2, myW2 For n = 1 To uw If myX(n, 1) = Empty Then myX(n, 1) = 2 End If Next n For n = 1 To uv If myY(n, 1) = Empty Then myY(n, 1) = 3 Else myY(n, 1) = Empty End If Next n Sheets("Sheet2").Range("AF2").Resize(uw, 1).Value = myX Sheets("Sheet1").Range("G2").Resize(uv, 1).Value = myY Erase myX, myY End Sub
お礼
ありがとうございました。 シート2が10,000行、シート1が5,000行で 20秒かかります。 シート1の5,000行のうち半分くらいが3です。 現在思ったとおり動作するのがmerlionXXさんの記述だけの為 これでいきます。 ちなみにVLOOKUPでは5~10分なので 20秒はかなり早いです。
補足
>Sheet1のA、B、C列→AAA + BBB + CCC >Sheet2のF、G、B列→A + AABB + BCCC >つまり、それぞれの列ではまったく違うデータなのに、結合させると同じになって>しまうケースです。 すいません。ありがとうございます。 そういうケースは絶対ないです。 それぞれ固定長です。 また各列値の役割が違うので 絶対無いです。 >ついでに何度もUboundの同じ計算をさせていたのを > uv = UBound(myV) > uw = UBound(myW) >と、変数に代入して一度で済ませるようにしました。 3,000行くらいだと秒速ですが 10,000行くらいだと20秒かかっています。 03で速くなるか試します。
- ki-aaa
- ベストアンサー率49% (105/213)
試してもらって、ありがとう。 回答の修正と補足 >.Range("AE2:AF" & 行).ClearContents ↓ .Range("AF2:AF" & 行).ClearContents >'*****これ以下はSheet2に有り、Sheet1に無いものを探す。 ↓ '*****これ以下はSheet1に有り、Sheet2に無いものを探す。 >.Range("AE2:AF" & UBound(a_b_c) + 1).ClearContents >.Range("AF2:AF" & UBound(a_b_c) + 1).Value = a_f_1 ↓ .Range("G2:G" & UBound(a_b_c) + 1).ClearContents .Range("G2:G" & UBound(a_b_c) + 1).Value = a_f_1
お礼
わざわざすいません。 テストは シート1が8行、シート2が6行で行いました。 1,2,3全て思ったとおり正しく転記されました。 で本番環境、 シート1が3,500行、シート2が2,500行でしたが 1秒かかりません。 これから20,000行クラスで挑戦します。 どうもありがとうございました。
補足
申し訳ありません。 テストデータのパターンは シート1 A2=AAAA B2=1234 C2=1234 シ-ト2 B2=1234 F2=AAAA G2=1234 シート1の値=AAAA12341234 シート2の値=AAAA12341234 ↓(一致なので) シート2のセルAF2に1と転記 でうまくいったのですが以下のような場合 シート1 A2=XXXX B2=1234 C2=5678 シ-ト2 B2=1234 F2=XXXX G2=5678 シート1の値=XXXX12345678 シート2の値=XXXX12345678 照合すると一致なので ↓ シート2のセルAF2に1と転記のはずが 2と転記され、かつ シート1のG2は空白のはずが3と転記されます。 シート1にあってシート2に無い場合の シート1のG列に3と転記は問題ないのですが シート1にもシート2にも有る場合で上記のパターンの時 が駄目でした。 速度は20,000行でも1秒かかってません。
- merlionXX
- ベストアンサー率48% (1930/4007)
> その場合はシート1のG列に3と記入したいです。 こんばんは。 もう回答が出揃っているようですが、補足をいただきましたので、それをうけて再回答します。 Sub test02() Dim myV, myV2, myW, myW2, myX, myY Dim i As Long, n As Long With Sheets("Sheet1") myV = .Range("A2", .Cells(Rows.Count, "C").End(xlUp)).Value End With With Sheets("Sheet2") myW = .Range("B2", .Cells(Rows.Count, "G").End(xlUp)).Value End With ReDim myV2(1 To UBound(myV), 1 To 1) ReDim myW2(1 To UBound(myW), 1 To 1) ReDim myX(1 To UBound(myW), 1 To 1) ReDim myY(1 To UBound(myV), 1 To 1) For i = 1 To UBound(myV2) myV2(i, 1) = myV(i, 1) & myV(i, 2) & myV(i, 3) Next i Erase myV For i = 1 To UBound(myW2) myW2(i, 1) = myW(i, 5) & myW(i, 6) & myW(i, 1) Next i Erase myW For i = 1 To UBound(myV2) For n = 1 To UBound(myW2) If myV2(i, 1) = myW2(n, 1) Then myX(n, 1) = 1 myY(i, 1) = 4 End If Next n Next i Erase myV2, myW2 For n = 1 To UBound(myX) If myX(n, 1) = Empty Then myX(n, 1) = 2 End If Next n For n = 1 To UBound(myY) If myY(n, 1) = Empty Then myY(n, 1) = 3 Else myY(n, 1) = Empty End If Next n Sheets("Sheet2").Range("AF2").Resize(UBound(myX), 1).Value = myX Sheets("Sheet1").Range("G2").Resize(UBound(myY), 1).Value = myY Erase myX, myY End Sub
お礼
完璧です。 テストは シート1が8行、シート2が6行で行いました。 1,2,3全て思ったとおり正しく転記されました。 で本番環境、 シート1が3,500行、シート2が2,500行でしたが 1秒かかりません。 あのめちゃくちゃな質問に対応していただき 感謝いたしております。 どうもありがとうございました。
補足
わがままですいません。 1→対象 2→非対称 3→再発行 に変更しようと思い If myX(n, 1) = Empty Then myX(n, 1) = 2 End If Next n For n = 1 To UBound(myY) If myY(n, 1) = Empty Then myY(n, 1) = 3 を If myX(n, 1) = Empty Then myX(n, 1) = "非対称" End If Next n For n = 1 To UBound(myY) If myY(n, 1) = Empty Then myY(n, 1) = "再発行" なのかなと推測していますが 1と転記する1に該当するがどこなのかわかりません。 また上記の推測もあっていますでしょうか? 数字は下手に書き換えると行数や列数やセル位置を 示す場合もあり、怖いです。 1,2,3を変更するのはユーザーリクエストですが 私も記述を理解するのに 1,2,3より漢字名称の方がいいなあと思いました。 お手数おかけします。m(__)m PS 今日は週末ですがお座敷でしょうか.....
- end-u
- ベストアンサー率79% (496/625)
Sub try() Dim dic As Object 'Scripting.Dictionary Dim s As String '文字列連結用 Dim mx As Long '配列添字最大値 Dim i As Long Dim v As Variant '取得用配列 Dim w() As Variant 'Sheet1書き出し用 Dim x() As Long 'Sheet2書き出し用 Set dic = CreateObject("Scripting.Dictionary") '"Sheet1"の範囲を配列に取得 With Sheets("Sheet1") 'A列がデータ有無判定基準の場合。 'A列にデータがある範囲を取得し、右に3列広げる。 v = .Range("A1", .Range("A65536").End(xlUp)).Resize(, 3).Value End With '配列をLoopして3つのキーを連結した文字列をDictionaryに登録。 'と同時に同サイズのLong型配列に 3 を入れる。 'dicのitemには配列の位置を記録しておく。 mx = UBound(v) ReDim w(1 To mx, 1 To 1) For i = 1 To mx s = v(i, 1) & "|" & v(i, 2) & "|" & v(i, 3) dic(s) = i w(i, 1) = 3 Next '"Sheet2"の範囲を配列に取得 With Sheets("Sheet2") 'B列がデータ有無判定基準の場合。 'B列にデータがある範囲を取得し、右に6列広げる。 v = .Range("B1", .Range("B65536").End(xlUp)).Resize(, 6).Value End With '配列をLoopして3つのキーを連結した文字列をDictionaryで照合。 '同サイズのLong型配列に判定結果を入れる。 mx = UBound(v) ReDim x(1 To mx, 1 To 1) For i = 1 To mx s = v(i, 5) & "|" & v(i, 6) & "|" & v(i, 1) If dic.Exists(s) Then '登録があればSheet2側の配列xに 1 をセット。 x(i, 1) = 1 '3を入れてあるSheet1側の配列wに Empty をセット。 'wへのセット位置は dic(s)のitemに記録ずみ。 w(dic(s), 1) = Empty Else x(i, 1) = 2 End If Next Sheets("Sheet1").Range("G1").Resize(mx).Value = w Sheets("Sheet2").Range("AF1").Resize(mx).Value = x Erase w, x Set dic = Nothing End Sub Dictionaryの理解の前に、配列処理に対して理解しておいたほうが良かったですね。 Variant型変数に v = Range(連続した複数範囲).Value などのように セル複数範囲の値を入れると2次元配列になります。 この時、配列のインデックスは1から始まります。 2次元配列に関しては、メモリ上にあるセル範囲のようなものを想像してください。 Sheet2の場合は ~~~~~~ v = .Range("B1", .Range("B65536").End(xlUp)).Resize(, 6).Value v(1, 1)にB1セル、v(2, 1)にC1セル、v(3, 1) にD1セルの値が入っています。 この時の(1, 1)というのがアドレスみたいなもので、 それによって配列(メモリ上の矩形範囲)のどの場所かを指定するわけです。 Loop内の s = v(i, 5) & "|" & v(i, 6) & "|" & v(i, 1) この処理で、タテ方向i番目のヨコ方向 5,6,1 列の値、 つまりF,G,B列の値を連結してます。
お礼
ありがとうございます。 配列処理の事を教えていただいて ありがとうございます。 でも、まだよくわかりません。 あと結果なのですが (スレッド最初の質問内容が悪くてすいません) まずシート2ですが AF列の1行目セルAF1に2と転記されます。 データは2行目からなので、ここに2と転記ではまずいです。 シート1には有ってシート2には無い場合 シート1のG列に3と転記ですが 同じくG列1行目セルG1に3と転記されます。 データは2行目からなので、ここに3と転記ではまずいです。 またシート1ですが シート1にもシート2にもある物の行以降で シート2に無い物の行があると、この3の転記の判定をしません。 シート1 2行目シート2にない→シート1のG2に3と転記 3行目シート2にない→シート1のG3に3と転記 4行目シート2に有る→シート2のAF4に1と転記 シート1のG4は空白 5行目シート2に有る→シート2のAF5に1と転記 シート1のG5は空白 6行目シート2にない→シート1のG6に3と転記のはずが空白 7行目シート2にない→シート1のG6に3と転記のはずが空白
- ki-aaa
- ベストアンサー率49% (105/213)
間違いがありました。 >.Range("AE2:AF" & UBound(a_b_c) + 1).ClearContents ↓ .Range("AF2:AF" & UBound(a_b_c) + 1).ClearContents
お礼
ありがとうございます。 こちらで試しました。 私の質問の不備である A-NO.3の補足の 以下の内容が駄目でした。 >>3.「シート1には有るがシート2には無い場合は >>シート2のAF列に3と記入」 >>としているが、 >>いったいSheet2のどの行に入れさせるおつもりなのか? >申し訳ありません。出来るわけ有りませんでした。 >その場合はシート1のG列に3と記入したいです。
- 1
- 2
お礼
Sub test04()と比べました。 Sub test04()→25秒 Sub test06()→1秒以内 また結果も双方同じでした。 ありがとうございました。
補足
はははは。(笑) >「非対称」って、かたっぽが「対象」なら「非対象」 私の誤記は永久に直りません。(ToT)/~~~ 見直してもその時はおかしいと思わない? 投稿後読み直すと気がつきます。 もしくは指摘されてから。 いつもすいません。