|
それでは実際のT'sKitでの使用例を見ていきましょう。
InsertCode:
If Me!fraInsertPosition = 3 Then
'新規プロシージャとして挿入するときはモジュールの末尾にコードを挿入
mdl.InsertText vbCrLf & strInsertCode
ElseIf strProcName = "(Declarations)" Or strProcName = "" Then
'Declarationsへ挿入するとき
lngEndDeclaration = mdl.CountOfDeclarationLines
If Me!fraInsertPosition = 1 Then
'Declarationsセクションの先頭に挿入
mdl.InsertLines 1, strInsertCode
Else
'Declarationsセクションの最後に挿入
mdl.InsertLines lngEndDeclaration + 1, strInsertCode
End If
Else
'プロシージャに挿入するとき
With mdl
'プロシージャの行数
lngCount = .ProcCountLines(strProcName, vbext_pk_Proc)
'プロシージャ全体の開始行番号
lngStartLine = .ProcStartLine(strProcName, vbext_pk_Proc)
'プロシージャ宣言行の行番号
lngBodyLine = .ProcBodyLine(strProcName, vbext_pk_Proc)
'プロシージャの最終行
lngEndProc = (lngBodyLine + lngCount - 1) - Abs(lngBodyLine - lngStartLine)
If Me!fraInsertPosition = 1 Then
'プロシージャの先頭に挿入
.InsertLines lngBodyLine + 1, strInsertCode
Else
'プロシージャの最後に挿入
.InsertLines lngEndProc, strInsertCode
End If
End With
End If
Return
このサンプルコードは、今回の話しの中心である"モジュールにコードを挿入する"処理の中心となるサブルーチンだけを抜き出したものです。この中で "mdl" は Moduleオブジェクト変数 です。この変数を使うにはその宣言(Dim mdl As Module)はもちろんですが、あらかじめフォームや標準モジュールを開いた上でこの変数への代入を行わなければなりません。これについては「#04 モジュールのプロシージャをリストアップ」で触れていますので、そちらを参照してください。 |
|
まずこのコードで使われているModuleオブジェクトのいくつかのプロパティについて簡単に説明します。
CountOfDeclarationLines プロパティ
このプロパティは、Declarationsセクションに記述されたコードの行数を返します。図の例では
5 が返されます。
ProcCountLines プロパティ
このプロパティは、最初の引数に指定したプロシージャのコードの行数を返します。これには"Function xxxx()"という宣言行や"End Function"などの行、さらに宣言行の前のコメント行や空行も含まれます。これは、モジュールウィンドウを連続表示にしたとき各プロシージャの境目に横線が引かれますが、この線と線に囲まれている行数と考えてください。図の例では
12 が返されます。なお、2つ目の引数にはプロシージャの種類を指定する組み込み定数を与えます。SubまたはFunctionプロシージャの場合は vbext_pk_Proc です。
ProcStartLine プロパティ
プロパティ名の単語からも想像できるように、指定のプロシージャの記述(コメント行や空行も含みます)が始まる行の番号を返します。この行番号とは、Declarationsセクションの最も上の行を"1"とするモジュール全体から見た番号です。2つ目の引数には[ProcCountLines]プロパティと同じく、プロシージャの種類を指定する組み込み定数を与えます。図の例の"IsLoaded"プロシージャでは
6 が返されます。
ProcBodyLine プロパティ
このプロパティは、指定のプロシージャの"Function xxxx()"のような宣言行の行番号(これもモジュール全体から見た番号です)を返します。図の例の"IsLoaded"プロシージャでは
9 が返されます。 |
|
|
続いて、今回の重要ポイントであるInsertLinesメソッドとInsertTextメソッドの構文を確認しておきましょう。
[Moduleオブジェクト変数].InsertLines <挿入先行番号>, <挿入するコード(文字列)>
ここで"挿入先行番号"は、前述の、モジュール全体から見た行番号です。したがって、もしあるプロシージャの先頭に変数の宣言を挿入したいような場合には、まずそのプロシージャがモジュール全体の何行目から始まるかを調べる必要があるわけです。また、挿入するコードは1行だけのこともあるでしょうが、複数の行をまとめて挿入したい場合にはこのメソッドを行数分繰り返す必要はなく、改行コード(定数 vbCrLf)を使えば1回で済ませることができます。なおこのメソッドを実行すると、もともと挿入先の行番号以降にあったコードは挿入された行数分下へシフトされます。 |
[Moduleオブジェクト変数].InsertText <挿入するコード(文字列)>
InsertTextメソッドはInsertLinesメソッドのような挿入行番号の引数は用いません。なぜなら、そのモジュール全体の一番最後に追加挿入するものだからです。新しいプロシージャなどをまとめて挿入したい場合には、InsertLinesメソッドでもできないことはありませんが、行番号の計算が要らない分、こちらのメソッドを使った方が楽でしょう。 |
|
それでは、T'sKitで使っているサンプルコードに戻って、その手順を説明していきましょう。
まず「挿入先プロシージャ」のオプショングループ"fraInsertPosition" の値や挿入先の「プロシージャ名」によって処理を分岐します。"3"は「新規プロシージャ」のオプション値です。また変数strProcNameには、あらかじめテキストボックス「プロシージャ名」への入力値がセットされています。ここではコードを新規プロシージャとして挿入するか、Declarationsセクションに挿入するか、あるいは既存のプロシージャの一部として挿入するかによって処理が分かれることになります。
新規プロシージャとして挿入する場合には、前のInsertTextメソッドのところで説明した通り、テキストボックス「挿入するコード」の文字列だけを引数としてそのメソッドを実行すれば処理は完了です。 |
続いてDeclarationsセクションに挿入する場合には、まず[CountOfDeclarationLines]プロパティを使ってセクション全体の行数を調べ、変数lngEndDeclarationにセットします。そして、挿入先がプロシージャの「先頭(オプション値=1)」の場合には1行目に、「最後(オプション値=2)」の場合には lngEndDeclaration + 1 行目、つまりDeclarationsセクションの一番下の行の次の行をターゲットにInsertLinesメソッドを実行します。
既存のプロシージャに挿入する場合もやり方はいっしょですが、挿入先の行番号の計算がちょっと面倒です。前述のプロシージャ関連の情報を取得するためのプロパティを使って、指定プロシージャの全行数、コメント行や空行を含めた全体の開始行番号、宣言行の開始行番号、そしてそれらの値から"End Function"などのプロシージャの最終行の行番号を算出して、それぞれ変数にセットします。そして最後にそれらの変数をInsertLinesメソッドの引数として実行します。 |
|
以上のように、AccessのVBAを使えばモジュール自体に自動的にコードを挿入することも可能となります。データベースアプリケーションそのものでは使い道はないかもしれませんが、VBAによるコーディング作業の効率化のために、開発時だけのオリジナルプロシージャなどで利用してみてはいかがでしょうか?。 |