オートシェイプで矢印を綺麗な環状に並べたい場合がある。
その名の通り「環状矢印」というシェイプを使うのだが、手でやるとなかなか綺麗にできない。
試しに手でやってみたのがこちら。。
ひどい。
そこで今回は環状矢印を綺麗に並べるためのマクロを作成してみた。
コード
Enum CircularArrowAdjustmentItemValues eThickness = 1 eStartDegree = 4 eEndDegree = 3 eArrowheadSize = 5 End Enum Type Position x As Double y As Double End Type Sub Draw360DegreeCircularArrows() '固定値:さわるな危険 Const START_DEGREE_OFFSET = -90 Const END_DEGREE_OFFSET = -110 '設定値:適宜変更よろしく Const RING_SIZE = 300 'ここで指定したリングサイズになる。 Const ARROW_THICKNESS = 0.1 '矢印の太さ。0~0.2くらいまでを、少数で指定する。 Const NUMBER_OF_ARROWS = 5 'ここで指定した数の矢印が書かれる。12くらいが限界。 Dim pos As Position pos.x = 100 pos.y = 100 'メインコードここから Dim startDegree As Long Dim endDegree As Long Dim i As Long For i = 1 To NUMBER_OF_ARROWS Dim sh As Shape: Set sh _ = ActiveSheet.Shapes.AddShape(msoShapeCircularArrow, pos.x, pos.y, RING_SIZE, RING_SIZE) With sh startDegree = endDegree endDegree = startDegree + 360 / NUMBER_OF_ARROWS .Fill.ForeColor.RGB = GetRandomColor .Line.Visible = msoFalse .Adjustments.Item(eThickness) = ARROW_THICKNESS .Adjustments.Item(eStartDegree) = startDegree + START_DEGREE_OFFSET .Adjustments.Item(eEndDegree) = endDegree + END_DEGREE_OFFSET .Adjustments.Item(eArrowheadSize) = .Adjustments.Item(eThickness) End With Next End Sub Function GetRandomColor() Dim r: r = WorksheetFunction.RandBetween(0, 255) Dim g: g = WorksheetFunction.RandBetween(0, 255) Dim b: b = WorksheetFunction.RandBetween(0, 255) GetRandomColor = RGB(r, g, b) End Function
実行方法
Draw360DegreeCircularArrowsを実行すると冒頭の図のように矢印が綺麗に環状に並ぶ。
定数で指定されている設定値を変えることで違った結果になる。
実行結果サンプル
NUMBER_OF_ARROWSに12を指定したのがこちら。
ARROW_THICKNESSを0.05に指定したのがこちら。
NUMBER_OF_ARROWSとARROW_THICKNESSはバランスを取る必要があり、太い矢印で個数を増やしすぎるとバグる。
ARROW_THICKNESSが0.2、NUMBER_OF_ARROWSが12の結果がこちら。
なぜか真ん中に円が。
ARROW_THICKNESSを0.5にしてみると。。。風車みたいになった。
ARROW_THICKNESSが0.2でも、NUMBER_OF_ARROWSが少ないとサマになる。
角度補正について
START_DEGREE_OFFSETがマイナス90度、END_DEGREE_OFFSETがマイナス110度となっている。
実は矢印の頭のサイズ分、.Adjustments.Item(eStartDegree)と.Adjustments.Item(eEndDegree)では角度の開始値がズレているためだ。
このままではとても分かりにくいので、両方とも時計の12時を0度として時計回りの角度で指定できるようにするためにオフセット値を引いて角度を補正している。
以上。