セレクトボタンを作る

ラボ

クラスを使ったシェイプボタンの作成

 今回は、上のようなセレクトボタンを作っていく過程を紹介します。
 ボタンは、シェイプを利用しており、押すたびに回転角度が変わって外側の値を指し示すような形になっています。
 オーディオなどで見られるセレクトスイッチ、レンジボタンなどと呼ばれるものを再現しています。

 今回のセレクトボタンのようなケースでは、初期状態やボタンの角度、現在の値などを保持する必要があるのでクラスを使うと便利です。
 さらにクラスを使えば、いくつでも同じようなスイッチを配置して使う事ができるようになります。
 
 クラスと言っても今回は簡単な例となりますので、初心者の方にも理解しやすいと思います。
 是非挑戦してみてください。

ボタンを配置する

 まずは、「図形」から「楕円」を選択して、シートに配置します。
 その際、楕円でなく真円である必要があります。Shiftキーを押しながら調整すれば、真円になるのですが、実際にはそう上手くいきません。
 
 そこで、以前シェイプの位置を正確に合わせるで紹介した、ツールを使います。
 ツールのインストール方法や使い方は以下のページを参照してください。
シェイプの位置を正確に合わせる

 ツールを使って、シェイプを真円にしてみましょう。
 ツールを起動し、配置したシェイプを選択して「Read」を押します。
 WidthとHeightの値が等しくない場合は、真円となっていません。
 WidthとHeightの左側にチェックを入れて、右側に同じ数値を入力します。
 「Set」ボタンでシェイプのWidthとHeightが同じ値となり、シェイプが真円に変更されます。

 次に線のシェイプを追加して、円の上に配置します。
 2つを選択して右クリックし、「グループ化」を選択します。
 
 グループ化したら、シェイプの名前を「セレクトボタン」に変更しておきましょう。

指示値を配置する

 今度はボタンの周りに、指示値を配置します。
 「図形」の「テキストボックス」を利用しましょう。
 「枠線なし」、「塗りつぶしなし」に設定して、好きな値を配置していきます。
 数はいくつでも構いません。均等に配置した方が見栄えが良いですが、均等でなくても構いません。

セレクトボタンの角度を記録

 指示値が配置できたので、それらを指し示す角度を記録しておきます。
 ここで再びシェイプ設定ツールの登場です。
 ツールを起動したら、セレクトボタンを選択してシェイプを回転させて指示値に合わせます。
 「Read」ボタンを押すと、Rotateに値が表示されます。この角度をそれぞれ記録しておきます。
※記録するだけなので、セルに書きこむ必要はありません。

セレクトボタンのクラスを作る

 クラスを使えばセレクトボタンの設定や動作を1つにまとめる事ができて便利です。
 まずは、メンバと呼ばれる変数やオブジェクトを宣言します。次にこれらを操作するためのメソッドを用意します。
 
 VBEのメニューから「挿入」>「クラスモジュール」としてクラスを追加します。
 追加したクラスのクラス名をCSelectSwitchとしておきましょう。
 クラス名の変更は、プロパティウインドウの「(オブジェクト名)」の所で変更できます。

メンバを用意

 今回のセレクトボタンでは、セレクトボタンのシェイプ名ボタンの角度指示値、そして現在の位置をメンバとして宣言します。以下のコードをクラスモジュールの CSelectButton をクリックしてコードウインドウに記述します。

’//CSelectButtonクラスモジュールに記述します

Private shp As shape       'セレクトボタンのシェイプ
Private mRotates            '目盛の角度(配列)
Private mValues             '目盛の値(配列)
Private mPos As Long    '現在指している目盛

 mRotates(目盛の角度)と、mValues(目盛の値)は、複数あるので配列になりますが、後程、Split関数で受けるのでバリアント型にしておきます。

初期化

 クラスの初期化には、Initialize関数が用意されています。
 コードウインドウ上部のClassからInitializeを選択すると、Class_Initialize関数が用意されます。
 ここに記述されたコードは、クラスが生成されるときに実行されます。

’//CSelectSwtchクラスモジュールに記述します
Private Sub Class_Initialize()
    mPos = 0    '最初は一番目を指すようにする。
End Sub

 メンバはそれぞれ初期化しなければなりませんが、今回は、クラス生成後に必要な値を代入していくようにします。
 シェイプの登録、目盛の回転角、目盛の指示値のメンバは以下の関数で初期化します。

'シェイプの登録
Public Sub setShape(name As String)
    Worksheets("Sheet1").Activate
    Set shp = ActiveSheet.Shapes(name)
End Sub

'回転角の登録
Public Sub setRotateAngle(list As String)
    mRotates = Split(list, ",")
End Sub

’指示値の登録
Public Sub setValue(list As String)
    mValues = Split(list, ",")
