条件が揃うまで実行ボタンを押せなくする

昨日は、コネクタをオートシェイプに置き換えたうえで、もともとコネクタと繋がっていた前後のオートシェイプと、改めてコネクタでつないでみました。

infoment.hatenablog.com

今日は、昨日配置したボタンについて、条件成立まで無効化することに挑戦です。

今日やりたいこと

昨日追加した機能は、コネクタ未選択の状態で実行するとエラーになります。選択したコネクタを最初に削除させているので、未選択の場合は「無いものを削除しろ」という無理な命令わすることになり、エラーになります。

そこで今回は、このエラーを回避する方法を検討してみました。ぱっと思いつく回避方法は、大別して下記の二通りです。

  • 実行後に条件を確認し、条件不成立の場合に処理を中断
  • 実行前に条件を確認し、条件不成立の場合に実行不可化

実行したあとに「やっぱり駄目でした」というのは寂しい話なので、今回は後者を採用することにします。

必要なこと

  1. 条件成立確認用の関数
  2. ボタン有効・無効切り替え用のマクロ作成
  3. 上記マクロを必要箇所に追加

1.条件成立確認用の関数

今回は、以下の二つを必須条件としました。

  1. ネクタリストの項目が選択済みであること
  2. オートシェイプ用テキストボックスが記入済

そこで上記の二点を確認し、条件成立であれば True を、不成立であれば False を返す関数を作成しました。

【標準モジュール】
Public Function CheckConnectorList() As Boolean

    With EditConnectorForm
        Dim TextFlag As Boolean
        If .AddChartTextBox <> "" Then
                TextFlag = True
        End If
        
        Dim SelectFlag As Boolean
        Dim i As Long
        For i = 0 To .ListBox2.ListCount - 1
            If .ListBox2.Selected(i) = True Then
                SelectFlag = True
                Exit For
            End If
        Next
    End With
    
    CheckConnectorList = TextFlag * SelectFlag
    
End Function

各項目のフラグを掛け算すると、以下の結果になります。

  • False * False = False
  • False * True = False
  • True * False = False
  • True * True = True

両条件がそろって初めて、戻り値が True となるわけです。

2.ボタン有効・無効切り替え用のマクロ作成

1.の結果を受けて、ボタンの有効/無効を切り替えるマクロを作成しました。

【標準モジュール】
Public Sub ControlAddChartButton()
        Select Case CheckConnectorList
            Case True
                EditConnectorForm.AddChartButton.Enabled = True
            Case False
                EditConnectorForm.AddChartButton.Enabled = False
        End Select        
End Sub

3.上記マクロを必要箇所に追加

今回の有効/無効の切り替えが発生するのは、以下のタイミングです。

  1. リストボックスが更新されるとき
  2. リストボックス内の項目が選択されるとき
  3. オートシェイプ用テキストボックスの値が変わったとき

そこで、それぞれのタイミングで切り替えが起きるよう、必要各所に追加します。

【標準モジュール】

リストボックス更新

Public Sub UpdateConnectorList()

    ' 一旦全てのオートシェイプ選択を解除
    Range("A1").Select

    Dim Shape As Shape
    Dim col As Collection
    Set col = New Collection
        For Each Shape In ActiveSheet.Shapes
            If Shape.Connector = msoTrue Then
                col.Add Shape.Name
            End If
        Next
    
    Dim SQC As SequenceClass
    Set SQC = New SequenceClass
        EditConnectorForm.ListBox2.Clear
        EditConnectorForm.ListBox2.List = SQC.ToArray(col)
    
    ' 今回の追加個所
    Call ControlAddChartButton

End Sub
【ユーザーフォームのモジュール】(EditConnectorForm)

リストボックス内の項目が選択されるとき

Private Sub ListBox2_MouseUp(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)

    Dim ConnectorName As String
        ConnectorName = ListBox2.List(ListBox2.ListIndex)
    
    Set SC = New ShapeClass
    Set SC.myShape = ActiveSheet.Shapes(ConnectorName)
        SC.myShape.Select
    Set start_shape = SC.myShape.ConnectorFormat.BeginConnectedShape
        StartPosition = SC.myShape.ConnectorFormat.BeginConnectionSite
    Set end_shape = SC.myShape.ConnectorFormat.EndConnectedShape
        EndPosition = SC.myShape.ConnectorFormat.EndConnectionSite

    ' 今回の追加個所
    Call ControlAddChartButton

End Sub

オートシェイプ用テキストボックスの値が変わったとき(新規)

Private Sub AddChartTextBox_Change()
    Call ControlAddChartButton
End Sub

結果

条件成立まで、ボタンを無効化することができました。
f:id:Infoment:20180923232239p:plain

次回に続きます。

参考まで。