前回は、構造体を用いて疑似LEDの属性である変数をまとめて管理する方法について説明した。 今回は、変数だけでなく、LEDを表示したり点滅させたりする処理(プロシージャ)も含めて、ひとまとまりとして管理するための仕組みとして、クラスモジュールを導入する。クラスモジュールとは、必要な変数と処理をコードとしてまとめたものである。
コード1は、前回、説明した構造体で変数を管理するコードである。この中で使用しているプロシージャ SpecSetLED()、makeLED()、BlinkLED() は、いずれも構造体 LED を操作する専用のもので、他の処理には使われない。したがって、構造体変数と共に関連する処理をひとまとめにしておくことで管理性が向上する。
コード1. 構造体による変数の管理
' 疑似LEDの構造体定義
Public Type LED
R As Integer ' LEDを配置するセルの行番号
C As Integer ' LEDを配置するセルの列番号
Col As Long ' LEDの表示色
T_on As Long ' LEDの点灯時間(ミリ秒)
T_off As Long ' LEDの消灯時間(ミリ秒)
End Type
' LED構造体の変数宣言
Public LED1 As LED
Public LED2 As LED
Public LED3 As LED
' LEDの属性を構造体に設定するプロシージャ
Sub SpecSetLED(ByRef led As LED, LED_Row As Integer, LED_Column As Integer, LED_Color As Long, LED_Time_On As Long, LED_Time_Off As Long)
led.R = LED_Row
led.C = LED_Column
led.Col = LED_Color
led.T_on = LED_Time_On
led.T_off = LED_Time_Off
End Sub
' LEDの初期描画(消灯状態)
Sub makeLED(ByRef led As LED)
With Cells(led.R, led.C)
.Font.Color = led.Col
.Value = "*"
.HorizontalAlignment = xlCenter
.Interior.Color = vbBlack
End With
End Sub
' LEDの点滅処理
Sub BlinkLED(ByRef led As LED)
Dim T_now As Long
Cells(led.R, led.C).Value = "●"
T_now = Timer * 1000
While Timer * 1000 < T_now + led.T_on: DoEvents: Wend
Cells(led.R, led.C).Value = "*"
T_now = Timer * 1000
While Timer * 1000 < T_now + led.T_off: DoEvents: Wend
End Sub
' メイン処理
Sub main()
' LEDの属性を設定
SpecSetLED LED1, 1, 1, vbRed, 500, 500
SpecSetLED LED2, 2, 2, vbYellow, 200, 200
SpecSetLED LED3, 3, 3, vbGreen, 100, 100
' LEDの初期描画
makeLED LED1
makeLED LED2
makeLED LED3
Stop ' 実行を一時停止(F5で続行可能)
' LEDの点滅ループ
Do
BlinkLED LED1
BlinkLED LED2
BlinkLED LED3
DoEvents
Loop
End Sub
コード2 は、変数と処理をクラスモジュールにまとめたものである。構造は、コード1と似ているが、よく見るとプロシージャのパラメータが変化している。SpecSetLED()、makeLED()、BlinkLED() の各プロシージャから引数 “ByRef led As LED” が消えている。これは、変数を同じクラスにまとめたことにより、構造体の型を受け渡す必要がなくなったためであり、各プロシージャがクラス内の変数 R や C を直接扱えるようになったことを意味する。
クラスモジュールの追加手順は以下のとおりである。Visual Basic Editor(VBE)にてワークブックを右クリックし、[挿入]→[クラスモジュール]を選択する。追加されたクラスモジュールを選択し、プロパティウィンドウでオブジェクト名を “LED” に変更する。このクラスモジュールに コード2 を貼り付ける。続いて、標準モジュールに コード3 を貼り付ける。Sub main() にカーソルを置いて F5キーを押すことで、ワークシートに疑似LEDが描画される。再度F5キーを押すことで、LEDが点滅を開始する。
コード2. 変数と処理をまとめたクラスモジュール
' *** クラスモジュール名:LED ***
' LEDの属性(構造体のフィールドに相当)
Public R As Integer ' LEDを配置するセルの行番号
Public C As Integer ' LEDを配置するセルの列番号
Public Col As Long ' LEDの表示色
Public T_on As Long ' LEDの点灯時間(ミリ秒)
Public T_off As Long ' LEDの消灯時間(ミリ秒)
' LEDの属性を設定する
Sub SpecSetLED(LED_Row As Integer, LED_Column As Integer, LED_Color As Long, LED_Time_On As Long, LED_Time_Off As Long)
R = LED_Row
C = LED_Column
Col = LED_Color
T_on = LED_Time_On
T_off = LED_Time_Off
End Sub
' LEDの初期描画
Sub makeLED()
With Cells(R, C)
.Font.Color = Col ' フォントの色を設定
.Value = "*" ' 初期値は消灯マークを設定
.HorizontalAlignment = xlCenter ' 文字をセルの中央寄せに設定
.Interior.Color = vbBlack ' セルの背景色を黒に設定
End With
End Sub
' LEDの点滅処理
Sub BlinkLED()
Dim T_now As Long
' 点灯
Cells(R, C).Value = "●" ' 点灯マーク
T_now = Timer * 1000 ' 処理開始時刻をmsで記録
While Timer * 1000 < T_now + T_on ' 現在時刻<(処理開始時刻+点灯時間) の間ループ
DoEvents
Wend
' 消灯
Cells(R, C).Value = "*" ' 消灯マーク
T_now = Timer * 1000 ' 処理開始時刻をmsで記録
While Timer * 1000 < T_now + T_off ' 現在時刻<(処理開始時刻+消灯時間) の間ループ
DoEvents
Wend
End Sub
コード3.標準モジュール
' 標準モジュール
Sub main()
' クラスのインスタンスを生成
Dim LED1 As New LED
Dim LED2 As New LED
Dim LED3 As New LED
' LEDの属性を設定 (引数: 行, 列, 色, 点灯時間ms, 消灯時間ms)
LED1.SpecSetLED 1, 1, vbRed, 500, 500 '1行1列, 赤色, 点灯0.5秒, 消灯0.5秒
LED2.SpecSetLED 2, 2, vbYellow, 200, 200 '2行2列, 黄色, 点灯0.2秒, 消灯0.2秒
LED3.SpecSetLED 3, 3, vbGreen, 100, 100 '3行3列, 緑色, 点灯0.1秒, 消灯0.1秒
' LEDの初期描画
LED1.makeLED
LED2.makeLED
LED3.makeLED
Stop ' 実行を一時停止(F5で続行する)
' LEDの点滅ループ
Do
LED1.BlinkLED
LED2.BlinkLED
LED3.BlinkLED
DoEvents
Loop
End Sub
定義したクラスモジュールを利用するには、変数と同様に、まず宣言が必要である。コード3 の”Dim LED1 As New LED”により、LED1 が LED クラスのインスタンス(実体)として生成される。
このように生成された LED1、LED2、LED3 は「オブジェクト」と呼ばれる。
生成されたオブジェクトは、LED1.BlinkLED のように、オブジェクト名とメソッド名をドットで連結することで、そのオブジェクトの属性(メンバー変数)に基づいて処理が実行される。
LED の数を増やすには、コード3 においてインスタンスを生成し、属性の設定、初期描画、点滅の各メソッドの呼び出しを追加すればよい。
次回は、順次点滅している LED を、同時に点滅させるようクラスモジュールを改良する予定である。