ド素人でも学べる ExcelVBA 013 別シート

ブログ

はじめに

 ExcelVBAでは、アクティブシートのセルの値を編集する時、ワークシートの指定を省略することができるが、アクティブでないシートのセルの値が欲しい場合は、ワークシートを指定する必要がある。

 ワークシートを指定するには、Worksheetsオブジェクトを使う。※1 Worksheetsオブジェクトは現在のブックが持つシート配列を扱うオブジェクトだ。このようなオブジェクトの配列の事をVBAでは「コレクション」という言い方をする。

(※1 Worksheetsオブジェクトの他に Sheetsオブジェクトというのもあるが、こちらはワークシートだけでなくグラフ表示用のシートなども扱うオブジェクトになる。)

Worksheetsオブジェクト

 ワークシートを指定する方法は2つある。1つは数値で指定する方法。もう1つはシート名で指定する方法だ。

ワークシートを数値で指定する

 数値でワークシートを指定するには以下のように記述する。

 Worksheets(1)

 Worksheetsの持つワークシート配列は 1 から始まる点に注意しよう。(通常の配列は 0 から始まる事もあるのだ。) 一方、最後のワークシートに関しては、ワークシートが増減するので、Countというプロパティを使う。
 Countプロパティは、ブックの持つワークシートの数を保持している。ワークシートの数を表示するプログラムは以下のようになる。

Sub testWorksheets()
    Debug.Print Worksheets.Count
End Sub

ワークシートをシート名で指定する

 シート名でワークシートを指定するには以下のように記述する。

 Worksheets("Sheet1")

 シート名は文字列で指定するので、シート名に “” を付ける。もちろん文字列型の変数を指定しても良い。

全てのシート名を表示するプログラム

 ブックにある全てのワークシートを巡回してシート名を表示するプログラムは以下のようになる。

Sub testWorksheets2()
    Dim i As Long
    For i = 1 To Worksheets.Count
        Debug.Print Worksheets(i).Name
    Next i
End Sub

 このプログラムでは、For文を使ってWorksheetsオブジェクトにある(単体シートの)Worksheet オブジェクトを巡回している。

 Worksheets オブジェクトは配列(コレクション)であるのに対して、Worksheet オブジェクトはワークシート単体のオブジェクトで扱いは異なるので注意しよう。

 実行するとブックにあるシート名が表示される。
例として以下のようなシート構成でプログラムを実行してみる。

【結果】
A
B
C
D

 ここから A シートを最後尾に移動して実行してみると以下のようになる。

【結果】
B
C
D
A

プログラムの結果は、表示されたExcelシートの順番になるが、プロジェクトウインドウに変化はない。
次は、B シートを非表示にして実行してみる。

【結果】
B
C
D
A

 結果は前回と同じで、非表示のシートもシート名を得る事ができる。(セルの値も取得・設定可能だ。)
但し、非表示のシートを Select(選択)する事はできない。

Sub testworksheets3()
     Debug.Print Worksheets("B").Select
End Sub

 B シートを非表示で上記のプログラムを実行すると以下のようなエラーメッセージが表示される。

 これらの挙動を理解しておくと、エラーの原因に気付く事ができるだろう。

For Each In

 繰り返し処理の特別バージョンを紹介しよう。For Each sh In は、コレクションでよく使用される。
「コレクション」とは、オブジェクトの配列の事を言う。
 構文は以下のような感じだ。

 For Each コレクション要素 In コレクションや配列
    内部処理
 Next コレクション要素

Sub testworksheets3()
    Dim sh
    For Each sh In Worksheets
        Debug.Print sh.Name
    Next sh
End Sub

 使い方は、まず繰り返しを行う単体のコレクション要素を変数として宣言するコレクション要素の変数はバリアント型がよく使われるが、Object型や固有のオブジェクト型でも可能だ。
 For Each に続き、コレクション要素の変数を記述したら、In の後にコレクションを記述する。
コレクションは、Worksheetss が付いた複数形になっている所に注目しよう。

 見てわかる通り、1,2,3,,,という風に順番で繰り返すというよりは、コレクション(配列)の要素に対して1つずつ繰り返し処理を行うというイメージだ。なので逆順に繰り返すような細かい処理には向いていない。

 初心者の方には、通常のFor文をマスターして、余裕がある人は特別バージョンとして覚えて貰えれば良いと思う。サンプルコードを参考にしたい時によく出てくるので紹介した次第だ。

各シートのデータの参照

 普段のExcelシートの操作では、目的のワークシートを選択してから値を参照する。この方法は、「マクロの記録」などで良く使用される方法だ。そもそも「マクロの記録」はユーザーの行った操作を記録するのだから Select してから、Selection に対して何かを行うという形が多い。

Sub Macro1()
'
' Macro1 Macro
'

'
    Range("B2").Select
    Selection.Copy
    Sheets("Sheet2").Select
    Range("A1").Select
    Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
        :=False, Transpose:=False
End Sub

 これは、アクティブシートのB2セルをコピーして、Sheet2のA1に値のみの貼り付けを行った例になる。
「マクロの記録」では、Select して、Selection に対して Copy 。次にシートを変えるために Sheet2 を Select して、A1セルを Select 。最後に、Selectionに対して、PasteSpecial で貼り付けを行っている。

 これをこれまで学んだ書き方で表現すると以下のようになる。

Sub myMacro2()
    Worksheets("Sheet2").Range("A1") = Range("B2")
End Sub

 簡単に書けたのは、Select や Selection を使わない事。さらに、値のコピーなので、プロパティ値の代入で済ませているからだ。

 また、Macro1では、現在のシートが Sheet2 に変更されるが、myMacro2 では、現在のシートは変化しない。
つまり、どのシートの値を取得・設定するにしても、そのシートを Select する必要はないのだ。

 このようにVBAでは、シートやセルを Select するということは稀で、使用する場合はユーザーに対して明示的に選択している事を示したい場合にのみ使用することになる。

 尚、Macro2 では現在のシートが変化すると結果が異なってしまう。コピー元もシートを固定すればユーザーがどのシートを開いていても結果は同じになる。

Sub myMacro3()
    Worksheets("Sheet2").Range("A1") = Worksheets("Sheet1").Range("B2")
End Sub

まとめ

 VBAでセルを指定する場合、シートを跨ぐようなコピーを行う場合、シート指定は、Worksheetsコレクションに対して、数値で指定する場合とシート名で指定する場合がある。

 Worksheets(1)
 Worksheets(“Sheet1”)

 ブック内のワークシートの数は、Countプロパティで取得できる。

 Worksheets(“Sheet1”).Count

 シート名のプロパティは Name を使う。

 Worksheets(1).Name

 ブック内のシートは、For文をつかって巡回できる。For Each sh In に関しては余裕のある人は覚えておこう。
また、シートを指定してセルの値をコピー・貼り付けを行う場合、現在のシート(アクティブシート)は変化することはないので覚えておこう。

 

コメント

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