フローチャートの編集 ~箱の一覧をリスト表示~

先日は、セルに書かれた内容を順番にフローチャートの箱(処理)に記載する方法を紹介しました。

infoment.hatenablog.com

箱を作るだけだと味気ないので、これらの何某かの処理を一括で行えるよう、ユーザーフォームを準備してみました。

f:id:Infoment:20180913063407p:plain

今はまだ、リストボックスだけです。リストボックスには、現時点では、以下3つの情報を持たせることにしました。

  1. 箱に記載された文字
  2. 同箱のID
  3. リストボックス内の項目が選択された順序

箱の記載された文字を見ながらリストボックス内で選択し、実際の処理は箱のIDで行います。選択順序情報を含めたのは将来的に、選択した順序にコネクタで接続するための下ごしらえです。
そこでまず、リストボックスの列幅を決めました。IDは見えなくても良いので、列幅は0です。

f:id:Infoment:20180913064023p:plain

複数選択できるようにしておきます。

f:id:Infoment:20180913064105p:plain

ユーザーフォームの初期化は、以下の通りです。

Private Sub UserForm_Initialize()

    Dim Shape As Shape
    Dim ListBoxSeq As Variant
    ReDim ListBoxSeq(1 To ActiveSheet.Shapes.Count, 1 To 3)
    Dim i As Long
        i = 1
        For Each Shape In ActiveSheet.Shapes
            ListBoxSeq(i, 1) = Shape.TextFrame2.TextRange.Characters.Text
            ListBoxSeq(i, 2) = Shape.ID
            ListBoxSeq(i, 3) = 0
            i = i + 1
        Next
        ListBox1.List = ListBoxSeq
          
End Sub

結果、次のようになりました。
初期状態なので、選択順序を表す数字は全て 0 のままです。

f:id:Infoment:20180913064644p:plain

次にリストボックスの項目を選択した順序を記録します。このように考えました。

  1. リストボックスの項目について、上から順に選択状況を確認する。
  2. 選択されている場合であって、もし選択順序が 0 ならば(つまり今回初めて選択されたのならば)、選択順序列の最大値+1 をセットする(=最後に選択されたことになる)。
  3. 選択されていないなら、0 を返す。

このために、以下の3つを準備します。
① リストボックスの2列目を配列とする関数

Private Function OrderSeq() As Variant
    Dim seq As Variant
    ReDim seq(0 To ListBox1.ListCount - 1)
    Dim i As Long
        For i = 0 To ListBox1.ListCount - 1
            seq(i) = CInt(ListBox1.List(i, 2))
        Next        
        OrderSeq = seq
End Function

② ①の配列内の最大値+1を返す関数

Private Function iMax() As Long
    iMax = WorksheetFunction.Max(OrderSeq) + 1    
End Function

③ リストボックスが選択されるたびに、選択順序を更新

Private Sub UpdateOrder()
    Dim i As Long
        For i = 0 To ListBox1.ListCount - 1
            If ListBox1.Selected(i) = True Then
                If ListBox1.List(i, 2) = 0 Then
                    ListBox1.List(i, 2) = iMax
                End If
            Else
                ListBox1.List(i, 2) = 0
            End If
        Next
End Sub

これを、ListBox1をクリックしてボタンが戻る際に実行します。

Private Sub ListBox1_MouseUp(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
    Call UpdateOrder
End Sub

結果、リスト内の項目を選択した順序が記録されるようになりました。

f:id:Infoment:20180913070133p:plain

項目の選択を解除しても、残りの項目が選択された順序は保持されています。
↓ 以下の例でいえば、「1 ⇒ 2 ⇒ 4 ⇒ 5」になっています(3が欠番)。

f:id:Infoment:20180913070248p:plain

次回(明日以降)に続きます。

参考まで。