【ExcelVBA】図形を線で繋ぐ

図形移動が作れたので、いよいよ大詰めの “線で繋ぐ" でっす。

フローチャートなんで、線で繋がないと意味がないです。
繋ぐ方法は、線を引いて二つの図形を繋げるだけなんで、
簡単と言えば簡単なんですが…

まずは、線で繋ぐ部分を手動で行ってみようと思います。
コネクタ①.jpg
まずは、矢印線を選択してシート上に作成します。

線が引けたら繋ぎたい図形の結合点に、線の結合点を重ねる事で、
コネクタ②.jpg
図形と線を接合する事ができます。

ひし形の図形にも矢印線を結合して、図形を移動させてみます。
コネクタ③.jpg
結合された線は、図形と共に移動します。

これをコードにしていきます。

まずは、矢印線を引いてみます。
標準モジュール

Option Explicit

Sub Connection()

Dim arrow As Shape

Set arrow = ActiveSheet.Shapes.AddConnector(msoConnectorStraight, 250, 300, 250, 370)

With arrow.Line
.EndArrowheadStyle = msoArrowheadTriangle
.Visible = msoTrue
.Weight = 1.75
End With

End Sub

説明すると、
ActiveSheet.Shapes.AddConnectorで線を引く事ができます。
()内は、線のタイプ、始点X座標、始点Y座標、終点X座標、終点Y座標を設定します。

線が引けたら、線の書式設定をします。
.EndArrowheadStyleで、矢印の形を設定します。
.Visibleで、線を入れるかなので当然Trueにします。
.Weightで、線の太さを設定します。

色なども設定できます。

このプロシージャをボタンに割り当てれば線を引く事ができます。

今回は、ユーザーフォーム上のボタンに設定するので、
ボタンモジュールでCall Connectionすれば機能します。

矢印線が引けたので、ここからは図形の結合を作っていきます。
標準モジュール

Option Explicit

Sub Connection()

Dim arrow As Shape '矢印線取得'
Dim selectSh(2) As Shape '選択中の図形取得'

Dim sh As Shape '図形検索変数'
Dim i As Long '配列カウント変数'

i = 0

'選択中の図形を検索して取得'
For Each sh In Selection.ShapeRange
Set selectSh(i) = sh
i = i + 1
Next

'仮線を作成'
Set arrow = ActiveSheet.Shapes.AddConnector _
(msoConnectorStraight, 1, 1, 1, 1)

'仮線を図形に繋ぐ'
With arrow
.ConnectorFormat.BeginConnect selectSh(0), 1
.ConnectorFormat.EndConnect selectSh(1), 1
.RerouteConnections

'線の書式設定'
With .Line
.EndArrowheadStyle = msoArrowheadTriangle
.Visible = msoTrue
.Weight = 1.75
End With

End With

End Sub

ちょっとややこしいので説明すると、

選択した図形をピックアップして、配列変数に取得しておきます。
For Each~Nextまでが取得部分になります。

図形が取得できたら矢印線を引くのですが、仮線として作図しておきます。
仮線なので、座標やサイズは適当でOKでっす。

図形に結合する事で座標や長さは自動的に調整されます。

.ConnectorFormat~.RerouteConnectionsまでが図形への接続部分になります。
開始図形の結合点~終了図形の結合点を指定する事で線を自動的に接続してくれます。

BeginConnectは、開始図形で、
EndConnectは、終了図形になります。

配列で取得しておいた、
一つ目が開始図形、BeginConnect selectSh(0), 1となります。
終了図形は、二つ目の図形なので、EndConnect selectSh(1), 1となります。

どちらとも末尾に1と設定していますが、結合点の位置を設定しています。

結合点は、
コネクタ④.jpg
結合点は、こんな感じで設定されています。

ここで少しややこしい話になるのですが、
今回、結合点をどちらとも1に設定しました。

本来なら開始図形の1と終了図形の1に接続されます。
繋がり方としては、おかしいですよね。

