和風スパゲティのレシピ

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

Worksheet.Selectと.Activateの違い

Worksheetオブジェクトから呼び出す場合の、
SelectメソッドとActivateメソッドの違いを説明します。

同じところ

どちらもアクティブシートを設定/変更できるメソッドです。

Worksheets("○○").Select
Worksheets("○○").Activate

は、多くの場合で○○シートをアクティブにする同じ動きをします。

ActiveSheetの使いどころ

違いを解説する前に先に断っておきますと、しっかりとマクロを組もうと思ったら、ActivateメソッドやSelectメソッドを利用したコードはなるべく書かないようにしましょう。

Worksheets("○○").Activate
Cells(1, 1) = 1

このような「シートをアクティブにしてからActiveSheetに処理をするコード」のことですね。


このコードはコードの書き換えや移植に弱く、
またステップ実行(デバッグなどで1行ずつ実行)時に、
ユーザーの操作で挙動が変わるなどの危険があります。


不具合発生時に原因を特定するときも、
実際に実行してみないとその時点での様子が確認しづらいため、
メンテナンス性が悪いコードになってしまいますからね。


シートオブジェクト名や変数を使って、

Dim ws As Worksheet
Set ws = Worksheets("○○")
ws.Cells(1, 1) = 1

としておくだけで、どのシートを選択していても同じ動きをしてくれる堅牢なコードになりますので、なるべくこの書き方を採用してください。


その上でこれらのメソッドの使いどころですが、

マクロ完了時に「完了しました」メッセージを出すときに、
ユーザーに映して見せたいシートをアクティブにする

ために使います。


その際は基本Activateメソッドを使っておけばOKで、
大きな理由は「別のブックのシートにも使用できるため」ですね。


それを踏まえた上で「ActiveSheetに頼らないシートの指定方法」については、
こちらの記事を参考ください。

www.limecode.jp


使いどころはないと知った上で、豆知識としてSelectとActivateの違いを知りたい方は、このまま読み進めてください。


では違いの解説を始めます。

違うところ:単独のシートに対して

まずは単独のシートに実行する場合に、
Activateメソッドの方がエラーになるパターンが少ないです。


一番よく出てくるのが「別のブックのシートをアクティブにしたい」ときで、
この時Selectメソッドはエラーになります。

' これはOK
Workbooks("△△").Worksheets("○○").Activate

' こちらは△△ブックがアクティブでないとエラー
Workbooks("△△").Worksheets("○○").Select

 
わざわざやる必要はないですが、Selectメソッドでやるなら

Workbooks("△△").Activate
Workbooks("△△").Worksheets("○○").Select

こう書く必要があります。


ついでにWork「book」におけるSelectとActivateの違いを説明しておくと、
そもそもWorkbookオブジェクトはSelectメソッドを持っていませんので、
Activateメソッドを使うことしかできません。


続いて「非表示のシート」に対してですが、
こちらもActivateメソッドだけが使用可能です。

Dim 非表示のシート As Worksheet
Set 非表示のシート = Worksheets("○○")

非表示のシート.Activate ' ←実行できる
非表示のシート.Select ' エラーになる

 
さてActivateメソッドは実行できるはできるのですが、
例えば↓の処理はどうなるか気になるところです。

非表示のシート.Activate
Cells(1, 1) = 1 ' ←このコードはどのシートに実行される??

 

結論ですが、ちゃんと非表示のシートに実行されます。

Activateメソッドは、「そのマクロ実行中に限り」非表示のシートをアクティブにできます。


ただし、この「そのマクロ実行中に限り」というのが曲者で、
マクロが終了すると隣の表示シートにアクティブシートが移ります。

それだけでなく、「F8のステップ実行」を行った場合は、

Cells(1, 1) = 1

このコードは表示されている隣のシートに実行されてしまいます。

一括実行時と、1行ずつ実行時で処理が変わってしまうということですね。


「非表示シートをアクティブにしている」という不思議な状況は、
VBAさんだけのもので、ユーザーが操作できるようになると解消されます。

好ましい状態ではありませんので、この仕様は知っていても使わないようにしましょう。

違うところ:複数のシートに対して

複数のシートに対して実行する場合は、Selectメソッドを使います。

二つのシートを選択するコードは、

Worksheets(Array("データ", "集計表")).Select

こう書くしかありません。

Activateメソッドはエラーになるというか、
そもそもWorksheet「s」オブジェクトはActivateメソッドを持っていません。


また、この2シートを選択する際には、
単独のシートを1枚ずつ選択していく、

Worksheets("データ").Select
Worksheets("集計表").Select Replace:=False

こんなコードを書くこともできます。


WorksheetオブジェクトのSelectメソッドは、
引数Replaceを持っており、これをFalseにすることで今の選択シートを保持したまま新しいシートを追加選択ができます。


といっても「複数のシートを選択する」こと自体が結構危険な状態なので、
いずれにせよ使うことはめったにないですけどね。

使い分け

一応単独のシートはActivate、複数のシートはSelectと使い分けることになります。


が、冒頭の通りいずれにせよマクロの中身で使うものではなく、
ユーザーにマクロの実行結果を見せるだけに使うべきなので、
ほぼActivateメソッドを使っておけばいいということになります。


複数シートの選択状態でマクロを終えると、
それに気づかずユーザーが手入力をした際に、
ActiveSheet以外の選択シートが破損しますからね。


それ以外にSelectメソッドの活きる場面ですが、

Worksheets.Select
Cells(1, 1) = 1

と、「すべてのシートを選択するコード」が楽に書けることを利用して、
全シートへ同じ処理をするコードをかなり短く書けます。


これも非表示のシートがあるとエラーになるなど普通に危険なコードですが、
それを承知で使い捨てのマクロを速攻書くときに使えなくはないです。

一応覚えておいて損はないかもしれませんし、
覚えたせいで損をするかもしれません。


やっぱりただの豆知識だと思っておいてください。