Excel VBA質問箱 IV

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

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


4884 / 13644 ツリー ←次へ | 前へ→

【53810】フォーマットの異なる複数シートのマージ hiro 08/2/8(金) 1:18 質問[未読]
【53812】Re:フォーマットの異なる複数シートのマージ ichinose 08/2/8(金) 8:13 発言[未読]
【53837】Re:フォーマットの異なる複数シートのマージ hiro 08/2/8(金) 17:06 お礼[未読]

【53810】フォーマットの異なる複数シートのマージ
質問  hiro  - 08/2/8(金) 1:18 -

引用なし
パスワード
   はじめまして。
最近VBAにはまり出したにわかマクロ使いです。
一通り基礎は理解できてきたのですが、性能面でどうかな、と思ったので
質問させてください。

エクセルのVBAで以下のようなマクロを作ろうとしています。

☆Sheet1とSheet2の内容をマージしたものをSheet3に出力するマクロ
  ●それぞれのシートの内容(データは適当です)
     Sheet1               Sheet2
     ID 名前 スコア1 スコア2   ID 名前 所属
      1  あ   20   30    1  あ 1組
      2  い   20   30    2  い 2組
      3  う   20   30    3  う 3組
      4  え   20   30    4  え 4組
      1  あ   20   30    
      2  い   20   30    
      3  う   20   30    

   Sheet1とSheet2の内容からIDをキーにして
   以下のようなシートを作成する。

     Sheet3
     ID 名前 スコア1 スコア2 所属
      1  あ   20   30 1組
      2  い   20   30 2組
      3  う   20   30 3組
      4  え   20   30 4組
      1  あ   20   30 1組
      2  い   20   30 2組 
      3  う   20   30 3組 

イメージ的には正規化の逆って感じです。

自分で考えたコードは
*************************************
for i = 1 to sheet1データ数

 方法1.
 for j = 1 to sheet2データ数
  if worksheets("sheet1").cells(i,1).value = _
    worksheets("sheet2").cells(j,1).value then
      worksheets("sheet3").range("A" & i & ":D" & i) = _
       worksheets("sheet1").range("A" & i & ":D" & i)
      worksheets("sheet3").cells(i,5).value = _
       worksheets("sheet2").cells(j,3)
  end if
 next j
 
 方法2.
 worksheets("sheet3").range("A" & i & ":D" & i) = _
  worksheets("sheet1").range("A" & i & ":D" & i)
 worksheets("sheet3").(i,5).calue = _
  Application.worksheetfunction.vlookup( _
  worksheets("sheet1").cells(i,1), _
  worksheets("sheet2").usedrange,3,false)

next i
*************************************
です。一応動くことは動くのですが、データ件数が多く(4〜5万件)なるとループ回数が増えてしまって実行時間がとても長くなります。

これ以外でもっとスマートな方法などありましたら、
アドバイスしていただけないでしょうか。
よろしくお願いします。

【53812】Re:フォーマットの異なる複数シートのマ...
発言  ichinose  - 08/2/8(金) 8:13 -

引用なし
パスワード
   ▼hiro さん:
おはようございます。

標準モジュールに
'==================================================
Sub main()
  Dim arng As Range
  Dim brng As Range
  With Worksheets("sheet1")
    Set arng = .Range("a1", .Cells(.Rows.Count, "a").End(xlUp)).Resize(, 4)
    End With
  With Worksheets("sheet2")
    Set brng = .Range("a1", .Cells(.Rows.Count, "a").End(xlUp)).Resize(, 3)
    End With
  With Worksheets("sheet3")
    .Range(arng.Address).Value = arng.Value
    .Range("e1").Value = "所属"
    With .Range("e2", _
       arng.SpecialCells(xlCellTypeLastCell).Offset(0, 1).Address)
     .Formula = "=vlookup(a2," & brng.Address(, , , True) & ",3,false)"
     End With
    End With
End Sub

で試してください

【53837】Re:フォーマットの異なる複数シートのマ...
お礼  hiro  - 08/2/8(金) 17:06 -

引用なし
パスワード
   ▼ichinose さん:

ichinoseさんのコードで、約6万件のデータをマージしたところ
1秒足らずで処理を終えることができました^^

このコードの肝は、予め必要となるrangeを取得しておいて、
対象となるセル全てを対象に、数式を一気に書き込むところですかね。

こんな方法があったとは驚きです。

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

>▼hiro さん:
>おはようございます。
>
>標準モジュールに
>'==================================================
>Sub main()
>  Dim arng As Range
>  Dim brng As Range
>  With Worksheets("sheet1")
>    Set arng = .Range("a1", .Cells(.Rows.Count, "a").End(xlUp)).Resize(, 4)
>    End With
>  With Worksheets("sheet2")
>    Set brng = .Range("a1", .Cells(.Rows.Count, "a").End(xlUp)).Resize(, 3)
>    End With
>  With Worksheets("sheet3")
>    .Range(arng.Address).Value = arng.Value
>    .Range("e1").Value = "所属"
>    With .Range("e2", _
>       arng.SpecialCells(xlCellTypeLastCell).Offset(0, 1).Address)
>     .Formula = "=vlookup(a2," & brng.Address(, , , True) & ",3,false)"
>     End With
>    End With
>End Sub
>
>で試してください

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