SeaGate HomePage 別館
本館 別館 ブログ
 
トップページ
第01回
第02回
第03回
第04回
第05回
第06回
第07回
第08回
第09回
第10回
第11回
第12回
第13回
第14回
おまけ
VBAではじめるAutoCADカスタマイズ VBAではじめるAutoCADカスタマイズ
第8回 プログラムのモジュール化

■ はじめに

この連載も第8回目となり、AutoCAD VBAでプログラムを作成するために必要な基礎知識について一通りの説明が終わりました。いよいよ本格的なプログラムを作成するための準備が整ったわけですが、単語や熟語、文法を学習したからといってすぐに文章が書けるわけではないように、実際にプログラムを作成するためにはいくつかのテクニックが必要です。今回は、プログラム全体を構成し、モジュール化するための手法について説明します。

■ モジュール

連載第1回目で、VBAプログラムはプロジェクトという単位で管理され、1つのプロジェクトには複数の標準モジュールなどを含めることができると説明しました。モジュールとは関連するプログラムコードを一まとまりにして記述し、格納するためのVBAの基本単位で、一つのコードウィンドウが一つのモジュールに対応しています。モジュールはモジュールの先頭部分にあってプロジェクトやモジュール全体に関わる定数や変数などを宣言する宣言セクションと、後述するプロシージャを記述する領域から構成されます。

VBAプロジェクトの構成
VBAプロジェクトの構成

これまでのサンプルプログラムでは、いつもプロジェクトエクスプローラの「ThisDrawing」をダブルクリックしてプログラムコードを記述してきましたが、ユーザがプロジェクトに標準モジュールを新たに追加してプログラムコードを記述することもできます。「ThisDrawing」が現在アクティブな図面と密接に関連し、主にその図面を対象とした処理を記述するのに対し、標準モジュールは個々の図面とは独立した汎用的な処理を記述する場合に多く用いられます。

プロジェクトに標準モジュールを追加するには、プロジェクトエクスプローラで標準モジュールを追加するプロジェクトを選択し、[挿入]メニューの[標準モジュール]をクリックします。プロジェクトエクスプローラで新たに追加した標準モジュールをダブルクリックするとコードウィンドウが開き、プログラムコードの入力を行うことができます。


ThisDrawing

ThisDrawingとは、ExcelやWord VBAのThisWorkbookやThisDcumentのように、現在アクティブな図面(Documentオブジェクト)自身を表わすAutoCAD VBAのキーワードです。AutoCADのDocumentオブジェクトにはクラスモジュールを関連付けることができるので、プロジェクトエクスプローラでThisDrawingをダブルクリックして開いたコードウィンドウは、現在アクティブなDocumentオブジェクトに関連付けられたクラスモジュールであると考えることができます。

ExcelやWordと違ってAutoCADはVBAプロジェクトをグローバルプロジェクトとして独立したファイルに保存することができます。ThisDrawingは、グローバルプロジェクトの場合は、ApplicationオブジェクトのActiveDocumentプロパティと同様、現在AutoCADでアクティブになっている図面を指し示しているのに対して、図面に埋め込まれたVBAプロジェクトでは、現在AutoCADでアクティブになっている図面に関わらず、常にそのVBAプロジェクトが含まれているDocumentオブジェクトを指し示します。

■ プロシージャ

これまでのサンプルプログラムでは、いつも「Sub」から「End Sub」の間に実際の処理を行うプログラムコードを記述してきました。この「Sub」から「End Sub」までのことをプロシージャ(Procedure)といい、一連の処理として実行するために記述したプログラムコードのまとまりです。VBAでは実行可能なプログラムコードはすべてプロシージャ内に記述する必要があり、プロシージャには下表に示すようにSubプロシージャの他にFunctionプロシージャなどもあります。

プロシージャからは別のプロシージャを呼び出すことができ、呼び出したプロシージャに記述された処理が終了すると呼び出し元のプロシージャに処理が戻って実行が再開されます。また、プロシージャは呼び出し元から引数として定数や変数、式などの値を受け取り、プロシージャ内部の計算などに利用することができます。ただし、引数は呼び出し元と呼び出し先で同じ数、同じデータ型とする必要があります。

プロシージャの種類
Subプロシージャ 一連の処理を実行するが、呼び出し元に値を返さないプロシージャ。
Functionプロシージャ 一連の処理を実行した結果、呼び出し元に値を返すプロシージャ。関数とも呼ばれる。

プロシージャの書式
書式:  Sub [プロシージャ名] [(引数リスト)]
  [処理]
End Sub

Function [プロシージャ名] [(引数リスト)] As [戻り値のデータ型]
  [処理]
  [プロシージャ名] = [戻り値]
End Function

Subプロシージャはプロシージャ名の後に呼び出し元から受け取る引数のリストを括弧で囲んで宣言し、呼び出し元ではCall ステートメントの後にプロシージャ名と引数を括弧で囲んだものを指定して呼び出します。

Functionプロシージャ(関数)は呼び出し元に値を返すので、変数と同じようにAsキーワードを使用してデータ型を宣言し、関数を終了する前に戻り値を「プロシージャ名 = 戻り値」の形式で設定します。また、呼び出し元では式の中で関数を同じデータ型の変数に代入するなどして使用し、呼び出し元で関数の戻り値を利用しないときはSubプロシージャと同様、Callステートメントを使用して呼び出すこともできます。

