Excel マクロ 入門講座 for Excel95 VBA

| Uchidas | News | Family | Yasuo | Michiko | Miho | Yuuta | Ai | あそぼーど |


サンプル・ワークシート及びマクロのダウンロードが可能になりました。圧縮していませんのでExcelですぐに読み込み可能です。

お知らせ
 vba2.xlsの<例9>では、やや特殊なワークシート関数DEC2HEXを使用しています。
 そのため、<例9>を正しく動作させるには「分析ツール」を組み込む必要がありますので,詳しくはExcelのマニュアルやオンラインヘルプを参照してください(他の例の実行には不要です)。

入門編

 ワープロと並んで最もよく利用されるアプリケーションは,表計算ソフトです.日本語では「表計算」という呼び方になりますが,単なる表の集計処理にとどまらず,データベース的な使い方から,プレゼンテーションに役立つグラフ資料の作成,シミュレーション,分析・解析処理に至るまで,さまざまな利用方法があります.そして,その多くは表計算ソフトの「直接的な操作」で容易に行なうことができます.しかし,定型的な処理の反復使用,処理の自動化,各業務に特化した処理などを行ないたい場合には,いわゆる「マクロ」が必要になってきます.マクロとは,各アプリケーションに備わっている機能を自由に呼び出し,組み合わせて使用することにより自動的な処理を可能にする,エンドユーザー向けのプログラミング言語のことです.「スクリプト」という言葉も,マクロとほぼ同じ意味で使用される場合があります.マクロを使うと表計算ソフトの活用範囲が数倍にも広がるものと思います.ぜひ挑戦してみてください.

■VBAとは
 ここで紹介する内容は,Microsoft Excel for Windows 95 Version 7.0のVBA に対応しています. VBAは,Microsoft Visual Basic Programming System Application Editionの略で,アプリケーション版Visual Basicという位置づけになります.したがって,Visual Basicをご存知の方はもちろん,一世を風靡した元祖の言語であるBasicをかじったことのある方はその知識が役立ちます.まったく初めての場合には,まず「マクロ」自体に慣れ親しんでください.そして,次のステップとして,「プログラミング」というものの概念を捉えてください.マクロを作るには,マクロ記録機能を使う方法と,マクロのプログラムを直接作成する方法の2通りの方法があります.

■マクロ記録機能
 試しに,ワークシートの1行目から5行目の行の高さを変更し「20」に設定するマクロを記録してみましょう.

[1] [ツール]-[マクロの記録]-[新規マクロの記録]を選択します.
[2] [新規マクロの記録]ダイアログボックスでマクロ名等を入力しをクリックします.マクロ名は,たとえば「Record1」とします.
[3] 記録したい操作を実行します. たとえば,1行目から5行目まで,ドラッグして選択します.
[4] [書式]-[行]-[高さ]を選択します.
[5] [行の高さ]ダイアログボックスで「行の高さ」を「20」に設定して,をクリックします.
[6] これで行の高さが変更されます. をクリックして,マクロ記録を終了します.
[7] ブックにモジュールシートが作成され,マクロが記録されています.

■マクロの実行
 続いて,記録されたマクロを実行してみます.

[1] 適当なワークシート,たとえば「Sheet2」を選択して表示します. [ツール]-[マクロ]を選択します.
[2] [マクロの実行]ダイアログボックスで,先ほど記録された「Record1」という名前のマクロを選択して,をクリックします.
[3] マクロが実行され,1行目から5行目までの行の高さが変更されます.

 このように,よく利用する一連の操作をマクロとして記録しておけば,必要なときに呼び出して簡単に実行することができます.いろいろと試してみてください.しかしながら,この方法では特定の領域を特定の値でしか変更できないなど柔軟性に欠けますし,より複雑な処理を行なうには適していません.そこで,本格的な処理を行なうには,マクロのプログラムを直接作成することになります.ただし,実際のマクロ作成にあたっては,マクロ記録機能を併用する場合もあります.

■マクロの直接入力
 マクロは,モジュールシートと呼ばれる専用シートに記述します.前述のマクロ記録機能では,「Module1」というシートが自動的に追加作成されましたが,自分で作るには次のようにします.

[1] [挿入]-[マクロ]-[モジュール]を選択します.
[2] 新しいモジュールシートが挿入されますので,ここにマクロを記入します.
[3] マクロは一文字ずつキーボードから入力するか,マクロ記録で作成されたマクロを流用して作ります.たとえば,先ほどの「Record1」というマクロをコピーして流用してみましょう.「Re cord1」のマクロをコピーし,新しいモジュールシートに貼り付けてください.
[4] 「' Record1 マクロ」の行を「' Record2 マクロ」に,「Sub Record1() 」の行を「S ub Record2()」に変更します.また,「Selection.RowHeight = 20 」の行を「Select ion.RowHeight = 13.5」に変更します.
[5] たとえば「Sheet2」を選択して表示したあと,[ツール]-[マクロ]を選択します.この後,「Record2」のマクロを選択して実行してください.

 以後の説明では,原則としてモジュールシートに直接記入することにより,マクロを作成するものとします.マクロの実行方法は前項と同様です.

■オブジェクト
 VBAのマクロを作る上で最も注意すべき考え方は,オブジェクトです.オブジェクトとは,簡単にいえばVBAの操作対象のことであり,Excelのワークシートやセルなど多くのものがあります.VBAは,このオブジェクトに対していろいろな処理を行ないます.その処理の手順を記したものがVBAのプログラムということになります. VBAプログラムの単純な構造は次のとおりです.

Sub Rei()

ステートメント

End Sub

