シートとブックを自在に操る!「親」を明記して誤作動を防ぐ技術

Level5 VBA・マクロ

「他のシートからデータを抽出したい」
「他のブックのデータを参照したい」
「他のブックを調べる方法を知りたい」

このように実務では複数のシートや、複数のExcelファイル(ブック)を開いて作業します。

そんな時、VBAのコードにたった一つ不足していると、思わぬ悲劇が起こります。
「違うシートにデータが上書きされた!」という恐怖です。

今回は、この悲劇を完全に防ぐための「親子関係」という概念を学びます。
このルールを知るだけで、あなたのマクロはどんな状況下でも正確に動き続ける、信頼できるロボットになりますよ!


VBAにおける「親子関係」のルール

VBAの世界では、すべてのオブジェクトに明確な階層構造があります。

  1. Application(Excelソフト全体)
  2. Workbook(ファイル)
  3. Worksheet(シート)
  4. Range(セル)

前回まで、ほとんどRange(子供)の名前だけを呼んで操作していました。
Rangeだけで問題がなかったのは、1つのシートだけを利用していたからです。

Range("A1").Value = "OK"  ' ← これ

VBAは「どのシートのことかな?まあ、今開いているシートでいいか!」と
勝手に判断して処理していました。これが誤作動の原因です。

たんたん
たんたん

複数のシート・ブックを利用する時には
必ずシート名やブック名を指定しよう!


誤作動を防ぐ「親の明記」の書き方

誤作動を防ぐためには、常にWorksheet(シート)の名前を明記して、Rangeの「親」を示してあげる必要があります。

1. シート名を明記する

VBAで「データシートのA1セル」を指し示すには、こう書きます。 
Worksheets("データ").Range("A1").Value = 100

これで、VBAは迷うことなく「データ」という名前のシートを探し出し、その中のA1セルを操作します。

2. シートを変数に入れる(スマートな書き方)

シート名を何度も書くのは大変なので、シートも変数(箱)に入れてしまいましょう。

たんたん
たんたん

シート名を何度も書くのはエラーの元だよ!

複数回シート名の指定があると予想したら
変数を用意しようね。

Sub 親の明記()
    Dim ws As Worksheet
    
    ' "データ"という名前のシートを、wsという箱に入れる
    Set ws = Worksheets("データ")
    
    ' 以降、ws(データシート)のA1セルを操作
    ws.Range("A1").Value = Date ' 本日の日付を入れる
End Sub

【重要】 
Set という言葉は、オブジェクト(WorksheetやRangeなど)を変数に入れるときだけ使うものです。数字や文字を入れるときは使いません。


複数のブックの指定

さらに複雑な処理、例えば「集計」ファイルの「月次」シートを読み込む場合
Workbook(ブック/ファイル)も必要になります。

ブックはシートの「親」に当たります。

Workbooks("集計.xlsx").Worksheets("月次").Range("A1").Value

これで、VBAは以下の流れで場所を特定します。

  1. Workbooks(“集計.xlsx”):集計ファイルを選択!
  2. .Worksheets(“月次”):その中の「月次」シートに入れ!
  3. .Range(“A1”):そしてA1セルにアクセスせよ!

この一連の流れも、手作業で「ファイルを選択 → タブをクリック → セルを発見」という
作業の実況中継そのものです。

注意
Workbooks("集計.xlsx")」というファイル指定の方法は
事前にファイルを開いていないと利用できません。

もしファイルを開くところからマクロを作成したいなら
フルパスで「ファイルを指定して、ファイルを開く」処理をしましょう。

詳しくはこちらの記事をご確認ください。

たんたん
たんたん

複数のファイルを利用するなら
ファイルを開くところから自動化のが大半だね。

だとしたら、複数ファイルを利用する時点で
 ・フルパスでファイル名を取得
 ・ファイルはSetを使って変数に入れる

2つは必ずやっておくべきなんだよ!


別シートに書き込まれる悲劇を防ぐ方法

なぜ親の明記が必要なのでしょうか?

あなたがマクロを実行した時、Excel画面では「集計」シートが開いているとします。
もしコードが Range("A1").Value = 100 だけだったら
マクロは「現在アクティブになっている(開いている)シート」のA1に100を書き込みます。

しかし、もし処理の途中で誰かが別のシートのタブをクリックしてしまったら?
マクロは律儀に、そのクリックされた違うシートに100を書き込んでしまい、データが破壊されます。

たんたん
たんたん

アクティブになっているシートって
マクロ内部でも逐一変わるんだ。

A処理をしているときはAシートが、
B処理をしているときはBシートが、
アクティブになっているみたいな感じ。

それを正確に把握してVBAを書くくらいなら
最初から自分で指定していた方が楽だよね。

親を明記していれば、たとえユーザーが別のシートを見ていても、マクロは指定されたシートを無視しません。

これが「信頼性の高いマクロ」を作るための第一歩です。


今回のクエストを終えて

  • マクロは省略すると「現在開いているシート」を勝手に選び、誤作動の原因になる。
  • 誤作動を防ぐには、常にWorksheets("名前").Range(...)のように親を明記する。
  • シートなどのオブジェクトを変数に入れるときは、Setという特別な言葉を使う。
  • Workbook → Worksheet → Rangeという関係を意識すれば、複雑な操作も怖くない!

これで、あなたのマクロは複数のファイルやシートが混在する環境下でも正確に動きます。

次回からは、いよいよ実務に直結する「コピー・ペーストの最適解」に入ります。
面倒な貼り付け操作を、たった1行のコードで高速かつ正確に終わらせるテクニックを学びましょう!

コメント

タイトルとURLをコピーしました