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の基本コードですので、
こちらも参考にしてみてください。