リストからコネクタを除外する
昨日は、オートシェイプの位置関係を、コネクタの種類と接続位置に反映してみました。
今日は、接続済みのコネクタをリストから除外することに挑戦です。
今日やりたいこと
今までは、シート上に接点・処理・分岐の3つのオートシェイプのみ存在する前提で、様々な処理を行ってきました。しかし、コネクタが存在する状態でオートシェイプのリストを作成しようとすると、現時点ではエラーが発生します。
恐らく、コネクタが持っていない情報(=テキスト)を取り出して表示させようとしたのが原因と思われます。
そこで、リスト作成の時点でコネクタを処理の対象から除外することにしました。手順は、以下の通りです。
- リスト作成時に、対象となるオートシェイプの種類を確認
- 配列のサイズを変更
必要なこと
- オートシェイプの種類の確認方法
- 二次元配列の一次元サイズを変更する方法
いくつか方法があると思います。今回紹介する方法は、その中の一つです。
1.オートシェイプの種類の確認方法
コネクタだけを除外したい場合、直ぐに思いつく方法は二つありました。
① オートシェイプの名前で判別
現時点で登場するコネクタの名前は、以下の二つです。
- Straight Arrow Connector
- Elbow Connector
いずれの場合も、名前に「Connector」が含まれています。そこでLike演算子を用いて、名前にConnectorを含むものを除外します。こんな感じです。
If Shape.Name Like "*Connector*" Then
② Connectorプロパティで判別
オートシェイプがConnectorであればTrueを返し、それ以外の場合はFalseを返してくれます。従って、こんな感じで確認します。
If Shape.Connector = msoTrue Then
これは省略して、このようにも書けます。
If Shape.Connector Then
①は直感的に分かり易く、②はコードがすっきりします。今回は、②を採用することにします。
2.二次元配列の一次元サイズを変更する方法
リストボックスのリスト用データとして準備した配列は、そのサイズを、シート上のオートシェイプの数で決めていました。
Dim ListBoxSeq As Variant ReDim ListBoxSeq(1 To ActiveSheet.Shapes.Count, 1 To 3)
この中にはコネクタも含まれるため、これを除外した場合、リストの末尾に空っぽの項目が追加されてしまいます。
現時点ではこの項目を選択すると、存在しないオートシェイプを選択しようとしてエラーが発生します。
配列のサイズを整えて、余分な空白が出ないようにしたいのですが、今回調整したい次元はRedimで変更できません。
thom.hateblo.jp
そこで、一次元のサイズを変更する関数を作成してみました。
【クラスモジュール】(SequenceClass)
'[用 途] ' 二次元配列について、一次元のサイズを変更する '[引 数] ' seq As Variant 元の配列 ' update_size As Long 変更後の一次元のサイズ ' preserve_flag As Boolean 値保持を選択(初期値はTrue) '[戻り値] ' 一次元のサイズを変更した配列 Public Function SpecialRedim(seq As Variant, _ update_size As Long, _ Optional preserve_flag As Boolean = True) As Variant Dim tempSeq As Variant ReDim tempSeq(LBound(seq) To update_size, LBound(seq, 2) To UBound(seq, 2)) Select Case preserve_flag Case False Case True Dim i As Long, j As Long For i = LBound(seq) To UBound(tempSeq) For j = LBound(seq, 2) To UBound(seq, 2) tempSeq(i, j) = seq(i, j) Next If i = UBound(seq) Then Exit For End If Next End Select SpecialRedim = tempSeq End Function
変更後のサイズで新たな配列を作成し、そこに値を移すだけの関数です。
これを、先ほどのコネクタ判別の仕掛けと併せてリスト作成に反映します。
【ユーザーフォームのモジュール】
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 If Shape.Connector = msoFalse Then ' ← 今回追加した箇所 ListBoxSeq(i, 1) = Shape.TextFrame2.TextRange.Characters.Text ListBoxSeq(i, 2) = Shape.ID ListBoxSeq(i, 3) = 0 i = i + 1 ' ← 今回追加した箇所 End If Next ' ------------↓↓今回追加した箇所↓↓------------ Dim SQC As SequenceClass Set SQC = New SequenceClass ListBoxSeq = SQC.SpecialRedim(ListBoxSeq, i - 1) ' ------------↑↑今回追加した箇所↑↑------------ ListBox1.List = ListBoxSeq Dim ComboBoxSeq(1 To 3, 1 To 2) ComboBoxSeq(1, 1) = "接点": ComboBoxSeq(1, 2) = msoShapeFlowchartTerminator ComboBoxSeq(2, 1) = "処理": ComboBoxSeq(2, 2) = msoShapeFlowchartProcess ComboBoxSeq(3, 1) = "分岐": ComboBoxSeq(3, 2) = msoShapeFlowchartDecision With ComboBox1 .ColumnCount = 2 .TextColumn = 1 .BoundColumn = 2 .List = ComboBoxSeq End With End Sub
結果
シート上にコネクタがあっても、それを除外したリストが作成されるようになりました。
次回に続きます。
参考まで。