検索
連載

Excelシートの参照、移動、コピー、追加、削除とイベント処理Excelマクロ/VBAで始める業務自動化プログラミング入門(9)(3/4 ページ)

プログラミング初心者を対象にExcelマクロ/VBAを使った業務自動化プログラムの作り方を一から解説します。今回は、ワークシート操作のメソッド、Move、Copy、Add、Deleteに加えて、Array関数による複数ワークシートの参照、イベント処理やFunctionプロシージャなどの使い方について【Windows 10、Excel 2016に対応】。

Share
Tweet
LINE
Hatena

Moveメソッドでシートの移動

 今回のシートは「メニュー」シートが1番先頭にあり、次に「1年生」〜「6年生」と続き、最後に「学年別成績集計」がある。

 実際の業務では、このシートのタブの順番を入れ替えたい場合も出てくるだろう。もちろん手動でドラッグ&ドロップすると順番を入れ替えることはできるが、これもマクロ化できるので、その方法を解説しておこう。今は、そんなに役に立つとは思わないマクロでも、将来マクロに精通し、本格的なマクロプログラムを書く際には、こういった処理も必ず必要になってくる。知っておいて損はない。

 シートの移動にはMoveメソッドを使用する。書式は下記の通りだ。

Moveメソッドの書式

Worksheetsコレクション.Move After:={どのシートの「後ろ」に移動するかを指定}

Worksheetsコレクション.Move Before:={どのシートの「前」に移動するかを指定}


 「学年別成績集計」のシートを「メニュー」の後ろに移動してみよう。マクロはリスト6のようになる。

Sub シートの移動()
  Worksheets("学年別成績集計").Move After:=Worksheets("メニュー")
End Sub
リスト6 「学年別成績集計」のシートを「メニュー」の後ろに移動

 解説はするまでもないだろう。「メニュー」の前に移動したい場合はBeforeを使うといい。実行すると図11のようになる。


図11 「学年別成績集計」シートが「メニュー」タブの後ろに移動した

Copyメソッドでシートのコピー

 シートのコピーは「既に作成されているシートと同じデータのシートを、もう1枚作りたい」という場合に使用する。表の項目名などは同じで、中のデータだけ変更したい場合などでは、元のシートをコピーして持ってくる方が、1から作成し直すより、はるかに手間が省ける。結構使用頻度は高いのではないかと思う。

 シートのコピーにはCopyメソッドを使用する。書式は下記の通りだ。

Copyメソッドの書式

Worksheetsコレクション.Copy After:={どのシートの「後ろ」にコピーするかを指定}

Worksheetsコレクション.Copy Before:={どのシートの「前」にコピーするかを指定)


 では、「3年生」のシートを「3年生」の後ろにコピーしてみよう。マクロはリスト7のようになる。

Sub リストのコピー()
  Worksheets("3年生").Copy After:=Worksheets("3年生")
End Sub
リスト7 リストのコピー

 これも、解説する必要はないだろう。「3年生」の前に移動したい場合はBeforeを使うといい。実行すると図12のようになる。


図12 「3年生(2)」シートが作成された。当然内容もコピーされている

Addメソッドでシートの追加

 シートの追加はシートタブの右側に表示されている[○に+]のアイコンをクリックするだけで、容易に追加できる。こんな簡単な手順をマクロ化して何の役に立つのか? それは、今後自分でマクロを本格的に書き出したころに答えが見つかるだろう。それまでは、「こういった処理もマクロ化できるのだ」といったつもりで読んでもらえればいいと思う。

 シートの追加にはAddメソッドを使用する。書式は下記の通りだ。

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
リスト8 シートの追加

 まず、「1年生」というシートの後ろに5枚のシートを追加している(2行目)。For〜Nextステートメントを用いて、変数「i」を2〜6まで反復処理し、Nameプロパティに変数「i」の値と文字列「年生」を&(アンパサンド)で連結して表示した(4〜6行目)。これで「2年生」〜「6年生」のシートが追加される。

 For〜Nextについては、連載第6回の「For〜Nextで繰り返し処理」を参照してほしい。

 実行したのが図13だ。


図13 「2年生」〜「6年生」のシートが追加された

Deleteメソッドでシートの削除

 シートの削除にはDeleteメソッドを使用する。書式は下記の通りだ。

Deleteメソッドの書式

Worksheetsコレクション.Delete


 では、図13で追加した「2年生」から「6年生」のシートを削除してみよう。マクロはリスト9になる。

Sub シートの削除()
  Dim i As Integer
  For i = 2 To 6
    Worksheets(i & "年生").Delete
  Next
End Sub
リスト9 シートの削除

 「2年生」〜「6年生」のシートを削除している。これを実行すると、図14のようにいちいち削除確認のメッセージが出る。


図14 シート削除確認のメッセージが出る

警告ダイアログ表示の有無を指定するApplication.DisplayAlertsプロパティ

 この警告を表示させないためには「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
リスト10 警告を出さずにシートを削除

 For〜Nextステートメント内に「Application.DisplayAlerts = False」と指定して、5枚のシート削除時に警告を出さないようにしている。削除し終わった後は再度Trueに戻して、警告が出るようにしておく。

 これまでのマクロは全て「Sub〜End」、つまり「Subプロシージャ内」に書いてきた。以前にも書いたが、プロシージャには「Subプロシージャ」と「Functionプロシージャ」がある。ここで、ちょっと「Functionプロシージャ」について触れておこう。

コラム「Functionプロシージャとは」

 「Functionプロシージャ」とは、何らかの処理を行って、その結果を返すプロシージャのことをいう。説明だけでは分かりづらいので、サンプルを作って解説しよう。

 例えば図15のような画面があったとする。


図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
リスト11 「姓」と「名」を結合して表示する

 まず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のようになる。


図16 「姓」と「名」が連結して表示された

 この「名前作成」のように、何らかの処理を行って、その結果を返すプロシージャのことを「Functionプロシージャ」という。SubプロシージャとFunctionプロシージャの違いは、処理結果を返すかどうかという点にある。

 この中で使用しているFor Each〜Next構文については『「配列」「コレクション」の各要素に対して繰り返し処理を行うFor Each〜Next』を参照してほしい。


 次ページでは、最後にシートに関するイベントについて解説しよう。

Copyright © ITmedia, Inc. All Rights Reserved.

ページトップに戻る