エクセルマクロの紹介、その2です。以前のものは Excel 95 形式でしたが、今回のファイルは Excel 97 形式です。Excel 97 形式以上で閲覧して下さい。あと、ウィルスチェックも。念のため。
Excel 97 でマクロを作成しようとしたとき、Excel 95 との違いに驚いたのは僕だけでしょうか? Excel 95 だと、ブックの中にマクロシートとして記録されますが、Excel 97 だと Visual Basic のインターフェイスのようで、さらに Visual Basic との共通化が進んでいるようです。さらには、Power Point も。。。そんなわけで、Visual Basic を扱う感じでちょっとマクロのインターフェイスをいじっていると、あっさりとシートのイベントが取れそうだったので、勢いでつくったのがこのサンプルです。ホント、Visual Basic と同じ感覚です。Visual Basic の初歩ではコレクションはあまり使いませんが、Excel の場合はコレクションの取扱が必須になってくるので、コレクションの理解は必須になると思われます。。。
サンプルマクロの機能ですが、Sheet1 の A2 と B2 に数値を入力すると、Sheet2 の A2 に足し算の答えを表示するという簡単な物です。以前から Excel のデータの変更などのイベントが取れるらしいことは、それとなく知っていたのですが、どうするかは知らなくて、とりわけ使うわけでもなく調べないまま放置していたのですが、今回はその解決版と言うことになります。
次に、マクロのコードの表示方法と編集方法です。Excel のメニューの [ツール]−[マクロ]−[Visual Basic Editor] を選択すると、普通の Visual Basic と同じ様な画面が立ち上がります。タイトルは、「Microsoft Visual Basic - macro2.xls」となっているはずです。その画面のメニューで、[表示]−[プロジェクト エクスプローラ] を選択すると、「プロジェクト VBAProject」という子ウィンドウが表示(選択)されます。その子ウィンドウの中はツリー表示になっているので、[VBAProject]−[Microsoft Excel オブジェクト]−[Sheet1(Sheet1)] をダブルクリックすると新たに子ウィンドウが表示されます。タイトルは「macro.xls - Sheet1 (コード)」となっています。この子ウィンドウに表示されているのが、今回追加したコードの全てです。
以下、コードの抜粋
Private Sub Worksheet_Change(ByVal Target As Excel.Range)
Dim intA As Integer
Dim intB As Integer
If Target.Row = 2 And (Target.Column = 1 Or Target.Column = 2) Then
If IsNumeric(Range("A2").FormulaR1C1) And IsNumeric(Range("B2").FormulaR1C1) Then
intA = Val(Range("A2").FormulaR1C1)
intB = Val(Range("B2").FormulaR1C1)
Sheets("Sheet2").Select
Sheets("Sheet2").Range("A2").FormulaR1C1 = Str(intA + intB)
End If
End If
End Sub
以下、コードの簡単な説明
関数 Worksheet_Change は Sheet1 のセルの内容が変更されたときに呼び出されるイベントプロシージャです。引数の Target は変更されたセルに対するオブジェクトで、Target を調べることで、どのセルの内容が変更されたかなどを知ることができます。
よって、
>If Target.Row = 2 And (Target.Column = 1 Or Target.Column = 2) Then
はどのセルが変更されたかを調べています。
>If IsNumeric(Range("A2").FormulaR1C1) And IsNumeric(Range("B2").FormulaR1C1) Then
は A2 と B2 の値が数値として評価できるかどうかを調べています。
>intA = Val(Range("A2").FormulaR1C1)
と次の表はそれぞれ A2 と B2 の値をそれぞれ変数に代入しておいて、
>Sheets("Sheet2").Select
で Sheet2 を選択して、
>Sheets("Sheet2").Range("A2").FormulaR1C1 = Str(intA + intB)
で和の値を Sheet2 の A2 に代入しています。
プログラム自体はオブジェクトのイメージをつかめないとなかなか理解できないかもしれません。サンプルプログラムでは足す数と足される数をいったん変数内に保存していますが、実際はもっと省略することができて次のように1行で書くことも出来ます。
Sheets("Sheet2").Range("A2").FormulaR1C1 = Str( _
Val(Sheets("Sheet1").Range("A2").FormulaR1C1) + _
Val(Sheets("Sheet1").Range("B2").FormulaR1C1))
オブジェクト Range は オブジェクトSheets のメンバなので、このようなことが出来るわけですが、どのオブジェクトにどのメンバがあるかはオブジェクトの種類はやはりある程度使っていかないと分からないと思います。その都度、ヘルプなどを参照するのが最も確実でしょう。