VBAでオブジェクト指向を理解する
第4回 クラスモジュールを改造する

今回は前回作成したクラスモジュールを改造し、順番に点滅させていた疑似LEDを同時に点滅させることにする。

LEDの属性を設定する変数、すなわちメンバー変数に「LEDが点灯開始した時間:T_st」と「タイマー監視フラグ:Flg」を追加した。また、LEDを同時に点滅させるため、メソッド BlinkLED を改造した。点灯を開始した時間を T_st に保存し、その時間を起点にして点灯時間と消灯時間を監視して制御する。他の処理を待たせないよう、タイマーのカウントアップを待つのではなく、タイマーの状態をチェックし、点灯・消灯の操作をしたら直ぐに処理を抜けるようにした。タイマー監視フラグ Flg は、タイマーの監視中であることを保持し、 T_st を更新しないようにする役割を持つ。

コード 1 をクラスモジュールに、コード 2 を標準モジュールにそれぞれ貼り付けて、標準モジュールの main を実行すると、三つの LED が同時に点滅することを確認できる。

コード1.クラスモジュール

' ***** クラスモジュール: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の消灯時間(ミリ秒)
Public T_st  As Long     ' LEDが点灯開始した時間(ミリ秒)
Public Flg   As Integer  ' タイマー監視フラグ 1:監視中 0:監視中でない

' 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
    Flg = 0
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()

    ' タイマー、LED点滅、監視フラグの関係
    '
    ' タイマー:T_st       T_st+T_on  T_st+T_on+T_off
    '           +----------+----------+
    '      LED:●(点灯)   *(消灯)
    '      Flg:1(タイマー監視)       0(監視終了)

    Dim Now_ms As Long
    Now_ms = Timer * 1000
    If Flg = 0 Then     ' タイマー監視中か
        T_st = Now_ms   ' 点灯開始時間を保持
        Flg = 1         ' タイマー監視開始
    End If
    
    Select Case Now_ms
        Case Is < T_st + T_on
            Cells(R, C).Value = "●"

        Case Is < T_st + T_on + T_off
            Cells(R, C).Value = "*"

        Case Else       ' T_st + T_on + T_off <= Now_ms
            Flg = 0     ' タイマー監視終了
    End Select
End Sub

コード2.標準モジュール

' ***** 標準モジュール *****
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

上記のように、改造はクラスモジュール内だけで完結し、標準モジュールのコードは影響を受けない。クラスモジュール化によって保守性が高くなることがわかる。さらに、オブジェクトが自己の状態を保持することで、オブジェクトの独立性が生まれ、並行処理が可能になる。

シェアする

  • このエントリーをはてなブックマークに追加

フォローする