Excel VBA質問箱 IV

当質問箱は、有志のボランティア精神のおかげで成り立っています。
問題が解決したら、必ずお礼をしましょうね。
本サイトの基本方針をまとめました。こちら をご一読ください。

投稿種別の選択が必要です。ご注意ください。
迷惑投稿防止のため、URLの入力を制限しています。ご了承ください。


2187 / 13645 ツリー ←次へ | 前へ→

【69482】条件が一致したもののみコピーする tantan 11/7/20(水) 23:36 質問[未読]
【69485】Re:条件が一致したもののみコピーする Yuki 11/7/21(木) 15:53 発言[未読]
【69486】Re:条件が一致したもののみコピーする こたつねこ 11/7/21(木) 23:29 回答[未読]
【69495】Re:条件が一致したもののみコピーする tantan 11/7/23(土) 15:35 お礼[未読]

【69482】条件が一致したもののみコピーする
質問  tantan  - 11/7/20(水) 23:36 -

引用なし
パスワード
   お世話になります。以前、こちらでお世話になり下記のような
マクロを教えていただき使用しておりますが、一部変更したいので
ご教授願います。

Sheet1とSheet2のJ3セル以下の製造番号を対比して同じであれば
Sheet2のFG列より右に入っている数字やテキストなどすべてをSheet1の
同じ場所にコピーしたい

現行:下記マクロでSheet1のJ列の製造番号「1234」のFG列データ「ああああ」
があり、Sheet2に製造番号「1234」がないとマクロ実行した際、Sheet1の「ああああ」は消えてしまう。

改善点:Sheet1とSheet2の製造番号を比較し一致した場合のみSheet1のFG列より
右側のデータを上書き変更する。一致しない、またはSheet2には存在しない場合は
Sheet1のデータをそのまま残したい

Sub sample()
 Dim dic As Object
 Dim endRow As Long
 Dim i As Long, j As Long
 Dim v1(), v2(), v3()
 
 With ThisWorkbook.Worksheets("Sheet1")
  'Sheet1のJ列の最終行を取得
  endRow = .Cells(.Rows.Count, "J").End(xlUp).Row
  'Sheet1の製造番号を配列v1へ格納
  v1() = .Range("J3:J" & endRow).Value
  'Sheet1のメモを配列v2へ格納
  v2() = .Range("FG3:IV" & endRow).Value 
 End With
 
 '配列v1をループし辞書を作成する
 Set dic = CreateObject("Scripting.Dictionary")
 For i = 1 To Ubound(v, 1) 
  '製造番号に対応するメモの行を一旦、辞書に登録
  If Not dic.exists(v1(i, 1)) Then
   dic(v1(i, 1)) = i
  End If
 Next i
 
 With ThisWorkbook.Worksheets("Sheet2")
  'Sheet2のJ列の最終行を取得
  endRow = .Cells(.Rows.Count, "J").End(xlUp).Row
  'Sheet2の製造番号を配列v1へ格納
  v1() = .Range("J3:J" & endRow).Value
  'v3の配列サイズを決める    
  ReDim v3(1 To Ubound(v1, 1), 1 To UBound(v2, 2))

  '配列v1をループし、製造番号に対応するメモを配列v3へ格納    
  For i = 1 To Ubound(v1, 1)  
   If dic.exists(v1(i, 1)) Then
    For j = 1 To UBound(v3, 2)
     v3(i, j) = v2(dic(v1(i, 1)), j)
    Next j
   End If
  Next i
  '配列v3をシートに出力する
  .Range("FG3").Resize(UBound(v3, 1), _
        UBound(v3, 2)).Value = v3() 

 End With
 '配列クリア
 Erase v1, v2, v3
 'オブジェクト解放
 Set dic = Nothing
End Sub

以上、長くなりましたがよろしくお願いいたします

【69485】Re:条件が一致したもののみコピーする
発言  Yuki  - 11/7/21(木) 15:53 -

引用なし
パスワード
   ▼tantan さん:
>Sheet1とSheet2のJ3セル以下の製造番号を対比して同じであれば
>Sheet2のFG列より右に入っている数字やテキストなどすべてをSheet1の
>同じ場所にコピーしたい
こんにちは。
こんな感じですか。

