和風スパゲティのレシピ

日本語でコーディングするExcelVBA

33本目:マクロ記録の改修

Excel&VBA解説サイト「エクセルの神髄」様出題の問題集、
VBA100本ノック」に対する私の回答と解説のページです。

100本ノックの出題リストはこちらから
excel-ubara.com

出題:マクロ記録の改修

#VBA100本ノック 33本目
「このVBAはマクロの記録から作ったのですが、件数の数値を変更してから実行しなければならず、データ件数も多くて何分も時間がかかりとても困っています。なんとかしてもらえないでしょうか?」
こう頼まれました。VBAを書いて対応してあげましょう。

データサンプル

◇ 出題ページはこちら

ソースコード

Formula利用版

Sub 名称と単価をマスタから取得し金額を計算する_Formula利用版()
    
    Dim 最終行 As Long
    最終行 = WSデータ.Cells(WSデータ.Rows.Count, 2).End(xlUp).Row
    
    WSデータ.Range("D2:D" & 最終行).Formula = "=IFERROR(VLOOKUP(B2,マスタ!A:C,2,FALSE),"""")"
    WSデータ.Range("E2:E" & 最終行).Formula = "=IFERROR(VLOOKUP(B2,マスタ!A:C,3,FALSE),"""")"
    WSデータ.Range("F2:F" & 最終行).Formula = "=C2*E2"
    WSデータ.Range("D2:F" & 最終行).Value = WSデータ.Range("D2:F" & 最終行).Value

End Sub

WorksheetFunction利用版

Sub 名称と単価をマスタから取得し金額を計算する_WorksheetFunction利用版()
    
    Dim 最終行 As Long
    最終行 = WSデータ.Cells(WSデータ.Rows.Count, 2).End(xlUp).Row
    
    Dim R As Long
    For R = 2 To 最終行
        
        On Error Resume Next
        WSデータ.Cells(R, 4) = WorksheetFunction.VLookup( _
            WSデータ.Cells(R, 2), WSマスタ.Columns("A:C"), 2, False)
        WSデータ.Cells(R, 5) = WorksheetFunction.VLookup( _
            WSデータ.Cells(R, 2), WSマスタ.Columns("A:C"), 3, False)
        On Error GoTo 0
        WSデータ.Cells(R, 6) = WSデータ.Cells(R, 3) * WSデータ.Cells(R, 5)
        
    Next
    
End Sub

解説

マクロ記録をどうやって改修するかに加えて、
膨大な検索を行う処理をどう高速化するかを考える問題でした。


私の100本ノックはライブラリ(汎用関数)づくりもテーマにしていましたが、
本問は「マクロ記録からExcelVBAを学び始めた人にも読めるコード」が重要なため、
本問ではライブラリの使用をストップしています。


本問の解き方としてストレートなのはやはりFormulaで、
書きやすく、そして処理も超高速です。

特にExcelからVBAに入っていく人にとっては、
シート数式をそのまま流用できるという点も大きいですね。


実務上の解答としてはFormulaを使ったコードで十分と思いますが、
本問は「マクロ記録を使っている人の教育」もテーマということで、
ロジックをそのままに綺麗に書き替えたバージョンも用意してみました。

WorksheetFunctionをFor文で回すというVBAの基本コードですので、
こちらも参考にしてみてください。