Powerpoint VBAを使おう!

Powerpoint VBAやExcelのVBAで遊んでいます。Word VBAも始めました。

図形の記録と再現に挑戦中。

パワーポイントには記録マクロがありません。

Excelの記録マクロってのはやっぱり便利で,せっかくいろいろやっていますし,

このようにブログに書くときに,いちいち

スライドに ■△◇ と △▲◇ の図形と 〇行●列のテーブルを用意して実行してください・・

とか書くのが嫌いです。

じゃあファイルの添付ができるように,どこかにHP準備して・・

とかできるほど,私が書くこちらに意義を感じているわけではありません。

今ではきちんと,自分の備忘録として使っていて,その点では十分に役に立っています。

紙のノートだと検索できませんから・・(;´▽`A`` インデックスのところを開いて,ページ内検索でだいたいのことを把握して,以前書いたコード例を引っ張り出して,と

当初の目的を十分に達しました。パワーポイントでVBAで組むにあたり最低限のことは書けていると思えています。


じゃあ,今後何書こうかな・・。何か書かないと 面白くはないしな,と思い,今後も何か書く上で,

エクセルでいつかやったように,スライドのオブジェクト類を記録再現できる仕組みを作ろうと思いました。

パワーポイントでなら特に意義はあると思いますし。記録マクロ無いですからね・・

テーブルやテキストボックスやマクロの関連付けとかは簡単なんですが,今戦っているのはフリーフォーム。

なかなかの敵ですし,どこ検索しても私が知っている範囲のことが書かれているのがほとんど。

もう一歩のところを書いてあるところが無くて,いつも通り悪戦苦闘中です。


とはいえ,とても面白い相手なのでもう少し頑張ります。
f:id:chemiphys:20170126212526p:plain
こういうフリーフォームを再現してみているところです。

コードはこちら。

Option Explicit

Sub test()
Dim TSlide As Slide: Set TSlide = ActivePresentation.Slides(1)
Dim s As Shape
Dim colShape As Collection: Set colShape = New Collection
For Each s In TSlide.Shapes
    If s.Type = msoFreeform Then
        colShape.Add "Freeform:" & s.Name & ":" & s.Fill.ForeColor.RGB & StrFreeform(s)
    End If
Next

Dim TSlide2 As Slide: Set TSlide2 = ActivePresentation.Slides(2)
Dim i As Long, j As Long
Dim strNode As String, ff As FreeformBuilder, sf As Shape

For i = 1 To colShape.Count
    Select Case Split(colShape(i), ":")(0)
        Case "Freeform"
            Call DrawFreeForm(colShape(i), TSlide2)
    End Select
Next
End Sub

Function StrFreeform(図形 As Shape) As String
    Dim 各ノード As ShapeNode
    
    For Each 各ノード In 図形.Nodes
        StrFreeform = StrFreeform & ":" & CLng(各ノード.Points(1, 1)) & "," & CLng(各ノード.Points(1, 2)) & "," & 各ノード.SegmentType
    Next
End Function

Sub DrawFreeForm(strNode As String, pslide As Slide)
    Dim i As Long, ff As FreeformBuilder, sf As Shape

    Set ff = pslide.Shapes.BuildFreeform(msoEditingAuto, CLng(Split(Split(strNode, ":")(3), ",")(0)), CLng(Split(Split(strNode, ":")(3), ",")(1)))
    For i = 4 To UBound(Split(strNode, ":"))
        ff.AddNodes msoSegmentLine, msoEditingAuto, Split(Split(strNode, ":")(i), ",")(0), Split(Split(strNode, ":")(i), ",")(1)
    Next
    Set sf = ff.ConvertToShape
    sf.Name = Split(strNode, ":")(1)
    sf.Fill.ForeColor.RGB = Split(strNode, ":")(2)

    
    Debug.Print "with pSlide.Shapes.BuildFreeform(msoEditingAuto, " & CLng(Split(Split(strNode, ":")(3), ",")(0)) & ", " & CLng(Split(Split(strNode, ":")(3), ",")(1)) & ")"
    For i = 4 To UBound(Split(strNode, ":"))
        Debug.Print "        .AddNodes msoSegmentLine, msoEditingAuto, " & Split(Split(strNode, ":")(i), ",")(0) & ", " & Split(Split(strNode, ":")(i), ",")(1)
    Next
    Debug.Print "    .ConvertToShape"
    Debug.Print "end with"
    Debug.Print "pslide.shapes(pslide.shapes.count).Name = """ & Split(strNode, ":")(1) & """"
    Debug.Print "pslide.shapes(pslide.shapes.count).fill.forecolor.rgb = " & Split(strNode, ":")(2)

End Sub

スライド1の図形をスライド2に再現します。スライド1に適当にフリーフォームで書いて,スライド2をとりあえず作り,testマクロを実行をしてみてください。
f:id:chemiphys:20170126212826p:plain
こうなります。

場所とかは正確に写し取っています。内部での名前に書き替えられますが,一応名前もそれっぽく引き継ぎます。

あと,スライドの宣言を事前に付け加えないといけませんが,このカクカクした図形を書くコードをイミディエイトウィンドウに出力します。

これをやってて,はたと気づきました。

むむむ・・

ポイント数が多すぎる。

確認してみてわかったんですが,コントロールポイントもNodeとして取得するんです。

取得したすべてのノードを繋ぐと変な図形になるわけです。


どうすればいいんだろうと,Excelの記録マクロでノードの変化をたどろうとしたら,それはExcel記録してくれません。

ムムム・・

さらに悩み調べまくりましたが,最終的に私を納得させる答えは,MSDNにありました。

FreeformBuilder.AddNodes Method (PowerPoint)

Syntax

  expression .AddNodes(SegmentType, EditingType, X1, Y1, X2, Y2, X3, Y3)

If the EditingType of the new node is msoEditingCorner, this argument specifies the horizontal distance (in points) from the upper-left corner of the document to the first control point for the new segment.

Excelの記録マクロ等でも,きちんとフリーフォームの描画は記録しません。

記録マクロで記録した図形を描かせてみると愕然とします。ぜんぜん再現されない(゚▽゚*)

でも,たまーに引数が異様に多いことがあるんです。

なんだろうなぁと思ってて,このページをきちんと読んだら,EditingTypeをmsoEditingCornerにしたときに限り,Control pointを引数で与えられる,と書かれているんですね。

コントロールポイントをきちんと制御できることがここでわかりました。

なので,先ほど載せていたコードで座標を記録させれば,その座標を利用してきちんと図形が描けそうなところまでは確認した。

光が十分に見えます。

ただ,残念ながらファジーなところがあり,

直線で結ぶ部分が含まれると,ノードの数が安定しないんです。ローカルウィンドウやら,いろいろなノードの情報やらを書き出させたりしてかなりにらめっこしましたが,

今のところは引数の数をきちんと処理できるようになるまでは,スライド上の図形を記録し,それをコードに変えるということはちょっと遠い。

でも,コントロールポイントの制御が全く分からなかった最初から考えれば十二分に進歩しています。

忙しい時期に入り,本当はこんなことにかまけてたらいけないんですが,

あいかわらず考えることは楽しく,興味は尽きません(;´▽`A``