Sub TESTa()
  ' Sheet2 --> Sheet1
  Dim v1 As Variant
  Dim v2 As Variant
  Dim v3 As Variant
  Dim Dic As Object
  Dim i  As Long
  Dim j  As Long
  
  With Worksheets("Sheet2")
    v1 = .Range("J3:J" & .Range("J" & .Rows.Count).End(xlUp).Row).Value
    v2 = .Range("FG3:IV" & .Range("J" & .Rows.Count).End(xlUp).Row).Value
  End With
  Set Dic = CreateObject("Scripting.Dictionary")
  For i = 1 To UBound(v1)
    If Not Dic.Exists(v1(i, 1)) Then
      Dic(v1(i, 1)) = i
    End If
  Next
  With Worksheets("Sheet1")
    v1 = .Range("J3:J" & .Range("J" & .Rows.Count).End(xlUp).Row).Value
    v3 = .Range("FG3:IV" & .Range("J" & .Rows.Count).End(xlUp).Row).Value
  End With
  For i = 1 To UBound(v1)
    If Dic.Exists(v1(i, 1)) Then
      For j = 1 To UBound(v2, 2)
        v3(i, j) = v2(Dic(v1(i, 1)), j)
      Next
    End If
  Next
  With Worksheets("Sheet1")
    .Range("FG3").Resize(UBound(v3), UBound(v3, 2)).Value = v3
  End With
End Sub

【69486】Re:条件が一致したもののみコピーする
回答  こたつねこ  - 11/7/21(木) 23:29 -

引用なし
パスワード
   説明文とプログラムからすると、説明文のSheet1とSheet2を間違えているよう
ですので、Sheet1とSheet2を読み替えた場合の対応を書いておきます。
転記前にSheet2の内容をセットするだけです。

#掲示板で教えていただいたコードは、ちゃんと理解するようにしたほうが
いいと思いますよ。
動きを理解していれば、今回程度の修正はご自分で出来たと思います。

Sub sample()
 Dim dic As Object
 Dim endRow As Long
 Dim i As Long, j As Long
 Dim v1(), v2(), v3()
 
 With ThisWorkbook.Worksheets("Sheet1")
  'Sheet1のJ列の最終行を取得
  endRow = .Cells(.Rows.Count, "J").End(xlUp).Row
  'Sheet1の製造番号を配列v1へ格納
  v1() = .Range("J3:J" & endRow).Value
  'Sheet1のメモを配列v2へ格納
  v2() = .Range("FG3:IV" & endRow).Value 
 End With
 
 '配列v1をループし辞書を作成する
 Set dic = CreateObject("Scripting.Dictionary")
 '▼▼▼ここ『v』に『1』がぬけてますよね?
 'For i = 1 To Ubound(v, 1)
 For i = 1 To Ubound(v1, 1) 
  '製造番号に対応するメモの行を一旦、辞書に登録
  If Not dic.exists(v1(i, 1)) Then
   dic(v1(i, 1)) = i
  End If
 Next i
 
 With ThisWorkbook.Worksheets("Sheet2")
  'Sheet2のJ列の最終行を取得
  endRow = .Cells(.Rows.Count, "J").End(xlUp).Row
  'Sheet2の製造番号を配列v1へ格納
  v1() = .Range("J3:J" & endRow).Value

  '▼▼▼ここを変更
  'v3の配列サイズを決める    
  'ReDim v3(1 To Ubound(v1, 1), 1 To UBound(v2, 2))
  v3() = .Range("FG3:IV" & endRow).Value 

  '配列v1をループし、製造番号に対応するメモを配列v3へ格納    
  For i = 1 To Ubound(v1, 1)  
   If dic.exists(v1(i, 1)) Then
    For j = 1 To UBound(v3, 2)
     v3(i, j) = v2(dic(v1(i, 1)), j)
    Next j
   End If
  Next i
  '配列v3をシートに出力する
  .Range("FG3").Resize(UBound(v3, 1), _
        UBound(v3, 2)).Value = v3() 

 End With
 '配列クリア
 Erase v1, v2, v3
 'オブジェクト解放
 Set dic = Nothing
End Sub

【69495】Re:条件が一致したもののみコピーする
お礼  tantan  - 11/7/23(土) 15:35 -

引用なし
パスワード
   ▼こたつねこ さん、Yukiさん
ありがとうございました。

こたつねこさんの一行追加するだけで、自分の思っていたことが
できるなんて。。
こたつねこさんのおっしゃるとおり、ここで教えていただくコードを
ちゃんと理解しこのような小さな変更を思うとおりできるように
なりたいと思います。
どうもありがとうございました。

2187 / 13645 ツリー ←次へ | 前へ→
ページ:  ┃  記事番号:
2610219
(SS)C-BOARD v3.8 is Free