開始図形の3と、終了図形の1と設定しないとダメでは?となります。

そこで、.RerouteConnectionsを設定します。

これは、リルートとなってる通り、
一度接続した線を再接続する設定になります。

RerouteConnectionsの処理については、
Microsoftドキュメント
コネクタを接続するとき、コネクタを接続する図形の結合点を指定しますが、コネクタを接続した後に RerouteConnections メソッドを使用すると、コネクタを接続する結合点が変更され、元の結合点の選択は無効となります。
との事なので、結合点を指定しても無視されます。

メリットとしては、接合する線が、図形の最短距離になるように、
結合点と線の長さを調整してくれる所です。

結合点を指定して接続したい場合は、RerouteConnectionsは必要ないので、
開始図形と終了図形の指定だけすれば、結合点も任意の場所に設定する事ができます。

これで、接続ができるようになったのでテストしてみます。
コネクタ⑤.jpg
問題無く接続できました。

接続までできたので、図形取得について小ネタを書いておきます。

For Eachで、選択中の図形を取得したわけですが、
ShapeRangeプロパティで、選択中の図形をピックアップしました。

このShapeRangeには、選択した順番なんかも格納されています。
なので、上図形・下図形と順に選択した場合と
下図形・上図形と選択した場合では、取得順番が変わります。

試しにテストしてみます。
コネクタ⑥.jpg
上・下の順で選択すると矢印線は下向きになります。

コネクタ⑦.jpg
下・上の順で選択すると矢印線は上向きになります。

選択順がキープされているのは、ありがたいですね~
接続したい順に図形を選択すれば、矢印の向きを調整しなくてすみます。

と、ShapeRangeの小ネタは、これくらいにして。


これで図形の接合ができるようになりました。
しかし!

フローと言えば分岐が存在します。
当然、直線だけじゃなくて、カギ線でも繋ぐ必要があります。

そんなに大きくは変わらないと思うので、バイパス繋ぎも作ってみます。
標準モジュール

Sub ElbowConnect()

Dim arrow As Shape '矢印線取得'
Dim selectSh(2) As Shape '選択中の図形取得'

Dim sh As Shape '図形検索変数'
Dim i As Long '配列カウント変数'

i = 0

'選択中の図形を検索して取得'
For Each sh In Selection.ShapeRange
Set selectSh(i) = sh
i = i + 1
Next

'仮線を作成'
Set arrow = ActiveSheet.Shapes.AddConnector _
(msoConnectorElbow, 1, 1, 1, 1)

'仮線を図形に繋ぐ'
With arrow
.ConnectorFormat.BeginConnect selectSh(0), 4
.ConnectorFormat.EndConnect selectSh(1), 4

'線の書式設定'
With .Line
.EndArrowheadStyle = msoArrowheadTriangle
.Visible = msoTrue
.Weight = 1.75
End With

End With

End Sub

基本的には、まったく同じなんですが、
変更点は、
・線種は、msoConnectorElbowタイプをチョイス
・.RerouteConnectionsを抜いて、結合点を4にする

図形の右側にカギ線のバイパスを繋げる感じになります。

これで線が引けるようになったので、簡単なフローを作ってみます。
コネクタ⑧.jpg
うまく作れています。ヽ(´▽`)/~♪

少しづつ機能が作れてくると嬉しくなってきますね~♪


図形の接続ができたので、
これで完成! とはいかないんですよね~(T-T) グスッ

実は、いろいろと問題点があります。
・矢印線も図形なので、セル中央揃えに反応してしまう。
・図形が選択されてないとエラーがかかる
・一つしか図形が選択されてないとエラーがかかる
・三つ以上の図形に対応できない

この辺りを作りこまないと使い勝手が悪いので、
次回は、修正と複数選択時の処理を記事にまとめられるように
頑張って作ろうと思います。

それでは、( ^ 0 ^ )/~~~~see you again



この記事へのコメント