今回のシートは「メニュー」シートが1番先頭にあり、次に「1年生」〜「6年生」と続き、最後に「学年別成績集計」がある。
実際の業務では、このシートのタブの順番を入れ替えたい場合も出てくるだろう。もちろん手動でドラッグ&ドロップすると順番を入れ替えることはできるが、これもマクロ化できるので、その方法を解説しておこう。今は、そんなに役に立つとは思わないマクロでも、将来マクロに精通し、本格的なマクロプログラムを書く際には、こういった処理も必ず必要になってくる。知っておいて損はない。
シートの移動にはMoveメソッドを使用する。書式は下記の通りだ。
Worksheetsコレクション.Move After:={どのシートの「後ろ」に移動するかを指定}
Worksheetsコレクション.Move Before:={どのシートの「前」に移動するかを指定}
「学年別成績集計」のシートを「メニュー」の後ろに移動してみよう。マクロはリスト6のようになる。
Sub シートの移動() Worksheets("学年別成績集計").Move After:=Worksheets("メニュー") End Sub
解説はするまでもないだろう。「メニュー」の前に移動したい場合はBeforeを使うといい。実行すると図11のようになる。
シートのコピーは「既に作成されているシートと同じデータのシートを、もう1枚作りたい」という場合に使用する。表の項目名などは同じで、中のデータだけ変更したい場合などでは、元のシートをコピーして持ってくる方が、1から作成し直すより、はるかに手間が省ける。結構使用頻度は高いのではないかと思う。
シートのコピーにはCopyメソッドを使用する。書式は下記の通りだ。
Worksheetsコレクション.Copy After:={どのシートの「後ろ」にコピーするかを指定}
Worksheetsコレクション.Copy Before:={どのシートの「前」にコピーするかを指定)
では、「3年生」のシートを「3年生」の後ろにコピーしてみよう。マクロはリスト7のようになる。
Sub リストのコピー() Worksheets("3年生").Copy After:=Worksheets("3年生") End Sub
これも、解説する必要はないだろう。「3年生」の前に移動したい場合はBeforeを使うといい。実行すると図12のようになる。
シートの追加はシートタブの右側に表示されている[○に+]のアイコンをクリックするだけで、容易に追加できる。こんな簡単な手順をマクロ化して何の役に立つのか? それは、今後自分でマクロを本格的に書き出したころに答えが見つかるだろう。それまでは、「こういった処理もマクロ化できるのだ」といったつもりで読んでもらえればいいと思う。
シートの追加にはAddメソッドを使用する。書式は下記の通りだ。
Worksheetsコレクション.Add Before:={どのシートの前に追加するかを指定,Count:=追加するシートの数}
Worksheetsコレクション.Add After:={どのシートの後ろに追加するかを指定,Count:=追加するシートの数}
最初は「1年生」というシートだけが存在しているものとする。「1年生」というシートの後に5つのシートを追加して、「2年生」〜「6年生」というシート名にしてみよう。マクロはリスト8のようになる。なお今回は、ここまでの解説で既に「メニュー」「学年別成績集計」「1年生」〜「6年生」というシートが追加されているので、リスト8を試す場合は、新しいExcelブックを起動して、「Sheet1」を「1年生」に名前を変更した後にしてほしい。
Sub シートの追加() Worksheets.Add After:=Worksheets("1年生"), Count:=5 Dim i As Integer For i = 2 To 6 Worksheets(i).Name = i & "年生" Next End Sub
まず、「1年生」というシートの後ろに5枚のシートを追加している(2行目)。For〜Nextステートメントを用いて、変数「i」を2〜6まで反復処理し、Nameプロパティに変数「i」の値と文字列「年生」を&(アンパサンド)で連結して表示した(4〜6行目)。これで「2年生」〜「6年生」のシートが追加される。
For〜Nextについては、連載第6回の「For〜Nextで繰り返し処理」を参照してほしい。
実行したのが図13だ。
シートの削除にはDeleteメソッドを使用する。書式は下記の通りだ。
Worksheetsコレクション.Delete
では、図13で追加した「2年生」から「6年生」のシートを削除してみよう。マクロはリスト9になる。
Sub シートの削除() Dim i As Integer For i = 2 To 6 Worksheets(i & "年生").Delete Next End Sub
「2年生」〜「6年生」のシートを削除している。これを実行すると、図14のようにいちいち削除確認のメッセージが出る。
この警告を表示させないためには「Application.DisplayAlerts」プロパティにTrueまたはFalseを指定する。Falseを指定すると図14のメッセージは表示されない。デフォルトはTrueで表示されるようになっている。リスト9をリスト10のように書き直すと、警告メッセージは出なくなる。
Sub 警告を出さずにシートを削除() Dim i As Integer For i = 2 To 6 Application.DisplayAlerts = False Worksheets(i & "年生").Delete Next Application.DisplayAlerts = True End Sub
For〜Nextステートメント内に「Application.DisplayAlerts = False」と指定して、5枚のシート削除時に警告を出さないようにしている。削除し終わった後は再度Trueに戻して、警告が出るようにしておく。
これまでのマクロは全て「Sub〜End」、つまり「Subプロシージャ内」に書いてきた。以前にも書いたが、プロシージャには「Subプロシージャ」と「Functionプロシージャ」がある。ここで、ちょっと「Functionプロシージャ」について触れておこう。
「Functionプロシージャ」とは、何らかの処理を行って、その結果を返すプロシージャのことをいう。説明だけでは分かりづらいので、サンプルを作って解説しよう。
例えば図15のような画面があったとする。
「C2」のセルに「姓」、「C3」のセルに「名」と、それぞれ別個に「姓名」を入力して[実行]ボタンをクリックすると、「C5」のセルに「姓名」が連結されて表示されるマクロはリスト11だ。
Option Explicit Function 名前作成(mySheet As Range) As String Dim myCell As Range Dim myName As String For Each myCell In mySheet myName = myName & myCell.Value Next 名前作成 = myName End Function Sub 姓名結合() Range("C5").Value = 名前作成(Range("C2:C3")) End Sub
まず2〜9行目で、値を返す「名前作成」Functionプロシージャを作成する。
引数にRangeオブジェクト型のmySheetを指定し、返す結果は文字列(String型)とする(2行目)。Range型の変数myCellを宣言し、String型のmyNameも宣言する(3〜4行目)。
For Each〜Next構文を使ってRangeオブジェクト型のmySheetコレクションの中を、Range型のmySheetで反復処理しながら、mySheetコレクション内の値を取得していく(5〜7行目)。文字列型変数myNameにValueプロパティでRangeコレクション内の取得した値を格納していく(6行目)。Functionプロシージャの名称、「名前作成」に取得した値を格納しているmyNameの値を格納する(8行目)。
次に、この「名前作成Functionプロシージャ」を呼び出すSubプロシージャを記述する(11〜13行目)。
ここでは、「C5」のセルに「名前作成」の引数に「Range("C2:C3")」と指定するだけだ(12行目)。
これで、「C5」のセルに「姓名」が連結されて表示される。[実行]ボタンには「姓名結合Subプロシージャ」を関連付け、実行すると図16のようになる。
この「名前作成」のように、何らかの処理を行って、その結果を返すプロシージャのことを「Functionプロシージャ」という。SubプロシージャとFunctionプロシージャの違いは、処理結果を返すかどうかという点にある。
この中で使用しているFor Each〜Next構文については『「配列」「コレクション」の各要素に対して繰り返し処理を行うFor Each〜Next』を参照してほしい。
次ページでは、最後にシートに関するイベントについて解説しよう。
Copyright © ITmedia, Inc. All Rights Reserved.