End Sub

 シェイプの登録では、登録する時にシェイプがアクティブシートにないと上手く登録できないようです。
 シートが複数ある場合も想定して、冒頭でシェイプのあるシートをアクティブにしておきます。
 
 回転角と指示値の登録では、カンマ区切りの文字列を引数に取って、Split関数で配列を得るようにしています。
 尚、回転角と指示値の配列の数が揃っていないと上手く行きません。

その他の関数

 上記以外にボタンを動作させて値を取得するための関数が必要になります。
 まず、ボタンを押すたびにシェイプを回転させる関数です。実際のセレクトスイッチなどは、右回りと左回りが自由にかえられますが、ここでは、マウスの左クリックしか扱えないので、クリックするたびに右回りするようにしています。
 2つ目の関数は、引数に数値を取って、その位置にセレクトボタンを回転させるというものです。初期化などで使います。
 3つ目はセレクトボタンが示す値を返してくれる関数です。

'クリックするたびに回転角度を変更する。
Public Sub stepRotationButton()
    mPos = mPos + 1
    If mPos > UBound(mRotates) Then mPos = 0
    shp.Rotation = mRotates(mPos)
End Sub

'引数の位置にボタンをセットする。(大きすぎる場合は最初の値)
Public Sub setButtonPos(n As Long)
    mPos = n
    If n > UBound(mRotates) Then
        mPos = UBound(mRotates)
    ElseIf n < 0 Then
        mPos = 0
    End If
    
    shp.Rotation = mRotates(mPos)
End Sub

'現在の目盛の値を返す
Public Function getValue() As Long
    getValue = mValues(mPos)
End Function

クラスを使ってみる

 セレクトボタンのクラスが出来たので、このクラスを使ってみましょう。
 
 今回のプログラムでは、クラスをグローバル変数にして、ブックを閉じるまで生成したクラスを保持するようにします。
 
 クラスは最初に New して生成してから使いますが、今回の場合ブックを開いた時に生成を行うのが自然でしょう。
 生成のプログラムは標準モジュールに書いて、それを Workbook_Open() 内で呼び出すようにします。

クラスの生成

'//以下のコードは標準モジュールに記述します。

Public SelectButton As CSelectButton   'クラスをグローバル変数にする

’初期化のプログラム Workbook_Open() 内で呼び出す
Sub setupFirst()
    Worksheets("Sheet1").Activate
    
    Set SelectButton = New CSelectButton    'クラスの生成
    
    ’クラスの初期設定
    With SelectButton
    .setShape "セレクトボタン"                           'どのシェイプをボタンに割り付けるか
    .setRotateAngle "230,270,307,0,50,90,128"    'ボタンの回転角度
    .setValue "0,10,20,30,40,50,60"                     'ボタンの指示値
    .setButtonPos 0                                          'ボタンの初期位置
    Range("D14") = .getValue                            '値の表示
    End With
    
End Sub

 まずは、Sheet1をアクティブにしておきます。別のシートになっていると、上手くシェイプをセットする事ができなくなります。
 次に、クラスの生成です。クラスを変数に代入する時は、Set を忘れないようにしましょう。
 また、クラスを生成する時は New を使います。クラスは New したときに、Initialize()が呼び出されます。
 
 続いて、クラスの初期化を行います。
 ここでは、どのシェイプをボタンとして割り付けるか、ボタンの回転角度、ボタンの指示値、ボタンの初期位置、値の表示を行っています。
 ボタンの位置は、回転角度と指示値の配列インデックスになります。

 クラスの初期化である setupFirst() は、ThisWorkbookモジュールのイベントプロシージャ、 Workbook_Open()内で実行します。

'// 以下のコードはThisWorkbookモジュールに記述します。
Private Sub Workbook_Open()
    Call setupFirst
End Sub

ボタンをクリックした時の動作

 今回はシェイプをボタンとして利用します。クリックするたびにシェイプの回転角を変えて、その角度に応じた値を出力するようにします。
 
 シート上でボタンを右クリックして「マクロの登録」を実行します。
 ボタンを押した時に実行されるマクロを「新規作成」で作成します。ここでは、セレクトボタン_Click() という関数名にします。

'//以下のコードは標準モジュールに記述します。
Sub セレクトボタン_Click()
    SelectButton.stepRotationButton
    Range("D14") = SelectButton.getValue
End Sub

 プログラムは、SelectButton の stepRotationButton() を実行します。これでボタンは次の指示値を指します。
 次に、getValue() が実行され、現在のポジションの値を返してくれるので、それを D14セルに書き込みます。

実行してみる

 プログラムを作り終えたら、一度保存して終了して再度起動してみましょう。
 もし、以下のようなエラーが出た場合は、クラスが生成されていない可能性があります。

 手動で setupFirst() を実行して動作を確認してみてください。

 うまく行けば、ボタンを押すたびにセレクトボタンが回転し、指示した値が D14 セルに表示されます。

コメント

タイトルとURLをコピーしました