
シート1には
A~F列まで値があり、行数は都度相違し約15,000行くらい。
データは2行目から開始です。
シート2には
A~AE列まで値があり、行数は都度相違し約5,000~25,000行
あり同じくデータは2行目からです。
シート1の行ごとに
A列,B列,C列の順で連結した値と
シート2の行ごとに
F列,G列,B列の順で連結した値を
照合させます。
その値が
(1)シート1にもシート2にもある場合は
シート2のAF列に1と転記
(2)シート1には無いがシート2にはある場合は
シート2のAF列に2と転記
(3)シート1には有るがシート2には無い場合は
シート2のAF列に3と記入
シート2のデータのある行まで
作業を繰り返すマクロの記述を教えてください。
VLOOKUPを使用したマクロを作成しましたが
判定1,2,3の転記がうまく出来ないのと
VLOOKUPが重すぎて処理が遅すぎるので
速く処理が出来るとうれしいです。
例
シート1
A2=XXXX
B2=1234
C2=5678
シ-ト2
B2=1234
F2=XXXX
G2=5678
シート1の値=XXXX12345678
シート2の値=XXXX12345678
照合する
↓(一致なので)
シート2のセルAF2に1と転記
No.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
この回答への補足
はははは。(笑)
>「非対称」って、かたっぽが「対象」なら「非対象」
私の誤記は永久に直りません。(ToT)/~~~
見直してもその時はおかしいと思わない?
投稿後読み直すと気がつきます。
もしくは指摘されてから。
いつもすいません。
Sub test04()と比べました。
Sub test04()→25秒
Sub test06()→1秒以内
また結果も双方同じでした。
ありがとうございました。
No.14
- 回答日時:
補足読みました。
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
では、よろしくお願いします。
No.13
- 回答日時:
実際にどれくらい時間がかかるか大量のデータでテストしてみました。
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
この回答への補足
end-uさんの修正版は1秒かからなかったです。
ki-aaaさんの記述も1秒かからなかったです。
ki-aaaさんの物は私の説明が悪く誤処理でしたが
今修正版をくれました。
多分、修正版も1秒以内は変わらないと思います。
merlionXXさんも修正版をくれました。
これも1秒以内となるとどれを使用しても
いいのですね。
お手数かけました。
あれっ。お座敷だったのでは?
お忙しいのにすいません。
ありがとうございます。
別のマクロ作成にはまっていて
(もうギブアップ)
実験していません。
本日修正版がupされてましたので
そちらで実験いたします。
No.12
- 回答日時:
補足、ありがとうございます。
意図したものと違う結果が出るデータは大量にあるのでしょうか。
テストデータではうまく行ったのでしょうか。
後考えられるのは、データの型の問題かな・・・。
問題のあるデータをプリントしてみる他ないかな。方法は下に書きます。
'*****ここから '*****ここまで を追加する。
データを目視で調べる。
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
No.11
- 回答日時:
>またシート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
としたら正しく動作しました。
どうもありがとうございました。
No.10
- 回答日時:
おや、追加リクエストがあったんですね、気づきませんでした。
> また上記の推測もあっていますでしょうか?
> 数字は下手に書き換えると行数や列数やセル位置を
> 示す場合もあり、怖いです。
ならばテストデータで試してみたらいかがでしょう?
こちらもあなたの質問に答えるためにテストデータをわざわざ作成してるのです。
ま、一応回答しておきますね。
今日はなんとお昼からお座敷がかかっています(笑)
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
No.9
- 回答日時:
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
この回答への補足
>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で速くなるか試します。
ありがとうございました。
シート2が10,000行、シート1が5,000行で
20秒かかります。
シート1の5,000行のうち半分くらいが3です。
現在思ったとおり動作するのがmerlionXXさんの記述だけの為
これでいきます。
ちなみにVLOOKUPでは5~10分なので
20秒はかなり早いです。
No.8
- 回答日時:
試してもらって、ありがとう。
回答の修正と補足
>.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
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秒かかってません。
わざわざすいません。
テストは
シート1が8行、シート2が6行で行いました。
1,2,3全て思ったとおり正しく転記されました。
で本番環境、
シート1が3,500行、シート2が2,500行でしたが
1秒かかりません。
これから20,000行クラスで挑戦します。
どうもありがとうございました。
No.7
- 回答日時:
> その場合はシート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→対象
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 今日は週末ですがお座敷でしょうか.....
完璧です。
テストは
シート1が8行、シート2が6行で行いました。
1,2,3全て思ったとおり正しく転記されました。
で本番環境、
シート1が3,500行、シート2が2,500行でしたが
1秒かかりません。
あのめちゃくちゃな質問に対応していただき
感謝いたしております。
どうもありがとうございました。
No.6
- 回答日時:
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と転記のはずが空白
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Visual Basic(VBA) vbaエクセルマクロ RemoveDuplicatesについて RemoveDuplicatesを使 3 2023/02/28 01:13
- Excel(エクセル) Excelで、別シートの表のステータスに伴った動的な自動転記をしたいです。 2 2023/06/14 15:56
- Excel(エクセル) Excel_マクロ_複数のシートのVLOOKUPで表示された#N/A以外に色付けをしたいです 1 2023/02/16 22:37
- Visual Basic(VBA) VBAで、シート間の転記するコードをFOR~NEXTで教えてください。 9 2023/04/30 20:04
- その他(Microsoft Office) エクセルマクロ オートフィルターでで選択コピー 2 2022/04/18 11:05
- Visual Basic(VBA) VBAで、1つのエクセルで、2つのシートからもう1つのシートに条件のある転記コードを教えてください。 1 2023/03/16 18:07
- Visual Basic(VBA) vbaエクセルマクロ RemoveDuplicatesについて RemoveDuplicatesを使 1 2023/02/27 22:21
- Visual Basic(VBA) まとめシートから集計シートへA列のコードが一致したら1行コピーするマクロをネット上で見つけました。こ 1 2022/08/30 14:11
- Visual Basic(VBA) 顧客ごとに違う点検案内を作成するマクロ 4 2022/09/16 05:34
- Excel(エクセル) エクセル VBA セルの結合 2 2022/09/07 11:48
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
【マクロ】【配列】3つのシー...
-
文字の色も参照 VLOOKUP
-
【条件付き書式】countifsで複...
-
シートをまたぐ条件付き書式に...
-
ExcelのVlookup関数の制限について
-
エクセルVBA 列検索後に該当デ...
-
Excelにて、ファイル内の複数シ...
-
Excelでの並べ替えを全シートま...
-
マクロか関数で処理したいので...
-
エクセルで、チェックボックス...
-
エクセルの保護で、列の表示や...
-
スプレッドシートでindexとIMPO...
-
Excel 2段組み
-
【VBA】ピボットテーブルを既存...
-
エクセルVBA データを別シート...
-
エクセルの列の限界は255列以上...
-
複数行の同列に同じ値があった...
-
照合した結果によって決めた値...
-
【Excel】ある文字列からはじま...
-
エクセルのマクロで重複データ...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
文字の色も参照 VLOOKUP
-
ExcelのVlookup関数の制限について
-
【条件付き書式】countifsで複...
-
エクセルの保護で、列の表示や...
-
Excelのセルの色を変えた行(す...
-
エクセルで、チェックボックス...
-
VBAで繰り返しコピーしながら下...
-
シートをまたぐ条件付き書式に...
-
Excelでの並べ替えを全シートま...
-
Excel の複数シートの列幅を同...
-
Excelに自動で行の増減をしたい...
-
【VBA】複数のシートの指定した...
-
【エクセル】1列のデータを交...
-
SUMPRODUCTにて別シートのデー...
-
Excel 2段組み
-
エクセル マクロ 標準モジュー...
-
エクセルの列の限界は255列以上...
-
excel 複数のシートの同じ場所...
-
エクセルVBAで、ある文字を含ん...
-
VLOOKアップ関数の結果の...
おすすめ情報