マクロの記録の限界

職場で、Excelマクロの問い合わせを受けた。
それで回答しながら思ったのだが、やはりマクロの記録には壁(限界)がある。
f:id:Infoment:20200403220714p:plain

今回受けた問い合わせは、シートのコピーについて。
質問者から、マクロの記録で作成したコードの解説を依頼された。

記録時点では、↓こんな感じ。

Sub Macro1()
    Sheets("Sheet1").Select
    Sheets("Sheet1").Copy After:=Sheets(1)
    Sheets("Sheet1 (2)").Select
    Sheets("Sheet1 (2)").Name = "ああああ"
End Sub

第一の壁はやはり「選ばない」かな。マクロの記録は良くも悪くも、操作を愚直に記録してくれる。しかし、シートのコピーや名前の変更に於いて、「選ぶ」という動作は無くとも可能だ。

「選ぶ」という動作を記録した1,3行目を省略してみる。

Sub Macro1()
    Sheets("Sheet1").Copy After:=Sheets(1)
    Sheets("Sheet1 (2)").Name = "ああああ"
End Sub

これでも充分動作する。だが「選ばずともよい」という気づきに、果たして全ての人が独力で着想可能だろうか。少なくとも私は、教えられるまで気づけなかった。

コピーしたシートをその後も操作する場合、変数にセットすると扱いやすい。

Sub Macro1()
    Dim Sh As Worksheet
        Sheets("Sheet1").Copy After:=Sheets(1)
    Set Sh = ActiveSheet
        Sh.Name = "ああああ"
End Sub

しかし、マクロの記録に於いて「変数の宣言」や、「Set」などは登場しない。
先の「Selectの省略」は気づけても、これは、知らなければ知り得ない。

慣れてくると、「ActiveSheet」で失敗することがある。
「今、編集可能な状態のシート」など、状況によってどうとでも変化する。

だから、例えばシートのコピーではなく、単純な新規シートの追加であるならば、最近はこう書くようになった。

Sub Macro1()
    Dim Sh As Worksheet
    Set Sh = Worksheets.Add(After:=Sheets(1))
        Sh.Name = "ああああ"
End Sub

このあとシートを殆ど操作しない場合などは、こんな書き方でも良い。

Sub Macro1()
    With Worksheets.Add(After:=Sheets(1))
        .Name = "ああああ"
    End With
End Sub

これらもまた、いずれの場合も、マクロの記録では知り得ない。

ではこれらは、いつ学べばよいか。昔は、マクロの記録で得られるコードを最初に知り、次いで上記に紹介したような内容を段階的に学ぶのが良いと思っていた。
なぜなら、自分がそのように学んだから。

しかし今では考えが変わり、なるべく早い段階で上記紹介のような内容を知るのが良いと思っている。例えば今回のような質問を受けた場合は、上記のように様々な方法を伝えるようにしている。そう思うに至った理由は、以下の二つ。

  1. マクロの記録で得られる記述が体に染みつくのを避けるため
  2. 一つの処理に対し、なるべく多くのアプローチを知ってもらうため

私が体験した苦労を、そっくりそのまま辿る必要は無いのだから。

参考まで。