重要なお知らせ

「教えて! goo」は2025年9月17日(水)をもちまして、サービスを終了いたします。詳細はこちら>

電子書籍の厳選無料作品が豊富!

シート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と転記

A 回答 (15件中1~10件)

おはようございます。


見直してみたら無駄な箇所があったので修正しました。
これで同一データで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)/~~~
見直してもその時はおかしいと思わない?
投稿後読み直すと気がつきます。
もしくは指摘されてから。
いつもすいません。

補足日時:2010/12/13 08:33
    • good
    • 0
この回答へのお礼

Sub test04()と比べました。

Sub test04()→25秒
Sub test06()→1秒以内

また結果も双方同じでした。

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

お礼日時:2010/12/13 08:40

補足読みました。



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

では、よろしくお願いします。

この回答への補足

>このようになっているか、確認してください。

はいそうのとうりです。

お手数かけて申し訳ありません。

補足日時:2010/12/10 19:53
    • good
    • 0
この回答へのお礼

お手数かけました。
どうもありがとうございました。

お礼日時:2010/12/14 11:05

実際にどれくらい時間がかかるか大量のデータでテストしてみました。


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秒以内となるとどれを使用しても
いいのですね。
お手数かけました。
あれっ。お座敷だったのでは?
お忙しいのにすいません。

補足日時:2010/12/10 19:59
    • good
    • 0
この回答へのお礼

ありがとうございます。
別のマクロ作成にはまっていて
(もうギブアップ)
実験していません。
本日修正版がupされてましたので
そちらで実験いたします。

お礼日時:2010/12/13 08:31

補足、ありがとうございます。



意図したものと違う結果が出るデータは大量にあるのでしょうか。

テストデータではうまく行ったのでしょうか。

後考えられるのは、データの型の問題かな・・・。

問題のあるデータをプリントしてみる他ないかな。方法は下に書きます。
'*****ここから '*****ここまで を追加する。
データを目視で調べる。

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さんの書かれた、一定間隔で実行する方法も
使っています。感謝しています。
    • good
    • 0
この回答へのお礼

ありがとうございます。すいません。

説明が下手ですいません。(かえって混乱したらすいません。)

シート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

お礼日時:2010/12/10 17:42

>またシート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では自分で変更したりして、応用されてましたよね。

この回答への補足

シート1が約5,300行
シート2が約5,700行
で1秒かかりませんでした。
どうもありがとうございます。

補足日時:2010/12/10 14:09
    • good
    • 0
この回答へのお礼

>>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
としたら正しく動作しました。

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

お礼日時:2010/12/10 13:47

おや、追加リクエストがあったんですね、気づきませんでした。



> また上記の推測もあっていますでしょうか?
> 数字は下手に書き換えると行数や列数やセル位置を
> 示す場合もあり、怖いです。

ならばテストデータで試してみたらいかがでしょう?
こちらもあなたの質問に答えるためにテストデータをわざわざ作成してるのです。
ま、一応回答しておきますね。
今日はなんとお昼からお座敷がかかっています(笑)

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

補足日時:2010/12/10 11:16
    • good
    • 0
この回答へのお礼

漢字でいれてもらって、
私の予想とは全然違いました。
どうもありがとうございました。

お礼日時:2010/12/10 12:02

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で速くなるか試します。

補足日時:2010/12/10 10:40
    • good
    • 0
この回答へのお礼

ありがとうございました。
シート2が10,000行、シート1が5,000行で
20秒かかります。
シート1の5,000行のうち半分くらいが3です。
現在思ったとおり動作するのがmerlionXXさんの記述だけの為
これでいきます。
ちなみにVLOOKUPでは5~10分なので
20秒はかなり早いです。

お礼日時:2010/12/10 12:01

試してもらって、ありがとう。



回答の修正と補足

>.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秒かかってません。

補足日時:2010/12/10 11:48
    • good
    • 0
この回答へのお礼

わざわざすいません。
テストは
シート1が8行、シート2が6行で行いました。
1,2,3全て思ったとおり正しく転記されました。

で本番環境、
シート1が3,500行、シート2が2,500行でしたが
1秒かかりません。
これから20,000行クラスで挑戦します。
どうもありがとうございました。

お礼日時:2010/12/10 09:58

> その場合はシート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 今日は週末ですがお座敷でしょうか.....

補足日時:2010/12/10 09:38
    • good
    • 0
この回答へのお礼

完璧です。

テストは
シート1が8行、シート2が6行で行いました。
1,2,3全て思ったとおり正しく転記されました。

で本番環境、
シート1が3,500行、シート2が2,500行でしたが
1秒かかりません。
あのめちゃくちゃな質問に対応していただき
感謝いたしております。
どうもありがとうございました。

お礼日時:2010/12/10 09:29

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列の値を連結してます。
    • good
    • 0
この回答へのお礼

ありがとうございます。
配列処理の事を教えていただいて
ありがとうございます。
でも、まだよくわかりません。

あと結果なのですが
(スレッド最初の質問内容が悪くてすいません)

まずシート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と転記のはずが空白

お礼日時:2010/12/10 09:24

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