「Sub」の後に,マクロの名前(たとえば,Rei)を書き,「End Sub」までの範囲に処理内容に応じた命令を書きます.命令は,ステートメントと呼ばれます.なお,'(アポストロフィ)で始まる行はコメント(注釈)とみなされます.

■プロパティ
 オブジェクトに対する処理方法には,2種類あります.プロパティとメソッドです.プロパティとは,オブジェクトの属性です.プロパティに値を設定することにより,オブジェクトを制御できます.このときの形式は次のとおりです.

オブジェクト.プロパティ = プロパティの値

前出のマクロ「Record1」には,次のようなステートメントが含まれていました.

Selection.RowHeight = 20

の場合,「Selection」というのはオブジェクトではなくプロパティです.実は,「Selection」の前に「こApplication」というオブジェクトが省略された書き方になっているのです.したがって本当は次の意味になります.

Application.Selection.RowHeight = 20

ちなみに,Applicationオブジェクトとは,Excel自身のことを表しています.このため,Application.Selectionで選択されているオブジェクトが返されます.したがって,それに対して「RowHeight」つまり「行の高さ」を表すプロパティを適用することになります.その値に「20」を入れるわけですから,結局「行の高さ」を「20」に設定することになります.

■メソッド
一方,メソッドとはオブジェクトに対して行なえる操作のことです. メソッドはオブジェクトに作用し,働きかけます.メソッドの形式は次のとおりです.

オブジェクト.メソッド

前出のマクロ「Record1」には,次のようなステートメントが含まれていました.

Rows("1:5").Select

この場合も,「Rows」はオブジェクトではなくメソッドです.プロパティの場合と同様に,「Rows("1:5")」の前に「Application」というオブジェクトが省略された書き方になっているのです.したがって本当は次の意味になります.

Application.Rows("1:5").Select

このため,Application.Rows("1:5")でセル範囲を表すオブジェクトが返されます.それに対して「Select」つまり「オブジェクトを選択する」ことになります.したがって,1行目から5行目までの行のオブジェクトが選択されることになります.

■変数
 VBAプログラムの中で,一時的にデータを貯えておくための入れものとして変数があります.また,データにはその性質に応じた型があります.たとえば,整数データを表すInteger,オブジェクトを指し示すObject,真(True)と偽(False )のいずれかのみを表すBoolean,などの型があります. 変数は次の形式で宣言します.

Dim 変数名 [As データ型]

データ型は省略できますが,その場合は,いろいろなデータ型に対応できるバリアント型になります.たとえば,整数データを入れる変数として「a」という名前の変数を宣言するには次のようにします.

Dim a As Integer

■例1 計算
 それでは,簡単な計算を行なうマクロを作ってみましょう.ワークシート内の2つのデータを読み込んで四則演算を行ない,その結果をセルに格納します.まず,「shtRei1」というシートの中に,データなどを記入しておきます.セルA1 およびB1に,計算するデータを入れておきます.セルA3からA6には,計算結果の見出しとして「和」,「差」,「積」,「商」という文字を入れておきます.次のマクロをモジュールシートに記入した後,マクロを実行します.

'
' 例1 計算
'
Sub Rei1()

Dim a As Integer '「a」という整数型の変数を宣言する.
Dim b As Integer '「b」という整数型の変数を宣言する.

'ワークシート「shtRei1」をアクティブにする.
Worksheets("shtRei1").Activate

'セルA1の内容を変数aに入れる.
a = Worksheets("shtRei1").Range("A1").Value
'セルB1の内容を変数bに入れる.
b = Worksheets("shtRei1").Range("B1").Value

'a+bを計算してセルB3に入れる.
Worksheets("shtRei1").Range("B3").Value = a + b
'a-bを計算してセルB4に入れる.
Worksheets("shtRei1").Range("B4").Value = a - b
'a×bを計算してセルB5に入れる.
Worksheets("shtRei1").Range("B5").Value = a * b
'a÷bを計算してセルB6に入れる.
Worksheets("shtRei1").Range("B6").Value = a / b

End Sub

マクロを実行すると,四則演算の結果がそれぞれセルB3〜B6に格納されます.

■オブジェクト型変数の使い方
例1において,「a = Worksheets("shtRei1").Range("A1").Value」では,「Worksheets("shtRei1").Range("A1") 」に対して「Valueプロパティ」を用いてセルの値を取り出し,さらに「a」という変数に入れています.このとき,「Worksheets("shtRei1").Range("A1")」はワークシートのRangeオブジェクトを表しています.そこで,このオブジェクトを参照するオブジェクト型の変数を使うと次のように記述することができ,一度変数を宣言しておくと,マクロがすっきりしてわかりやすくなります.「a1」というオブジェクト型の変数を宣言するには次のようにします.

Dim a1 as object

オブジェクト型の変数へオブジェクトへの参照を入れるには,Setステートメントを使います.

Set a1 = Worksheets("shtRei1").Range("A1")

こうしておけば,「a = Worksheets("shtRei1").Range("A1").Value」と同じ働きを次のように簡単に記述することができるようになります.

a = a1.Value

例1のマクロを,オブジェクト型変数を利用して書き直すと次のようになります.

'
' 例1 計算
'
Sub Rei1a()

Dim a As Integer
Dim b As Integer
Dim a1 As Object '「a1」というオブジェクト型の変数を宣言する.
Dim b1 As Object '「b1」というオブジェクト型の変数を宣言する.
Dim wa As Object '「wa」というオブジェクト型の変数を宣言する.
Dim sa As Object '「sa」というオブジェクト型の変数を宣言する.
Dim seki As Object '「seki」というオブジェクト型の変数を宣言する.
Dim syou As Object '「syou」というオブジェクト型の変数を宣言する.

