パソコン活用研究5番街(Visual Basic、Excel(VBA)、BASIC プログラミング研究)

                VB&VBA-オブジェクトとイベント


1 はじめに
旧BASICとくらべてVBの一番大きな違いは、オブジェクトとイベントではないでしょうか。
オブジェクト、イベントについての説明は、数多くのVB入門書が出ておりますので、私が変な
説明をするよりそちらににおまかせします。
といって、何も言わずに過ぎてしまうのも、ちょっと無責任な気がするで、おじさん流にごく簡単に
説明してみます。まず今回はイベントについて説明します。

2 イベントドリブン
Visual Basicはイベントドリブン型のプログラムになります。はじめて、「イベントドリブン」とかいう単語を聞
いた人は、それだけでなにやら難しそーと思ってしまうかもしれませんが、ぜんぜんたいしたことはありません。

まず、「イベント」ですが、わかり易いところでは、「マウスをクリックした」、「ダブルクリックした」、「キーを押した」
という普段Windowsでやっている操作がみなイベントです。(イベントについては後で詳述します)
イベントドリブンとは、このイベントの発生によってプログラムが進行する、ということです。
言葉の説明ではわかりにくいので、例をあげてみましょう。

例えばFORMをCLICKした時に、"HELLO"とFORMに表示するプログラムを考えてみます。
FORMをCLICKするというのがイベントです。このイベントにより、"HELLO"と表示するプログラムが動くように
します。
具体的には
(1) FORMをCLICKするという
イベントによって呼び出されるイベントプロシージャ Private Sub
   Form1_Click( )   

(2) "HELLO"と表示するプログラム print "hello" を記述する
という形のコーディングになるわけです。

Private Sub Form1_Click( )
Print "hello"
End Sub

手続き型の旧BASICでプログラムしていた人は、VBに移行した当初、このイベントドリブン型のプログラミング
にとまどうかもしれません。おじさんもなんかなじめないなーと感じましたが、徐々に慣れていくでしょう。

あえて言うなら旧BASICでも、何かイベント(割り込み)が発生すると、サブルーチンに飛ばすための 
on ... gosub
というコマンドがありしたが、これなどはイベントドリブンに似たような仕掛けをプログラム上で作っていると
言えるかもしれません。
たとえば N88 Basic では以下のようなコマンドがありますね。
on com gosub   RS232Cから割り込みが発生したらサブルーチンにとばす
on key gosub   ファンクションキーがおされたらサブルーチンに飛ばす
on help gosub   HELPキーが押されたらサブルーチンに飛ばす
on pen gosub   ライトペンが押されたらサブルーチンに飛ばす
on stop gosub   STOPキーが押されたらサブルーチンにとばす
on time$ gosub  ある時刻になったらサブルーチンにとばす

例えば、上のVBと同じような機能のプログラムをあえて旧BASICで作ると以下のようになります。
(N88 Basic   ファンクション1キーを押すと、"hello" と表示します)
10 on key gosub 100
20 key on
30 rem
40 goto 30
100 print "hello"
110 return


旧BASICでは、上述のようなon ..... gosub を使い、あるイベント(割り込み)があると、指定されたサブルーチン
にとぶような仕掛けをつくりましたが、VBでは全てが、イベントの発生 −>そのイベントに対応したプロ
シージャ(サブルーチン的なものと思って下さい)を呼び出す、という形のプログラムになります。

VBでは、on .... gosub のようなコマンドで、あるイベント(割り込み)とそれにより呼び出されるるサブルーチン
(の行番号)を定義する必要はありません。
それらの仕掛けは、VBの仕様として最初から準備されています。プログラムする時は、必要なイベント
に対応するプロシジャの部分だけプログラミングします。(なんか文字で書いてもわからないと思いますが、
実際にプログラムしてみればすぐに理解できると思います)

3 イベント

では、どんなイベントが用意されているのか見てみます。
まず、一番基本になるFORMにどんなイベントが発生するかというと、
Initialize  FORMのインスタンスが作成された時に発生
load     FORMがメモリーにロードされた時に発生
avtivate  FORMがアクティブウィンドウになった時に発生
gotfocus FORMがフォーカスを得た時に発生
keydown キーを押し下げた時に発生
keypress キーを押した時に発生
mousedown マウスボタンを押した時に発生
click    マウスをクリックした時に発生
dblclick  マウスをダブルクリックした時に発生
などなどがあります。
他にもいろんなイベントがありますが、マイナーなイベントはあとでゆっくり覚えていって下さい。
VB初心者にとってまずぶつかる問題はそれぞれのイベントがどういう状況で発生するのか、
似たようなイベントの発生順序とその違いは?(initialize と load  activate と gotfocus
mousedown と click と dblclick)ということです。
いったいFORMがアクティブウィンドウになった時(activate)とフォカースを得た時(gotfocus)と
どう違うのでしょうか。おじさんは、旧BASICからVBに移行した当初、ここらへんの理解がいまひとつ
で、どうも思った通りにプログラムが動かないといったことが、よくありました。ある意味で旧BASICを
使っていた人にとっては、なんか面倒な感じの部分です。

それで、主なイベントが発生すると、DEBUG画面とFORMに何のイベントが発生したか表示
するプログラムを作ってみました。プログラムを見ればわかりますが、ただ、自分のイベント名
を表示させるだけの簡単なものです。しかし、これで、遊んでみればイベントにつてかなりはっきり
分かると思います。2つのFORMがありますが、SUB FORMの方は空のFORMです。
(gotfocus、lostfocus、paint、などのイベントをおこすためにだけにあるFORMです)
VB4用のコードです。VB5以上ではおそらく、initialize と terminate のところでエラーが出るので
そのイベントプロシージャの print 文 を rem 文にして下さい。

