• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:VBA 比較してリンク)

VBAでSheet1とSheet2のリンクを比較する方法

このQ&Aのポイント
  • VBAを使用してSheet1とSheet2の表を比較し、同じ名称の場合にSheet1のD列とSheet2のD列をリンクさせたい。
  • 現在は関数を使用しているが、数が多くなってきたためVBAで処理しようとしている。
  • 組んでみたコードでは、一部の結果が意図しないものになっているため、正しいコードに修正したい。

質問者が選んだベストアンサー

  • ベストアンサー
  • end-u
  • ベストアンサー率79% (496/625)
回答No.2

ふむ。失礼。 方針変更です。test1、test2は無かった事にしてください。 以下、■箇所のみ設定して後は相対関係で処理。 Sub test3()   Dim r(1 To 2) As Range '起点セル|Key列   Dim tmp    As Range 'xlCellTypeBlanks用   Dim s     As String 'R1C1数式共通文字用   Dim i     As Long   Dim x     As Long  '列指定用   Dim y     As Long  '行指定用   Dim v          'Application.Match用配列   '各シートのデータの起点セルを指定   Set r(1) = Excel.Range("Sheet1!A2") '■   Set r(2) = Excel.Range("Sheet2!A21") '■   x = r(1).Column + 3   y = r(1).Row - 1   For i = 1 To 2     With Excel.Range(r(i), r(i).Range("C1").EntireColumn.Cells(Rows.Count).End(xlUp))       '空白セルだけを取得[ctrl]+[g]ジャンプ機能       Set tmp = .Columns("A:B").SpecialCells(xlCellTypeBlanks)       '直上の値をセット       tmp.FormulaR1C1 = "=R[-1]C"       'rにE列を再セット       Set r(i) = .Columns("E")     End With     'E列を作業エリアとして A列&B列&C列 のキーを作る     r(i).FormulaR1C1 = "=RC[-4]&RC[-3]&RC[-2]"     r(i).Value = r(i).Value     '空白セル式クリア     tmp.ClearContents   Next   'Match関数で行位置取得   v = Application.Match(r(2), r(1), 0)   '作業エリアクリア   r(1).ClearContents   r(2).ClearContents   s = "='" & r(1).Worksheet.Name & "'!R"   'Loopして数式セット   With r(2).Offset(, -1).Cells     For i = 1 To UBound(v)       If IsNumeric(v(i, 1)) Then         .Item(i).FormulaR1C1 = s & v(i, 1) + y & "C" & x       End If     Next   End With End Sub

ga74235
質問者

お礼

お返事遅くなりました。今回のは思っていた通りのものでした。 本当にありがとうございました。すごく助かりました。 また、質問させて頂くことがあると思いますが、よろしくお願い致します。 (というより、同じ仕事の系列でもう出ていますが…^^;)

その他の回答 (1)

  • end-u
  • ベストアンサー率79% (496/625)
回答No.1

効率を考えれば、セルのデータ範囲を一旦、配列に取得し、 Loop処理で空白データの場合は直上のデータを見るようにし、 とにかくA列&B列&C列で、参照キーとなるデータを作る事です。 その後の照合については、MATCH関数を使っても良いし。 Sub test1()   Dim i As Long   Dim j As Long   Dim v, w, x, y, z, a, b   For i = 1 To 2     With Sheets("Sheet" & i)       With .Range("A1", .Cells(.Rows.Count, "C").End(xlUp))         v = .Columns("A:B").Value         w = .Columns("C").Value       End With       For j = 1 To UBound(v)         If Not IsEmpty(v(j, 1)) Then           a = v(j, 1)         End If         If Not IsEmpty(v(j, 2)) Then           b = v(j, 2)         End If         w(j, 1) = a & b & w(j, 1)       Next     End With     If i = 2 Then Exit For     x = w   Next   y = Application.Match(w, x, 0)   z = Application.Index(Sheets("Sheet1").Columns("D"), y)   Sheets("Sheet2").Range("D1").Resize(UBound(z)).Value = z End Sub 作業エリアとして、E列が使えるのなら、数式を埋め込んで処理するほうが簡単です。 Sub test2()   Dim rng As Range   Dim rs As Range   Dim x  As Long   Dim i  As Long   For i = 1 To 2     With Sheets("Sheet" & i)       'A2セルからC列最終データまでの範囲       Set rng = .Range("A1", .Cells(.Rows.Count, "C").End(xlUp).Offset(, -1))     End With     '後で使うからsheet1の最終行を覚えておく     If i = 1 Then x = rng.Rows.Count     '空白セルだけを取得[ctrl]+[g]ジャンプ機能     Set rs = rng.SpecialCells(xlCellTypeBlanks)     '直上の値をセット     rs.FormulaR1C1 = "=R[-1]C"     'E列を作業エリアとして A列&B列&C列 のキーを作る     With rng.Columns("E")       .Formula = "=A2&B2&C2"       .Value = .Value     End With     rs.ClearContents   Next   'Sheet2のD列にINDEX(..(MATCH..))関数で値を引っ張ってくる   With rng.Columns("D")     .Formula = "=index(sheet1!$D$1:$D$" & x & ",match(E2,sheet1!$E$1:$E$" & x & ",0))"     .Value = .Value   End With End Sub

ga74235
質問者

お礼

ありがとうございます。早速検証させて頂きました。 一応Test1のほうは結果通りでしたが、Test2の方は1行ずれた(?)状態で表記されてるみたいでした。自分なりに考えてみましたが、どこを触っていいか分かりません。。。 後、説明の仕方が良くなかったですね。 Sheet2のD列には数値をそのまま入れるのではなく、=Sheet1!$D$2と入れる形にしたかったのです。 また、Sheet1とSheet2のそれぞれの開始行が違うのですが、Sheet2の上の方にエラー値が入ってしまいます。この場合でもなんとかなりますでしょうか? 度々のご質問で申し訳ないですが、よろしくお願い致します。