Worksheets("shtRei1").Activate

'セルA1への参照を変数a1に入れる.
Set a1 = Worksheets("shtRei1").Range("A1")
'セルB1への参照を変数aに入れる.
Set b1 = Worksheets("shtRei1").Range("B1")
'セルB3への参照を変数waに入れる.
Set wa = Worksheets("shtRei1").Range("B3")
'セルB4への参照を変数saに入れる.
Set sa = Worksheets("shtRei1").Range("B4")
'セルB5への参照を変数sekiに入れる.
Set seki = Worksheets("shtRei1").Range("B5")
'セルB6への参照を変数syouに入れる.
Set syou = Worksheets("shtRei1").Range("B6")

a = a1.Value
b = b1.Value

wa.Value = a + b
sa.Value = a - b
seki.Value = a * b
syou.Value = a / b

End Sub

■例2 判断
何らかの条件を判断し,その結果に応じて処理を選択して実行するには,If...Then...Else ステートメントを使います.Ifの後に書かれている条件が成り立てばThen以降の処理を実行し,そうでなければElse以降の処理を実行します.なお,Elseについては省略する書き方もあります.たとえば,セルB1に格納されている点数データを読み込んで,60点以上であれば"合格",そうでなければ"不合格"という文字をセルB3に格納するマクロは,次のように書くことができます.

'
' 例2 判断
'
Sub Rei2()

Dim Ten As Object
Dim Msg As Object

Worksheets("shtRei2").Activate

Set Ten = Worksheets("shtRei2").Range("B1")
Set Msg = Worksheets("shtRei2").Range("B3")

If (Ten.Value >= 60) Then
Msg.Value = "合格"
Else
Msg.Value = "不合格"
End If

End Sub