FORM1 (event.frm)  VB 4用

VERSION 4.00
Begin VB.Form Form1
Caption = "イベントの実験"
ClientHeight = 6375
ClientLeft = 1140
ClientTop = 1515
ClientWidth = 4170
Height = 6780
Left = 1080
LinkTopic = "Form1"
ScaleHeight = 6375
ScaleWidth = 4170
Top = 1170
Width = 4290
End
Attribute VB_Name = "Form1"
Attribute VB_Creatable = False
Attribute VB_Exposed = False
Private Sub Form_Activate()
Debug.Print "Activate"
Print "activate"
End Sub

Private Sub Form_Click()
Debug.Print "click"
Print "click"
End Sub

Private Sub Form_DblClick()
Debug.Print "dblclick"
Print "dblclick"
End Sub

Private Sub Form_Deactivate()
Debug.Print "deactivate"
Print "deactivate"
End Sub

Private Sub Form_GotFocus()
Debug.Print "gotfocus"
Print "gotforcus"
End Sub

Private Sub Form_Initialize()
Debug.Print "initialize"
Print "initialize"
Form2.Show
End Sub

Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer)
Debug.Print "keydown"
Print "keydown"
End Sub

Private Sub Form_KeyPress(KeyAscii As Integer)
Debug.Print "keypress"
Print "keypress"
End Sub

Private Sub Form_KeyUp(KeyCode As Integer, Shift As Integer)
Debug.Print "keyup"
Print "keyup"
End Sub

Private Sub Form_Load()
Debug.Print "load"
Print "load"
End Sub

Private Sub Form_LostFocus()
Debug.Print "lostfocus"
Print "lostforcus"
End Sub

Private Sub Form_MouseDown(Button As Integer, Shift As Integer, x As Single, y As Single)
Debug.Print "mousedown"
Print "mousedown"
End Sub

Private Sub Form_MouseMove(Button As Integer, Shift As Integer, x As Single, y As Single) Debug.Print "mousemove"; x; y
Print "mousmove ";
End Sub

Private Sub Form_MouseUp(Button As Integer, Shift As Integer, x As Single, y As Single)
Debug.Print "mouseup"
Print "mouseup"
End Sub

Private Sub Form_Paint()
Debug.Print "paint"
Print "paint"
End Sub

Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
Debug.Print "queryunload"
Print "queryunload"
End Sub

Private Sub Form_Resize()
Debug.Print "resize"
Print "resize"
End Sub

Private Sub Form_Terminate()
Debug.Print "terminate"
Print "terminate"
End Sub

Private Sub Form_Unload(Cancel As Integer)
Debug.Print "unload"
Print "unload"
End Sub

FORM2 (event2.frm)

VERSION 4.00
Begin VB.Form Form2
Caption = "SUB FORM"
ClientHeight = 705
ClientLeft = 4785
ClientTop = 2055
ClientWidth = 3135
Height = 1110
Left = 4725
LinkTopic = "Form2"
ScaleHeight = 705
ScaleWidth = 3135
Top = 1710
Width = 3255
End
Attribute VB_Name = "Form2"
Attribute VB_Creatable = False
Attribute VB_Exposed = False

実行例


(1)  プログラム開始時
上記のプログラムで遊んでみると、プログラム開始時のイベント発生順序は次のようになっていることが
わかります。開発環境で「実行」してDEBUG画面を見てください。
initialize
load
resize
activate
gotfocus
paint
さて、次にFORMを見ると、resizeから表示されていますね。loadイベントまでは、FORM自体が
画面にないので、print のような表示の命令を使っても、表示されないということがわかります。
それと、もうひとつ。いろいろ遊んでいるうちに分かりますが、プログラムが起動されてから、終了
されるまでにinitialize,load イベントは1回しか起こりません。従って、データの初期設定など、
最初に1回だけすれば良いことは、このイベントプロシージャに書けば良いということになります。

(2) マウス
FORM上でマウスを動かしてください。Mousemoveイベントが連続的に起きているのがわかると
おもいます。
それでは、FORM上でマウスをダブルクリックしてみて下さい。どうでしょうか。
mousedown-->mouseup-->click-->mousemove-->dblclick-->mouseup
という順にイベントが発生しているのがわかりましたか。ダブルクリックの前にマウスボタン押し下げ、
マウスボタンアップ、クリック、マウスの移動のイベントが起きています。
これは、シングルクリックとダブルクリックで違うことをさせようとすると、ちょっと困ったことになります。
ダブルクリックの前に、シングルクリックのイベントプロシージャが実行されてしまうので、ちょつと工夫が
必要になります。

(3) キー入力
キーを押して下さい。
keydown-->keyup-->keypress
という順でイベントが発生します。

(4) フォーカスの移動
SUB FORMをクリックして下さい。フォーカスがSUB FORMにうつりましたね。
この時は lostfocus-->deactivate というイベントが発生します。
こんどはMAIN FORM(イベントの実験)をクリックして下さい。フォーカスが戻りました。
この時は
mousedown-->activate-->gotfocus-->mouseup-->click-->paint
という順に一連のイベントが発生しています。また、この間にmousemoveというイベントも発生
しているかもしれません。

(5) 終了
プログラムを終了すると
queryunload-->unload-->terminate
というイベントが発生します
Queryunloadはプログラムの終了(クローズ)の直前にunloadに先立ち発生します。
本当にプログラムを終了するか、確認のメッセージなどは、このイベントプロシージャに
記述すれば良いと思います。

 

TopPage > Visual BasIc&Excel活用研究目次