|    | 
     ▼かず さん: 
>▼かず さん: 
>>▼β さん: 
 
 サンプルコードに誤字があったので修正しました。 
 
4.サンプルコードの解説 (井川春樹さんの本から抜粋) 
 
'************************************************************* 
' 井川さんのサンプルコードの解説 
'************************************************************* 
では(1)から順に見ていきましょう。 
 まず、1行目でEventステートメントを使ってイベントを宣言しています。このクラスは 
Rowslnsertというイベントを発行して、そのイベントプロシージヤは、CancelというBoolean d 
の引数を参照渡しで受け取りますよ、といった宣言になります。 
 
CheckRowsInsertメソッドは、この後解説するタイマー処理によって繰り返し実行され、 
行が挿入されたタイミングでイベントを発行するメソッドです。 
 
ここで重要なのは、Static変数「myRow」が最終行を表すRangeオブジェクトへの参照を保持していることです。 
 
初めて実行されるときだけは変数「myRow」が「Nothing」なので、その場合には最終行を 
表すRange オブジェクトへの参照を格納するだけの処理を行いますが、2回目以降には 
いよいよチェックを行います。 
 
このチェックには、On Error Resume Nextステートメントを使って、実行時エラーを 
無視するようにしてから、変数「myRow」に参照が格納されているRangeオブジェクトの 
何らかのプロパティを取得してみるのが簡単です。 
 
ここではRowプロパティを取得していますが他のプロパティでもかまいません。 
このとき、行が挿入されていれば最終行は存在しなくなっているのでエラーが発生します。 
ですから、「エラーの発生=行が挿入された」と判断できるわけです。エラーの発生の 
有無はErr関数を使って参照を取得できるErrObjectオブジェクトのNumberプロパティ 
で判断できます。 
 
エラーが発生していなければNumberプロパティの値が「O」となるからです。 
そして、行が挿入されたと判断したらRaiseEventステートメントを使ってRowslnsert 
イベントを発行します。引数Cancelには変数[myCancel]を指定し、イペントプロシー 
ジヤによって、変数.[myCancel」の値が「True」に変更される(引数Cancelに「True」 
が設定される)と、ApplicationオブジェクトのUndoメソッドを使って、行挿入の操作 
を元に戻します。 
 
次に(2)のコードをご覧ください。これはタイマープロシージヤと呼ばれるプロシー 
ジヤで、この後解説するWin32API関数のSetTimer関数の引数lpTimeerFuncにこのプロ 
シージヤのアドレスを指定すると、繰り返し非同期で実行されるようになります。 
 
宣言部については決まり事として覚えておいてください。ここで行っている処理は、 
clsRowsInsertEventオブジェクトのCheckRowsInscrtメソッドを実行するといった 
ものです。 
 
clsRowsInsertEventオブジェクトへの参照は、?Bのコードで定義している 
ThisWorkbookクラスのRowsInsertEventClassプロパティを使って取得します。 
 
最後に(3)のコードの要点をまとめます。 
まず、このブックモジュールでclsRowsInsertEventオブジェ列が発行するイベント 
をハンドルするために、モジュールレベルのオブジェクト変数 
「mvRowsInsertEventClass」を、WithEventsキーワードを付けて 
、cIsRowsInsertEvent型で宣言します。 
 
そして、そのclsRowsInsertEventオブジェ列のRowslnsertイペントプロシージャに、 
行挿入時に実行する処理を記述します。ここでは、キャンセルするかどうかの 
問い合わせのみを行っています。 
 
タイマー処理の開始はブックのOpenイベントプロシージャで、終了はBeforeCloseイベント 
ブロシージャで行います。 
 
タイマー処理を開始するのはWin32API関数のSetTimerで、引数HwndとnlDEventには0を、 
nElapseにはタイマー処理を実行する問隔(ミリ秒)を、lpTimerFunc にはタイマー 
プロシージャのアドレスを指定します。プロシージャのアドレスはAddressOf演算子を 
使って取得します。 
 
なお、サンプルではnElapseに「O」を指定していますが、当然ですがOミリ秒ごとに処理 
を繰り返すといった非現実的なことは不可能です。このような場合処理できる極めて 
微小な時間単位で処理が繰り返されます。 
 
SetTimer関数の戻り値はタイマーIDと呼ばれる識別子で、 
KillTimer関数のnIDEventに指定することでタイマー処理を終了できます。 
サンプルでは、ブックのBeforeCloseイベントプロシージャの処理に保存確認の 
ロジックを内包しているのは、BeforeCloseイペントプロシージャの処理によって 
タイマー処理(イベント発行のための監視)を完了してから、Excelの機能によって 
保存確認が行われた場合にキャンセルすると、イベントをハンドルできない状態で 
開かれたままになるからです。 
 
さて(3)のコードの最後で定義しているRowsInsertEventClassプロパティの内容 
はまったく難しいものではありません。モジュールレベル変数 
[my RowsInsertE vent Class]が「Nothing」であれば新たにインスタンスを生成 
してから、その参照を返すプロパティです。 
 
しかし1つだけ重要なことがあります。 
このようにして外部にclsRowsInsertEventオブジェクトヘの参照を返す(公開する) 
場合には、clsRowsInsertEventクラスのInstancingがデフォルトのPrivate]のまま 
ではいけないからです。 
 
このような場合には、あらかじめ[プロパティ]ウインドウを使ってInstancingを 
[PublicNotCreatable]に設定しておきます。 
 
ポイント 
タイマー処理中に実行時エラーが発生すると、Excelが即座に落ちてしまいます。 
万が一にもそのようなことがないように、絶対に実行時エラーが発生しない処理 
でない限り、必ずOn Error Resume Nextステートメントを付けるようにしましょう。  
-- 
 
 | 
     
    
   |