なお,マクロを実行する前に,シート「shtRei2」の中にデータなどを記入しておく必要があります.セルB1には,点数データを入れておきます.セルA1およびA3には,見出しとしてそれぞれ「点数」,「判定」という文字を入れておきます.マクロを実行すると,条件判断の結果がセルB3に格納されます(.

■例3 繰り返し(For...Next)
何らかの処理を繰り返して実行するには,For...Nextステートメントを使います.Forの後に書かれている繰り返し条件に従って,Nextまでの範囲の内容が繰り返し実行されます.たとえば,セルA1からA10に,1から10までの数値を順に格納するとともに,その合計を求めてセルA12に格納するマクロは,次のように書くことができます.

'
' 例3 繰り返し(For...Next)
'
Sub Rei3()

Dim Data As Object
Dim Sum As Object
Dim i As Integer
Dim s As Integer

Worksheets("shtRei3").Activate

Set Data = Worksheets("shtRei3").Range("A1:A10")
Set Sum = Worksheets("shtRei3").Range("A12")

s = 0
For i = 1 To 10
Data.Rows(i).Value = i
s = s + i
Next i
Sum.Value = s

End Sub

マクロを実行すると,結果がシート「shtRei3」に格納されます.

■例4 繰り返し(Do...Loop)
繰り返し処理には,Do...Looptステートメントを使う方法もあります.Loopの後に書かれた条件に従って,DoとLooptで囲まれた範囲の内容が繰り返し実行されます.たとえば,セルB1とB2に格納された2つの数値の最大公約数を求めて,セルB4に格納するマクロは,次のように書くことができます.

'
' 例4 繰り返し(Do...Loop)
'
Sub Rei4()

Dim x As Integer
Dim y As Integer
Dim r As Integer

Worksheets("shtRei4").Activate

x = Range("B1").Value
y = Range("B2").Value

Do
r = x Mod y
x = y
y = r
Loop Until y = 0
Range("B4").Value = x

End Sub

このマクロでは,最大公約数を求めるのに「ユークリッドの互除法」という方法を使用しています.「r = x Mod y」という命令は,xをyで割った余りを求めてrに格納します.また,「Loop Until y = 0」という命令は,yが0になるまで繰り返すことを示しています. マクロを実行すると,最大公約数がセルB4に格納されます.

■例5 多肢選択(Select...Case)
条件を判定して複数の処理のうちの一つを選ぶことを,多肢選択と呼びます.Select...Case ステートメントを使うと,Select Caseの後に書かれた条件に対応して,Case 以降に書かれた処理を選択して実行することができます.たとえば,太陽に近い順に惑星を並べると「Mercury,Venus,Earth,…」となりますが,その順序番号を指定すると惑星の名前が表示されるマクロは,次のように書くことができます.

'
' 例5 多肢選択(Select...Case)
'
Sub Rei5()

Dim i As Integer

Worksheets("shtRei5").Activate

i = Range("B1").Value
Select Case i
Case 1
Range("B3").Value = "Mercury"
Case 2
Range("B3").Value = "Venus"
Case 3
Range("B3").Value = "Earth"
Case 4
Range("B3").Value = "Mars"
Case 5
Range("B3").Value = "Jupiter"
Case 6
Range("B3").Value = "Saturn"
Case 7
Range("B3").Value = "Uranus"
Case 8
Range("B3").Value = "Neptune"
Case 9
Range("B3").Value = "Pluto"
End Select

End Sub

セルB1に順番の数字を入れてマクロを実行すると,惑星の名前がセルB3に格納されます.


基礎編

■記録マクロを併用する
 記録マクロを併用してマクロを作ってみましょう.そのためには,まず最初にワークシートに対する操作を一度行なってみます.
 ワークシートのセルに色をつけることを考えます.いま,あるセルの色を「赤」に設定したいものとします.しかし,いきなりマクロを記述するのは難しいので,まずワークシート上で動作を試してみます.
 あるセルの色を「赤」に設定するには次のようにします.

[1] 適当なワークシート上でマウスの右ボタンをクリックすると,ショートカットメニューが表示されます.
[2] [セルの書式設定]コマンドを選択します.
[3] [セルの書式設定]ダイアログボックスで,[パターン]パネルを選択します.
[4] 「セルの色」として「赤」を選び,をクリックします.
[5] セルの色が「赤」に設定されます.

 この後,[マクロの記録]コマンドを選択し,上の操作をもう一度行ないます.そうすると,たとえば次のようなモジュールが作成されますので,前回の知識を使って,このモジュールに手を加えていけばよいのです.

' Record1 マクロ
Sub Record1()
With Selection.Interior
.ColorIndex = 3
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
End With
End Sub

■関数について
 VBAマクロで使える関数には2種類あります.おなじみのExcel自身のワークシート関数とVBA専用の関数です.前者はExcelのワークシートでの処理を行なうためのものであり,後者はVBAプログラムの中での処理に使用するためのものです.
 どのような関数が使えるかは,Excelのオンラインヘルプを参照してください.ワークシート関数であればヘルプ・ウィンドウのタイトルは「Microsoft Excel 」であり,VBA関数であれば「Visual Basic リファレンス」となります.
 たとえば,VBA関数の「Rnd関数」は,0以上1未満の乱数を返します.したがって,「7 * Rnd」と書けば0以上6.999…までの乱数を得ることができます. また,Int関数は小数部分を切り捨てた整数値を返しますので,「Int((7 * Rnd) + 1)」で1から7までの整数乱数を得ることができます.

■例6 カラフルなワークシート
 前述の色の設定で作成したマクロに手を加えていきます.
 ColorIndexプロパティを使うと,カラーパレットのインデックス番号で色を指定することができます.たとえば,1,2,3,…,は,黒,白,赤,…,というように対応しています.そこで,インデックス番号を乱数で発生させてセルの色を設定すれば,カラフルなワークシートができるはずです.また,繰り返しなどの命令を付加していき,マクロを完成させます.
 「shtColorful」という新規ワークシートを準備した後,マクロを実行します.カラフルなワークシートが出来上がります.

' 例6 カラフルなワークシート
Sub Colorful()
Dim i As Integer
Dim j As Integer
Dim color As Integer

Worksheets("shtColorful").Activate

For i = 1 To 20
For j = 1 To 10
'1から7までの整数乱数を発生させる.
color = Int((7 * Rnd) + 1)
Worksheets("shtColorful").Cells(i, j).Select
With Selection.Interior
.ColorIndex = color
End With
Next j
Next i
End Sub

■コントロール
 ダイアログボックスに含まれているラベルやボタンなどの部品をコントロールと呼びます.実は,このコントロールはワークシート上にも配置することができます.
 コントロールを配置するには次のようにします.

[1] フォームのツールバーを表示するために,[表示]-[ツールバー]を選択します.
[2] [ツールバー]ダイアログボックスで[フォーム]にチェックを入れて,をクリックします.
[3] 「フォーム」ツールバーが表示されます.
[4] コマンドボタンを配置してみます.右側の列の上から2つ目がコマンドボタンですのでクリックして指定します.
[5] ワークシート上で,対角線状にドラッグすると,ボタンが生成されるとともに,[マクロの登録]ダイアログボックスが表示されます.
[6] このときボタンをクリックすれば,その後の操作内容をマクロとして記録できます.たとえば,表示されているワークシートを切り替えて「Sheet1」を選択するという操作を行なうと,「Sheets("Sheet1").Select」という機能のマクロがボタンに登録されることになります.

■例7 ホームページならぬホームシート
 インターネットのホームページでは,リンクにより自由自在にページ間を移動することができます.それと同じイメージで,各シートに配置されているボタンを押すとシートが切り替わるマクロです.
 前項の要領で,コマンドボタンにマクロを作成して登録します.
 なお,ボタンに表示されている文字を変更するには,ボタン上で右クリックしてからマウスをほんの少しだけ動かし,左クリックした後編集します.

'例7 ホームシート
' Record1 マクロ
Sub Record1()
Sheets("Sheet2").Select
End Sub

' Record2 マクロ
Sub Record2()
Sheets("Sheet1").Select
End Sub

' Record3 マクロ
Sub Record3()
Sheets("Sheet3").Select
End Sub

■例8 ワークシート掲示板!?
 次にワークシート間のデータ転送の例ということで,電子掲示板ならぬワークシート掲示板を作ってみました.
 データ転送は,[コピー]と[形式を選択して貼り付け]の機能を使って行なっています.
 なお,繰り返し時のセルの指定として,Format関数により数値を文字に変換した名前を使うというテクニックを使っています.また,セルD1には,次に掲示すべき行の番号を保存しています.

' 例8 ワークシート掲示板
' 掲示板入力 マクロ
Sub InputBBS()
Dim i As Integer

For i = 3 To 7 Step 2
Sheets("sht掲示板入力").Select
Range("B" & Format(i)).Select
Selection.Copy Sheets("sht掲示板").Select
Cells(Range("D1").Value, (i - 1) / 2).Select
Selection.PasteSpecial Paste:=xlValues, Operation:=xlNone, _
SkipBlanks:=False, Transpose:=False
Next i
Range("D1").Value = Range("D1").Value + 2
End Sub

' 入力クリアー マクロ
Sub Clear()
Range("B3").Select
Selection.ClearContents
Range("B5").Select
Selection.ClearContents
Range("B7").Select
Selection.ClearContents
Range("B3").Select
End Sub

■例9 カラーエディタ
 ホームページ作成時によく利用するのが,カラーのRGB値です.そこで,スクロールバーを使って色の確認ができるマクロを作ってみました.
 colorプロパティに色を設定するために,VBAのRGB関数を使用しています.
 また,ワークシートの中で10進数を16進数に変換するワークシート関数DEC2HEX を使用していますが,この関数を使う場合には「分析ツール」を組み込む必要がありますので,Excelのオンラインヘルプを参照してください.

' 例9 カラーエディタ マクロ
Sub ColorEdit()
Range("G7").Select
With Selection.Interior
.color = RGB(Range("B5").Value, Range("B7").Value, Range("B9").Value)
End With
Range("E5").Select
With Selection.Interior
.color = RGB(Range("B5").Value, 0, 0)
End With
Range("E7").Select
With Selection.Interior
.color = RGB(0, Range("B7").Value, 0)
End With
Range("E9").Select
With Selection.Interior
.color = RGB(0, 0, Range("B9").Value)
End With
Range("A1").Select
End Sub

■例10 MsgBox関数
 Windows環境では,ダイアログボックスが非常に多く使われます.MsgBox関数を使うと,メッセージを表示するためのダイアログボックスが簡単に作れます.
 Time関数を使って現在時刻を求め,時刻に応じたあいさつを表示するマクロです.
 なお,Chr関数は文字コードを指定して文字を返すもので,Chr(10)により改行動作を行ないます.

' 例10 MsgBox関数
Sub Greeting()
Dim Greeting As String
Worksheets("Sheet1").Activate
If (Format(Time, "h") Num) Then
Msg = Msg1 & "もっと大きい"
Else
Msg = Msg1 & "もっとちいさい"
End If
End If
MsgBox Prompt:=Msg, _
Buttons:=vbOKOnly + vbExclamation
Loop While (Atari = False)
End Sub

■例11 InputBoxメソッド
 InputBoxメソッドを使うと,入力操作を伴うダイアログボックスが作れます.
 1桁の数値の数当てゲームを行なうマクロです.

' 例11 InpuBoxメソッド
Sub Kazuate()
Dim Msg As String
Dim Msg1 As String
Dim Rndnum As Integer
Dim Num As Integer
Dim Atari As Boolean

Worksheets("Sheet1").Activate
Atari = False
'0から9までの乱数整数を発生させる.
Rndnum = Int(10 * Rnd)

Do Num = Application.InputBox( _
Prompt:="私の考えている数値を当ててください", _
Type:=1)

If (Rndnum = Num) Then
Msg = "当たり!"
Atari = True
Else
Msg1 = "はずれ!" & Chr(10)
If (Rndnum > Num) Then
Msg = Msg1 & "もっと大きい"
Else
Msg = Msg1 & "もっとちいさい"
End If
End If
MsgBox Prompt:=Msg, _
Buttons:=vbOKOnly + vbExclamation
Loop While (Atari = False)
End Sub

■例12 データの値によるセルの色分け
 これは少し実用的なマクロです.セル内のデータの値を判定し,セルに色をつけます.成績点数の判定や売り上げデータの選別などいろいろな場面で活用できます.
 処理の対象とするセル範囲をマウスのドラッグ操作により指定できます.これは,Inputメソッドにおいてダイアログボックスの返すデータの型(type)として「セル参照」を指定することにより可能になります.

' 例12 判定 マクロ
Sub Judge()
Dim r As Integer
Dim c As Integer
Dim hani As Object
Worksheets("shtData").Activate

Set hani = Application.InputBox( _
Prompt:="セルを選択してください.", _
Type:=8)

rmax = hani.Rows.Count
cmax = hani.Columns.Count

For r = 1 To rmax
For c = 1 To cmax
Cells(r, c).Select
If Selection < 59.5 Then
With Selection.Interior
.ColorIndex = 6
End With
Else
With Selection.Interior
.ColorIndex = 0
End With
End If
Next c
Next r
End Sub


活用編


 活用編では,本格的なマクロを作成する際に必要な技法を紹介します.サンプルとしては,切手入出庫処理,成績処理などを取り上げてみました.

■ユーザー定義のダイアログボックス
 前回,MsgBox関数やInputBoxメソッドを使うと簡単にダイアログボックスが作成できることを説明しました.しかし,非常に単純なダイアログボックスであり,定型的な様式のため自由な設定ができませんでした.
 そこで,本格的なマクロづくりのためには,ユーザー定義のダイアログボックスを作成することになります.つまり,ダイアログボックスの大きさやその中に配置するコントロールを自分で定義するのです.
 ユーザー定義のダイアログボックスを作成するには次のようにします.

[1] [挿入]-[マクロ]-[ダイアログ]を選択します.
[2] 新しいダイアログボックスの原型が準備された「ダイアログシート」が表示されます.
[3] 「フォームのツールバー」が表示されますので,前回のワークシートにコントロールを貼り付けた要領で,フォームにコントロールを配置します.
   フォームとは,ダイアログボックスのレイアウト枠のことです.
[4] サイズやタイトル(キャプション)の変更,フォームやコントロールの書式設定などを行います.
   コントロールの書式設定を行なうには,コントロール上で右クリックして,ポップアップメニューから[オブジェクトの書式]を選択します.
[5] 必要に応じて,タブオーダーを設定します.
   タブオーダーとは,[Tab]キーを押したときに選択されるオブジェクトの順番(オーダー)のことです.タブオーダーはオブジェクトを作成した順序に付けられますが,変更することも可能です.オブジェクトの作成順序がバラバラであった場合に,オブジェクトの作成順序とマクロからのインデックス番号による参照順序を対応させるときには変更する必要があります.
 タブオーダーを変更するには,コントロール上で右クリックして[タブオーダー]を選択します.
[6] ボタンなどのコントロールにイベントプロシージャを登録します.
イベントとは,マウスによるクリックやキー入力などの動作(事象)のことです.プロシージャとは,実行可能なマクロを意味します.イベントプロシージャとは,イベントの発生に対応して実行することができるプロシージャです.
 イベントプロシージャを登録するには,コントロール上で右クリックして[ マクロの登録]を実行します.

■例13 タイプ練習マクロ
 ユーザー定義のダイアログボックスを使用したマクロの作成例として,タイプ練習を行なうマクロを作ってみましょう.
 まず,タイプ練習のためのダイアログボックスを定義します.

[1] 新しいダイアログシートを挿入します.
[2] ボタンのオブジェクトを選択し,[Delete]キーで削除します.
[3] ボタンのオブジェクトをドラッグして下方に移動します.
[4] ボタン内をクリックして編集し,タイトル(キャプション)の文字列を「終了」に変更します.
[5] ラベルを3つ配置します.ラベルの文字列として,それぞれ,「練習文字」,「入力文字」,「A」と設定します.
[6] エディットボックスを1つ配置します.

次にイベントプロシージャを登録します.この例のマクロの場合には,テキストボックスにキー入力されることによって発生するイベントを利用します.従って,テキストボックス上で右クリックして[マクロの登録]を行ないます.
タイプ練習のマクロでは,まず,ラベルの文字列として表示するための英大文字1文字を乱数を使って発生させます.そして,上で定義したダイアログボックスを表示します.ダイアログボックスを表示するには,Showメソッドを使います.
タイプ練習を始めるマクロの内容は,次のとおりです.

' タイピング練習
Sub Typing()
Set dlgTyping = DialogSheets("dlgTyping")

dlgTyping.Labels(3).Text = Chr(65 + Int(26 * Rnd))
dlgTyping.Show
End Sub

練習文字に対してキーボードから文字が1文字入力されると,イベントプロシージャが起動し,正しく入力されたかどうかの比較判定を行ないます.誤った文字であれば,ブザーを鳴らします.そして,入力文字の確認表示のため,無駄な繰り返しにより時間をかせいだあと,エディットボックス内をクリアしてプロシージャを終了します.
イベントプロシージャとして登録するマクロの内容は,次のとおりです.

' Type_in マクロ
Sub Type_in()
Set dlgTyping = DialogSheets("dlgTyping")

If (dlgTyping.Labels(3).Text = dlgTyping.EditBoxes(1).Text) Then
dlgTyping.Labels(3).Text = Chr(65 + Int(26 * Rnd))
Else
Beep
End If

For i = 1 To 500000: Next i
dlgTyping.EditBoxes(1).Text = ""
End Sub

ボタンについては,キャンセルボタンの働きをするものですので,この場合はイベントプロシージャを登録する必要はありません.

■例14 モジュール・テスト・マクロ
 次に,複数のダイアログボックスおよび複数のプロシージャを含むマクロで,相互にプロシージャを呼び合うパターンを紹介します.
 メインとなるダイアログボックスから,サブとなる2つのダイアログボックスのうちどちらかを選択し,対応するワークシートを表示することができるものです.
 ユーザー定義のダイアログボックスを3つ作成します.
「メイン」ダイアログボックスにはコマンドボタンを2つ配置し,「サブ」のダイアログボックスを表示するためのイベントプロシージャを登録します.また,「サブ」のダイアログボックスのボタンには,ワークシートを表示するためのイベントプロシージャを登録するものとします.
 このモジュールテストを行なうマクロは次のようになります.

' モジュールテスト マクロ
Sub メイン()
Set dlgメイン = DialogSheets("dlgメイン")
dlgメイン.Show
End Sub

' サブ1実行_Click マクロ
Sub サブ1実行_Click()
Set dlgサブ1 = DialogSheets("dlgサブ1")
dlgサブ1.Show
End Sub

' シート1表示_Click マクロ
Sub シート1表示_Click()
Sheets("shtシート1").Activate
End Sub

' サブ2実行_Click マクロ
Sub サブ2実行_Click()
Set dlgサブ2 = DialogSheets("dlgサブ2")
dlgサブ2.Show
End Sub

' シート2表示_Click マクロ
Sub シート2表示_Click()
Sheets("shtシート2").Activate
End Sub

■切手入出庫処理
 ここまでで本格的なマクロ作りの準備ができましたので,ちょっとした業務処理を考えてみましょう.それは,切手入出庫処理の業務です.
 さて,業務処理となると今までのマクロのような単なる例とは異なり,まずその業務の内容をよく分析してみる必要があります.そして,行なうべき処理の内容を明確にする必要があります.
 いま,処理の概要を次のように想定します.

(1) ある部署における切手の入出庫の管理を行なう.
(2) 種類ごとの切手の在庫枚数が管理できる.入庫(受入),出庫(請求),現在庫の確認機能がある.
(3) 取り扱い担当者名を選択できる.
(4) 切手の在庫数を保存するために,ワークシート「sht切手残高リスト」を使用する.
(5) 入出庫区分および担当者のデータを管理するために,ワークシート「sht 管理」を使用する.
(6) メインのプロシージャを実行すると,[切手管理]ダイアログボックスが表示され,このとき切手の現在庫を確認できる.
(7) [切手管理]ダイアログボックスから[切手入出庫]ダイアログボックスを呼び出すことができ,入出庫区分,種類・枚数,担当を入力できる.
(8) 切手の入出庫時には,「切手入出庫票」を印刷する.ただし,このマクロはサンプルであるので実際の印刷は行なわず,印刷のプレビューのみ行なうものとする.

 切手入出庫処理を行なうマクロは次のとおりです.

Dim メニューNo As Integer
Dim i As Integer
Dim max As Integer
Dim zan As Object
Dim prntflg As Boolean

' 切手入出庫処理 マクロ
Sub メイン()
Set dlgメニュー = DialogSheets("dlgメニュー")
Set zan = Sheets("sht切手残高リスト").Range("B5:H5")
max = 7
prntflg = False

For i = 1 To max
dlgメニュー.Labels(i).Text = zan.Columns(i).Value
Next i

dlgメニュー.Show

If (prntflg = True) Then
Sheets("sht切手入出庫票").Activate
ActiveSheet.PrintPreview
End If
End Sub

Sub メイン2()
Set dlgメニュー = DialogSheets("dlgメニュー")
Set dlg入出庫 = DialogSheets("dlg切手入出庫")

dlg入出庫.Labels(8).Text = Format(Date, "ge/m/d") & " " & Format(Time, "h:m")
dlg入出庫.Show
dlgメニュー.Hide
End Sub

' 入出庫処理 マクロ
Sub 入出庫処理()
Set dlg入出庫 = DialogSheets("dlg切手入出庫")
Set zan = Sheets("sht切手残高リスト").Range("B5:H5")
Set nyusyutu = Sheets("sht切手入出庫票").Range("E6:E12")
Set kubun = Sheets("sht切手入出庫票").Range("B6:B7")
Set tantou = Sheets("sht切手入出庫票").Range("G4")
Set nitiji = Sheets("sht切手入出庫票").Range("G2")

If (Sheets("sht管理").Range("A3") = 1) Then
kubun.Rows(1) = "*"
kubun.Rows(2) = ""
For i = 1 To max
If (dlg入出庫.EditBoxes(i).Text "") Then
zan.Columns(i).Value = zan.Columns(i).Value + dlg入出庫.EditBoxes(i).Text
End If
Next i
Else
kubun.Rows(1) = ""
kubun.Rows(2) = "*"
For i = 1 To max
If (dlg入出庫.EditBoxes(i).Text "") Then
zan.Columns(i).Value = zan.Columns(i).Value - dlg入出庫.EditBoxes(i).Text
End If
Next i
End If
For i = 1 To max
nyusyutu.Rows(i).Value = dlg入出庫.EditBoxes(i).Text
Next i
nitiji.Value = Format(Date, "ge/m/d") & " " & Format(Time, "h:m")
tantou.Value = Sheets("sht管理").Range("B3:B5").Rows(Sheets("sht管理").Range("B2").Value).Value
prntflg = True
End Sub

■「リンクするセル」の指定
 オプションボタンは,グループ内のどれか1つのオプションを選択するためのコントロールです.そのため,一般にオプションボタンはグループボックスで囲みます.
 区分として入庫と出庫という2つの選択肢を準備し、どちらかを選びぶものとします.このような処理には,オプションボタンが最適です.
 さて,マクロから,どちらのボタンが選択されたかを調べるにはどうすればよいのでしょうか?
 簡単な方法としては,「リンクするセル」を使う方法です.「リンクするセル」の機能を使うと,選択されたボタンを示すインデックス番号がセル内に自動的に設定されます.
 いま,「sht管理」という名前のワークシートを準備し,セルA3にリンクするものとします.
手順は次のとおりです.

[1] オプションボタン上で右クリックして,[オブジェクトの書式設定]を選択します.
[2] 「コントロール」パネル内の「リンクするセル」のエディットボックスをクリックします.
[3] リンク先を指定します.つまり,ワークシート「sht管理」のセルA3をクリックして選択します.すると,「sht管理!$A$3」のように表示されます.
[4] <OK>をクリックします.

 それでは,動作を確かめてみましょう.ワークシート「sht管理」を表示してください.[ツール]-[マクロ]を選択し,「メイン」を選んでマクロを開始します.さらに,[切手入出庫]ダイアログボックスを表示させます.この状態で,オプションボタンを押してみてください.セルA3の内容が変化するはずです.入庫のときは「1」,出庫のときは「2」が入りますので,この内容をマクロから読み込んで処理に使えばよいわけです.

■「入力範囲」の指定
 ドロップダウンリストボックスは,選択項目のリスト(一覧)がドロップダウンして表示されるコントロールです.
 このマクロでは,担当者の名前を一覧から選択するために使用します.
 ドロップダウンリストボックスを使用するときには,2つのことを考えなければなりません.1つは,何番目の項目が選択されたかということですが,これは前述の「リンクするセル」を使います.もう1つは,リストボックスに表示するデータ自身の設定です.これを行なうには,「入力範囲」の指定という方法を使います.手順は,前述の「リンクするセル」の場合とほぼ同じです.

[1] ドロップダウンリストボックス上で右クリックして,[オブジェクトの書式設定]を選択します.
[2] 「コントロール」パネル内の「入力範囲」のエディットボックスをクリックします.
[3] 表示したいデータの入力範囲を指定します.つまり,ワークシート「sht 管理」のセル範囲B3:B5をドラッグして選択します.すると,「sht管理!$B$3:$B$5 」のように表示されます.
[4] をクリックします.

■データ処理の基本
 さて,いよいよ最後に成績処理を行なうマクロを作成しますが,その前に重要なことを考えておきましょう.それは,データ処理の基本は何かということです. データ処理の基本の一つは,「一覧データと個別データの変換」であろうと思います.Excelという表計算ソフトであってもAccessのようなデータベースソフトであっても,本質は同じではないかと考えます.
 つまり,一覧データと個別データについて入力と出力が自由にできればよいわけです.
 「個別データ←→個別データ」および「一覧データ←→一覧データ」の様式変換は比較的簡単なのですが,「個別データ←→一覧データ」の変換(扱い)はやや難しいといえます. このことは,表計算ソフトにしろデータベースソフトにしろ,内部の処理でやらねばならないことは,本質的に同じといえます.つまり,2つのデータの場所のリンク(つながり)をどう扱うかです.
 一般的に,データ間のリンクの扱いという点ではデータベースソフトが優れています.一方,一覧データの扱いでは表計算ソフトの方が優れているといえます.
 それでは,表計算ソフトにおける,「一覧データ→個別データ」への変換(抽出)処理を考えてみましょう.比較的簡単な方法は,まず,一覧データの1件分のデータを抜き出して作業領域(作業シート)に複写し,そのデータを個別データにリンクする方法です.一覧データでは個別のデータの位置(行)が変化しますのでこれを変数で処理して,抽出先の作業領域へ繰り返して抜き出します.

■成績処理
 成績処理の一機能として,生徒の成績一覧表から個人別の成績を抽出し,個人成績票として印刷処理を行なうマクロを作ってみます.処理の概要は次のとおりです.

(1) ダイアログボックスでメニューを表示し,全員印刷または個人印刷の処理が選択できる.
(2) 個人印刷処理では,ドロップダウンリストボックスで,印刷したい生徒の番号を選択できるほか,直接,番号を入力しても指定できる.
(3) 全員印刷,個人印刷ともに1人の処理が終われば,次の番号の生徒へ処理が移る.

「メイン」プロシージャでは,[印刷メニュー]ダイアログボックスのコマンドボタンによって選択された処理の切り分けを行ないます.全員印刷処理は個別処理の繰り返しとして実現します.一覧データから作業領域へのデータのコピーはマクロで処理を行ないます.このとき,範囲名を利用していますので,それぞれのワークシートのセル範囲にあらかじめ名前をつけておく必要があります.一方,作業領域と個人成績票とのデータのやり取りはマクロでは行なわず,個人成績票から作業領域の各項目への参照という形態をとっています.したがって,各項目に参照の式を設定しておく必要があります.
 成績票の印刷を行なうマクロは次のとおりです.

Dim メニューNo As Integer
Dim i As Integer
Dim max As Integer

' 成績票印刷 マクロ
Sub メイン()
Set dlgメニュー = DialogSheets("dlgメニュー")
max = 3
Sheets("sht抽出").Range("A2").Value = 1

Do
dlgメニュー.Show
Select Case メニューNo
Case 1:
全員印刷
Case 2:
個別印刷
End Select
Loop Until メニューNo = 0
End Sub

' 全員印刷_Click マクロ
Sub 全員印刷_Click()
Set dlgメニュー = DialogSheets("dlgメニュー")
メニューNo = 1
dlgメニュー.Hide
End Sub

' 個人印刷_Click マクロ
Sub 個人印刷_Click()
Set dlgメニュー = DialogSheets("dlgメニュー")
メニューNo = 2
i = Sheets("sht抽出").Range("A2").Value
dlgメニュー.Hide
End Sub

' メイン終了_Click マクロ
Sub メイン終了_Click()
Set dlgメニュー = DialogSheets("dlgメニュー")
メニューNo = 0
dlgメニュー.Hide
End Sub

' 全員印刷 マクロ
Sub 全員印刷()
For i = 1 To max
個別印刷
Next i
End Sub

' 個別印刷 マクロ
Sub 個別印刷()
Set src番号 = Sheets("sht成績一覧").Range("s番号")
Set src氏名 = Sheets("sht成績一覧").Range("s氏名")
Set src英語 = Sheets("sht成績一覧").Range("s英語")
Set src数学 = Sheets("sht成績一覧").Range("s数学")
Set src国語 = Sheets("sht成績一覧").Range("s国語")
Set dst番号 = Sheets("sht抽出").Range("d番号")
Set dst氏名 = Sheets("sht抽出").Range("d氏名")
Set dst英語 = Sheets("sht抽出").Range("d英語")
Set dst数学 = Sheets("sht抽出").Range("d数学")
Set dst国語 = Sheets("sht抽出").Range("d国語")

Sheets("sht個人成績").Activate
dst番号.Value = src番号.Rows(i)
dst氏名.Value = src氏名.Rows(i)
dst英語.Value = src英語.Rows(i)
dst数学.Value = src数学.Rows(i)
dst国語.Value = src国語.Rows(i)
ActiveSheet.PrintPreview

If (i < max) Then
Sheets("sht抽出").Range("A2").Value = i + 1
End If
End Sub


■参考文献


ご注意
 本マクロの利用・改変・配布等は自由です。
 著作権は、内田保雄(Yasuo Uchida)に帰属します。
 本マクロは学習用のサンプルとして作成したものであり、運用上生じた直接あるいは間接的な損害については一切補償いたしかねますので、利用者個人の責任で運用くださるようお願いします。


(since Sep 18, 1996)

ご意見・ご感想をお寄せください。
E-mail yasuo@uchidas.com



Copyright (c) 1996 Yasuo Uchida