プロシージャ内に「Exit Sub」や「Exit Function」ステートメントを記述するとプロシージャを強制的に終了させることができ、プログラムの実行が直ちに呼び出し元のプロシージャに戻ります。また、一番初めに実行されたプロシージャで「Exit Sub」や「Exit Function」ステートメントが実行された場合は、プログラム全体が終了します。「Exit Sub」や「Exit Function」ステートメントはプロシージャ内の任意の場所に必要に応じていくつでも記述することができます。

プログラムが大規模で複雑なものになると、何度も同じような処理を記述したり一つのプロシージャに記述するプログラムコードの量が増えてプログラム全体の見通しが悪くなります。このような場合、プログラムを用途別や機能別のプロシージャに分割して作成するとプログラムの管理がしやすくなり、プログラムの修正やデバッグなども容易になります。ちょうど建物のプランを検討する時、モジュールごとにプランニングしたりゾーニングするようなものです。

プロシージャの使用例
> プログラムコードを別ウィンドウで表示 ※ 行番号を入力する必要はありません

■ スコープレベル

変数や定数、プロシージャなどにはスコープレベル(適用範囲)があり、プロジェクト内やモジュール内、プロシージャ内などの定められた範囲でしか利用したり呼び出したりすることができません。変数が値を保持する期間を変数の有効期間といい、変数が適用範囲外となってその有効期間が終了するとその値が破棄され、変数に値を格納するために確保されていたメモリも解放されます。変数や定数、プロシージャなどの適用範囲は宣言された場所や方法によって決まり、プロシージャレベル、モジュールレベルおよびグローバルレベルの3つのレベルがあります。

変数や定数、プロシージャの適用範囲
変数や定数、プロシージャの適用範囲

◆ プロシージャレベル

DimステートメントやConstステートメントを使用してプロシージャ内で宣言された変数や定数はプロシージャレベルになります。プロシージャレベルの変数や定数はそのプロシージャ内でしか利用することができないので、主にプロシージャ内で一時的に利用する変数や定数として使用されます。プロシージャレベルの変数や定数はそのプロシージャが終了するときに有効期間が終了してその値が破棄されます。

◆ モジュールレベル

標準モジュールなどの宣言セクション(モジュールの先頭から最初のプロシージャまでの領域)でPrivateステートメントを使用して宣言した変数や定数とPrivateキーワードを付けて宣言したプロシージャはモジュールレベルになります。モジュールレベルはプロシージャレベルよりも範囲が広いスコープレベルで、モジュールレベルの変数や定数、プロシージャは同一モジュール内のすべてのプロシージャからのみ利用することができます。

◆ グローバルレベル

標準モジュールなどの宣言セクションでPublicステートメントを使用して宣言した変数や定数とPublicキーワードを付けて宣言したプロシージャはグローバルレベルになります。グローバルレベルは最上位のレベルで、プロジェクトに含まれるすべてのモジュールのプロシージャから利用することができます。モジュールレベルやグローバルレベルの変数や定数はプログラムが終了するまでその値が保持されます。

プロシージャレベル 変数 Dim X As Integer
定数 Const Y As String = "Test"
モジュールレベル 変数 Private X As Integer
定数 Private Const Y As String = "Test"
プロシージャ Private Sub Z()...End Sub
グローバルレベル 変数 Public X As Integer
定数 Public Const Y As String = "Test"
プロシージャ Public Sub Z()...End Sub

スコープレベルは変数や定数、プロシージャの管理に役に立ちます。例えばプログラムで使用する変数がすべてグローバルレベルだとすると、すべてのプロシージャでその値が変更される可能性があるため、どのプロシージャがどのようにその変数を利用しているか常に意識していなければプログラムを意図した通りに動作させることができません。変数や定数、プロシージャの適用範囲を限定すれば、他のプロシージャでその値が変更される可能性は考えなくてもよいので、いま記述しているプロシージャのプログラムコードのみに注意を払えばよいことになります。

エントリーポイント

AutoCAD VBAではグローバルレベルのSubプロシージャだけが[マクロ]ダイアログボックスに表示され、[実行]ボタンを押すとそのプロシージャを起点にしてプログラムの実行が開始されます。このように実行時に一番初めに呼び出されるプロシージャをプログラムのエントリーポイントといいます。

プロジェクトに複数のグローバルレベルのSubプロシージャを作成すると、一つのプロジェクトで複数の実行可能なプログラムをユーザに提供することができます。逆に本来エントリーポイントにするべきでないプロシージャをグローバルレベルに設定してしまうと、ユーザによって誤って実行されてしまう可能性があるため、このようなプロシージャは必ずPrivateキーワードを付けてモジュールレベルとして宣言します。


■ 最後に

プログラミング言語も長い歴史を経てより効率的でバグの少ないプログラムコードが記述できるように進化してきました。今回説明したモジュールやプロシージャ、スコープレベルなどは現代的なプログラミング言語の多くが備える機能で、プログラムを論理的かつ構造的に記述する上で重要なものです。次回はAutoCAD VBAを使用して簡単なゲームを作成してみたいと思います。ゲームを楽しみながら少し本格的なプログラムに取り組んでみましょう。
SeaGate
コレクション



inserted by FC2 system