フローチャートの編集 ~箱の一覧をリスト表示~
先日は、セルに書かれた内容を順番にフローチャートの箱(処理)に記載する方法を紹介しました。
箱を作るだけだと味気ないので、これらの何某かの処理を一括で行えるよう、ユーザーフォームを準備してみました。
今はまだ、リストボックスだけです。リストボックスには、現時点では、以下3つの情報を持たせることにしました。
- 箱に記載された文字
- 同箱のID
- リストボックス内の項目が選択された順序
箱の記載された文字を見ながらリストボックス内で選択し、実際の処理は箱のIDで行います。選択順序情報を含めたのは将来的に、選択した順序にコネクタで接続するための下ごしらえです。
そこでまず、リストボックスの列幅を決めました。IDは見えなくても良いので、列幅は0です。
複数選択できるようにしておきます。
ユーザーフォームの初期化は、以下の通りです。
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 のままです。
次にリストボックスの項目を選択した順序を記録します。このように考えました。
- リストボックスの項目について、上から順に選択状況を確認する。
- 選択されている場合であって、もし選択順序が 0 ならば(つまり今回初めて選択されたのならば)、選択順序列の最大値+1 をセットする(=最後に選択されたことになる)。
- 選択されていないなら、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
結果、リスト内の項目を選択した順序が記録されるようになりました。
項目の選択を解除しても、残りの項目が選択された順序は保持されています。
↓ 以下の例でいえば、「1 ⇒ 2 ⇒ 4 ⇒ 5」になっています(3が欠番)。
次回(明日以降)に続きます。
参考まで。