構成図自動結線マクロ(その1)
2021年09月20日
構成図自動結線マクロ(その1)
会社の同僚がエクセルを使って物理構成図を作成していた。
接続するLANポートをオートシェープで作って、そこに番号を振る。
そして、ポート同士を直線コネクタや鍵コネクタで接続する。
LANケーブル90本も引くのに、手作業は辛すぎないか・・・?
しかも、LANポートの位置をずらすと鍵コネクタのアジャスタが
初期化されて動かせず。
これはやばすぎる!!ってことでオートシェープ関係について調べてみた。
まずは物理構成図の基本をチェック。
https://shigotoswitch.com/?p=1231
確かにオブジェクト選択とセルに合わせるボタンを用意しとくと便利。
次に見つけたのがこれ。★
http://blog.livedoor.jp/qoozy/archives/52567093.html
複数のオートシェープを選択してマクロを実行すると、
1つ目に選択したシェイプから2~n番目のシェイプに線を引いてくれる。
これは素晴らしい!!
ソースも書いてあるので、流用させてもらうことにした。
ここでやりたいことの整理。
1.構成図を書くうえで、結線を簡単に描きたい。
2.完成した構成図から結線リストを作成したい。
3.鍵コネクタの線が重なるのを避けたい。
4.なるべく汎用性を持たせるために、修正や取り消しをしたい。
大体こんな感じ。
1については、上記のページを流用すればOK。
2は、コネクタを接続したときに両端のオブジェクトの名前を取得できればいけそう。
3は余力があれば。。。
さっそく★ページのソースを流用してつくってみた。
With ActiveSheet.Shapes.AddConnector の部分で仮のコネクタを作成する。
以下のメソッドで始点と終点のオブジェクトおよび接続箇所を指定。
.ConnectorFormat.BeginConnect Selection.ShapeRange(1), 3 '最初にクリックしたものから
.ConnectorFormat.EndConnect Selection.ShapeRange(i), 1
後々ハマったんだけど、「Selection.ShapeRange(1)」で指定するのはいまいちで
コネクタの接続点の図形名称を取得できなくなる。
【修正前】For i = 1 To Selection.ShapeRange.CountのSelection.ShapeRange(i)
【修正後】For Each shp In Selection.ShapeRangeのshp(shpはShapeオブジェクト)
カンマの後の数値が接続点で、1:上、2:左、3:下、4:右 だった。
今回は、下から上に接続で固定。
.RerouteConnectionsを指定すると、接続点を自動判定してくれるけど
修正が大変になるので使用見送り。
2つのオブジェクトでSelection.ShapeRange(i).Topを比較して決定した。
今回は長くなるのでいったん終了。
引く線は、直線コネクタと鍵コネクタと曲線コネクタの3種類を用意。
With ActiveSheet.Shapes.AddConnector(線種, 0, 0, 0, 0)で
線種を変更すればいいんだけど、withの中身だったのでうまくパラメータ化できず
ださい作りになってしまった。
他の部分はせめてパラメータ化しないとと思って直してたら
コネクタ種類の数値オプションあんじゃん。自作の受け渡しの値と同じだし。
終盤に出てくるオブジェクト名の命名や冒頭に出てくるmaxNumの計算は
自作したコネクタのやり直しマクロへの布石。
オリジナルの名称と通番を振っておけば、けつから順に削除できる。
(UnDoを作るつもりだったけど、1つだけ消すほうが簡単で便利だった。)
NameArrayは、終了時に挿入したコネクタを選択状態にしたかったから用意。
結果はこんな感じ。
【実行前】FWのLポートを最初に選択。
【実行後】FWのLポートから各ポートにコネクタを作成。
以下、ソース。
会社の同僚がエクセルを使って物理構成図を作成していた。
接続するLANポートをオートシェープで作って、そこに番号を振る。
そして、ポート同士を直線コネクタや鍵コネクタで接続する。
LANケーブル90本も引くのに、手作業は辛すぎないか・・・?
しかも、LANポートの位置をずらすと鍵コネクタのアジャスタが
初期化されて動かせず。
これはやばすぎる!!ってことでオートシェープ関係について調べてみた。
まずは物理構成図の基本をチェック。
https://shigotoswitch.com/?p=1231
確かにオブジェクト選択とセルに合わせるボタンを用意しとくと便利。
次に見つけたのがこれ。★
http://blog.livedoor.jp/qoozy/archives/52567093.html
複数のオートシェープを選択してマクロを実行すると、
1つ目に選択したシェイプから2~n番目のシェイプに線を引いてくれる。
これは素晴らしい!!
ソースも書いてあるので、流用させてもらうことにした。
ここでやりたいことの整理。
1.構成図を書くうえで、結線を簡単に描きたい。
2.完成した構成図から結線リストを作成したい。
3.鍵コネクタの線が重なるのを避けたい。
4.なるべく汎用性を持たせるために、修正や取り消しをしたい。
大体こんな感じ。
1については、上記のページを流用すればOK。
2は、コネクタを接続したときに両端のオブジェクトの名前を取得できればいけそう。
3は余力があれば。。。
さっそく★ページのソースを流用してつくってみた。
With ActiveSheet.Shapes.AddConnector の部分で仮のコネクタを作成する。
以下のメソッドで始点と終点のオブジェクトおよび接続箇所を指定。
.ConnectorFormat.BeginConnect Selection.ShapeRange(1), 3 '最初にクリックしたものから
.ConnectorFormat.EndConnect Selection.ShapeRange(i), 1
後々ハマったんだけど、「Selection.ShapeRange(1)」で指定するのはいまいちで
コネクタの接続点の図形名称を取得できなくなる。
【修正前】For i = 1 To Selection.ShapeRange.CountのSelection.ShapeRange(i)
【修正後】For Each shp In Selection.ShapeRangeのshp(shpはShapeオブジェクト)
カンマの後の数値が接続点で、1:上、2:左、3:下、4:右 だった。
今回は、下から上に接続で固定。
.RerouteConnectionsを指定すると、接続点を自動判定してくれるけど
修正が大変になるので使用見送り。
2つのオブジェクトでSelection.ShapeRange(i).Topを比較して決定した。
今回は長くなるのでいったん終了。
引く線は、直線コネクタと鍵コネクタと曲線コネクタの3種類を用意。
With ActiveSheet.Shapes.AddConnector(線種, 0, 0, 0, 0)で
線種を変更すればいいんだけど、withの中身だったのでうまくパラメータ化できず
ださい作りになってしまった。
他の部分はせめてパラメータ化しないとと思って直してたら
コネクタ種類の数値オプションあんじゃん。自作の受け渡しの値と同じだし。
終盤に出てくるオブジェクト名の命名や冒頭に出てくるmaxNumの計算は
自作したコネクタのやり直しマクロへの布石。
オリジナルの名称と通番を振っておけば、けつから順に削除できる。
(UnDoを作るつもりだったけど、1つだけ消すほうが簡単で便利だった。)
NameArrayは、終了時に挿入したコネクタを選択状態にしたかったから用意。
結果はこんな感じ。
【実行前】FWのLポートを最初に選択。
【実行後】FWのLポートから各ポートにコネクタを作成。
以下、ソース。
Sub オートシェイプを直線で繋ぐ()
オートシェイプをコネクタで繋ぐ (1)
End Sub
Sub オートシェイプを鍵線で繋ぐ()
オートシェイプをコネクタで繋ぐ (2)
End Sub
Sub オートシェイプを曲線で繋ぐ()
オートシェイプをコネクタで繋ぐ (3)
End Sub
Sub オートシェイプをコネクタで繋ぐ(ConnectorOpt As Long)
'ConnectorOpt コネクタ形状オプション 1:直線 2:鍵式、3:カーブ
If ConnectorOpt <> 1 And ConnectorOpt <> 2 And ConnectorOpt <> 3 Then
End '規定外オプションは終了
End If
On Error GoTo ERR1 'オブジェクト未選択対策
'-----------------------------------------------------------オプション開始
Dim stcPos As Long, edcPos As Long '上下スタイルか左右スタイルか
If Selection.ShapeRange(2).Top > Selection.ShapeRange(1).Top Then
stcPos = 3: edcPos = 1
Else
stcPos = 1: edcPos = 3
End If '上下スタイル終了
' If Selection.ShapeRange(2).Left > Selection.ShapeRange(1).Left Then
' stcPos = 4: edcPos = 2
' Else
' stcPos = 2: edcPos = 4
' End If '左右スタイル終了
'コネクタスタイル
Const Con_arrowheadStyle = 1 '1:矢印なし, 2:三角矢印, 3:開いた矢印, 4:鋭い矢印, 5:ひし型, 6:円形矢印
Const Con_arrowheadLength = 2 '1:短い, 2:普通, 3:広い
Const Con_arrowheadWidth = 1
Const Con_LineWeight = 3 '太さ
Const Con_R = 0: Const Con_G = 0: Const Con_B = 0 'RGB(0, 0, 0) '光の三原色
Const Con_Transparency = 0 ' .Line.Transparency = 0 '0.0 (不透明) ~ 1.0 (透明)
'-----------------------------------------------------------オプション終了
'まず、コネクタ名の開始番号をチェック
Dim maxNum As Long, tarNum As Long
Dim spPos As Long, shapeName As String
Dim i As Long
For i = 1 To ActiveSheet.Shapes.Count 'シート内の名前をチェック
shapeName = ActiveSheet.Shapes(i).Name
If Left(shapeName, 5) = "myCn_" Then
spPos = InStrRev(shapeName, " ")
tarNum = Mid(shapeName, spPos + 1, 4)
If tarNum > maxNum Then maxNum = tarNum 'tarnumの最大値を探す
End If
Next i
Debug.Print "maxNum=" & maxNum
Dim cnt As Long 'インデックス番号
cnt = Selection.ShapeRange.Count 'まず選択中のシェイプを選択した順に取得(何もしなくても選択順になる)
If cnt < 2 Then
MsgBox "2つ以上のオートシェイプを選択してください。"
Exit Sub
End If
Dim NameArray() As String
ReDim NameArray(cnt - 2)
'コネクタを作っていく開始
Dim shp As Shape, shpCnt As Long, shp1 As Shape
For Each shp In Selection.ShapeRange
shpCnt = shpCnt + 1
If shpCnt > 1 Then
maxNum = maxNum + 1
'コネクタを作る
With ActiveSheet.Shapes.AddConnector(ConnectorOpt, 0, 0, 0, 0) 'ConnectorOpt 1:直線 2:鍵式、3:カーブ
'コネクタの色や太さを変更
.Line.EndArrowheadStyle = Con_arrowheadStyle
.Line.EndArrowheadLength = Con_arrowheadLength
.Line.EndArrowheadWidth = Con_arrowheadWidth
'.Line.Visible = msoTrue '非表示にはしないでしょ
.Line.Weight = Con_LineWeight '太さ
.Line.ForeColor.RGB = RGB(Con_R, Con_G, Con_B) '光の三原色
.Line.Transparency = Con_Transparency '0.0 (不透明) ~ 1.0 (透明)
'シェイプ同士を繋ぐ
.ConnectorFormat.BeginConnect shp1, stcPos '最初にクリックしたものから
.ConnectorFormat.EndConnect shp, edcPos '他のシェイプへ
'コネクト位置 1:上、2:左、3:下、4:右
'.RerouteConnections '位置を自動判定
.Name = "myCn_" & "Straight " & maxNum
NameArray(shpCnt - 2) = "myCn_" & "Straight " & maxNum
End With
Else
Set shp1 = shp
End If
Next
ActiveSheet.Shapes(NameArray(0)).Select Replace:=True
For i = 1 To UBound(NameArray)
ActiveSheet.Shapes(NameArray(i)).Select Replace:=False
Next i
Exit Sub
ERR1:
MsgBox "2つ以上のオートシェイプを選択してください。"
End Sub
PR
Comment