はじめに
パワポに複数の画像を貼り付けてトリミングサイズを合わせたいと思った時に,同時にトリミングがで来ませんでした.
一つずつ数値を入力するのはとてもとても時間と労力かかるので,同時にできるマクロをつくろうってわけです.
マクロに,数値を入力できるインターフェースが欲しい時があります.文字サイズのような.
そんな時に,アドインが使えるんじゃないかと思いました.知らんけど.
基礎ちしき
そもそもパワポファイルはxmlファイルをzipで圧縮したもの(エクセル,ワードも).
このxmlをいじると,自作のマクロをタブしちまうことだってできるでやんす.
ちなみに,拡張子をzipに変えて展開すればメディアファイル等を拾えるらしいです.やったことないけど.
拡張子
pptx:マクロ無し
pptm:マクロ有効化
ppam:アドイン(昔は.ppa)
Macの場合,アドインは名前をつけて保存ではなく,エクスポート…から出力できます.
必要なもの
・マクロ開発済み.pptmファイル.1つ
・zip圧縮・展開できるファールアーカイバアプリ.1つ.(ここでは,Kekaを使うよ!)
・エディタ.1つ.(必須ではないけど,扱うのはxmlなのであると便利!必須!)
やりかた
ながれ
マクロ有効化ファイル(.pptm)でタブの見た目を調整・確認後に,タブにします.なんならアドインにします.
1..pptmを展開
2.ファイルの数箇所を変更する
3..pptmに戻す.ボタンの配置とかの確認.
4.マクロの数箇所を変更する
5..ppamにしてアドインにしてしまう
注意点として,マクロを変更すると1から始めることになる.
というのも,2でxmlの編集を行い,編集の確認をするには3でpptmに必要がある.
が,実はマクロは1で展開した時点で.binファイルになり,変更できなくなる(したくなくなる).
そのため,3でpptmに戻すとマクロは1の展開時のものになり,2でマクロを編集しても無かったことになる.
xmlの編集と,マクロの編集は片方ずつでないとダメ.
1..pptmファイルの展開
ファイルアーカイバアプリで展開しましょう.
右クリック -> ファイルアーカイバKekaに送信(など)
フォルダが生まれます.
2.ファイルを変更する
VSCodeなら,拡張機能"XML"があれば,shft alt f でコードの整列ができます.
次の2つのファイルを変更と作成すると新しくタブを作ることができます.
_res/.rels
<Relationships>タグ内に,次の1行を追加.
<Relationship Id="myCustomUI" Type="http://schemas.microsoft.com/office/2006/relationships/ui/extensibility" Target="customUI/customUI.xml"/>
customUI/customUI.xml
customUIフォルダを作成し,以下の中身のcustom.xmlを作成.
<customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui" onLoad="InitCustomTab">
<ribbon startFromScratch="false">
<tabs>
<tab id="customTab" label="CUSTOM TAB" insertBeforeMso="TabHome">
<group id="customGroup1" label="Shapes and Pictures" insertBeforeMso="TabHome">
<editBox id="EditBoxCropWidth" label="Width:" sizeString="WW" getText="GetEditBoxText" onChange="SetEditBoxText" />
<editBox id="EditBoxCropHeight" label="Height" sizeString="WW" getText="GetEditBoxText" onChange="SetEditBoxText" />
<button id="GetSize" label="Get Crop Size" imageMso="PicturePropertiesSize" size="large" onAction="GetImgCropSize" />
<button id="Apply" label="Apply Crop Size" imageMso="PicturesCompress" size="large" onAction="CropImgs" />
</group>
</tab>
</tabs>
</ribbon>
</customUI>
<customUI>
たまにxmlns属性に2007/09のものを指定しているものを見るが,Macでは無理ぽい?バージョンなのかな.
onLoar属性にマクロ名を指定するとそのマクロがタブを表示した時に呼び出される.
<tabタグ>
labelで指定したものがタブ名として表示される.
タブを並び替える場合,属性"insertAfterMso"or"insertBeforeMso"を追加すると可能.各タブのMsoを指定すればok.(調べてね)
例:ホームタブの左側insertBeforeMso="TabHome"
<editbox>
フォントサイズ等入力する部分のやつ.
sizeSttingは入力部分のサイズ.指定した文字の分のサイズになる.文字幅の広いWを指定するものをよく見る.
onChangeは,入力後にEnterか別のものを選択した場合に呼び出すマクロ名
getTextは,入力ボックスがユーザに表示される時(タブを切り替えた時など)と,onChangeの呼び出し後によびだされる(と思う).
<button>
ボタン.
・imageMsoはボタンのアイコン.たくさんある.
参考:https://ymrt.jp/imagemso/index.html(2022年9月)
・sizeは大きさ.largeかnormal.
・onActionは,ボタン押された時に呼び出すマクロ.
3..pptmに戻す
展開したフォルダの中にある全てのファイルをまとめてアーカイブにします.
右クリック -> Kekaで圧縮
アーカイブ.zipが生まれます.
アーカイブ.zipの拡張子を.pptmに変更すると,開けるようになります.
タブができてるはず.
4.マクロの変更
Option Explicit
Dim crop_ratio As Single ' 倍率の値
Public CustomRibbon As IRibbonUI ' EditBoxの更新に必要
Private current_crop_width As String ' 幅
Private current_crop_height As String ' 高さ
Dim c As Single ' ピクセル - cm間の変換に使う
Dim CustomIds As ids ' xmlのid属性を間違えないようにユーザ定義
Private Type ids
CropWidth As String
CropHeight As String
End Type
Sub InitCustomTab(ribbon As IRibbonUI) ' onLoadで絵呼び出す
CustomIds.CropWidth = "EditBoxCropWeigh"
CustomIds.CropHeight = "EditBoxCropHeight"
Set CustomRibbon = ribbon
current_crop_width = "-1"
current_crop_height = "-1"
c = 0.03527777777
End Sub
Sub GetEditBoxText(ByRef control As IRibbonControl, ByRef text)
Dim size_pt_str As String
size_pt_str = ""
If control.Id = "EditBoxCropWeigh" Then size_pt_str = current_crop_width
If control.Id = "EditBoxCropHeight" Then size_pt_str = current_crop_height
If Val(size_pt_str) < 0 Then
text = ""
Else
text = CStr(CInt(Val(size_pt_str) * 100) / 100)
End If
End Sub
Sub SetEditBoxText(ByRef control As IRibbonControl, ByRef text As String)
' 入力してEnter
If Not IsNumeric(text) Then
If control.Id = CustomIds.CropWidth Then text = current_crop_width
If control.Id = CustomIds.CropHeight Then text = current_crop_height
CustomRibbon.InvalidateControl (control.Id)
Else
If control.Id = CustomIds.CropWidth Then current_crop_width = text
If control.Id = CustomIds.CropHeight Then current_crop_height = text
CropImgs
End If
End Sub
Sub GetImgCropSize()
Dim w_before As Single, w_org As Single
With ActiveWindow.Selection
If .Type = ppSelectionShapes Then
If .ShapeRange.Count > 0 Then
If .ShapeRange(1).Type = msoPicture Then
.ShapeRange(1).LockAspectRatio = msoTrue
' crop size
current_crop_width = .ShapeRange(1).PictureFormat.Crop.ShapeWidth * c
current_crop_height = .ShapeRange(1).PictureFormat.Crop.ShapeHeight * c
CustomRibbon.Invalidate ' EditBox 更新
' crop_ratio
w_before = .ShapeRange(1).PictureFormat.Crop.ShapeWidth
.ShapeRange(1).ScaleWidth 1, msoTrue
w_org = .ShapeRange(1).PictureFormat.Crop.ShapeWidth
crop_ratio = w_before / w_org
.ShapeRange(1).Width = w_before
End If
End If
End If
End With
End Sub
Sub CropImgs()
Dim shp As Shape
With ActiveWindow.Selection
If .Type = ppSelectionShapes Then
For Each shp In .ShapeRange
If shp.Type = msoPicture Then
If crop_ratio > 0 Then
shp.LockAspectRatio = msoTrue
shp.ScaleHeight crop_ratio, msoTrue
End If
With shp.PictureFormat.Crop
If Val(current_crop_width) > 0 _
And Val(current_crop_height) > 0 Then
.ShapeWidth = Val(current_crop_width) / c
.ShapeHeight = Val(current_crop_height) / c
End If
End With
End If
Next
End If
End With
End Sub
ポイントは,マクロからEditBoxへ値を取得することができないという点.
Apply!ってボタン押しても,誰に値聞けばいいですか??になる.
ので,入力があったときにその値を保持する必要があり,それ(current_crop_width, height)をはじめに宣言しておく.
keytip
他のと競合があると、自動的に割り振られたものになる。
競合したものが表示されてなければ(有効になっていなければ)大丈夫。
5..ppamにしてアドインにしてしまう
エクスポート…から.ppamを選択して出力.
VBAコードはコンパイルできません...の場合,何か未定義の変数がある可能性あり.
アドイン化はマクロが1つもないとアドイン(*.ppam)形式で保存できない。
アドインの追加は、開発タブを表示させて、開発タブのアドインの追加化じゃないとできない?
要素
[MS-CUSTOMUI]: Custom UI | Microsoft Learn
idMsoを指定して、Labelを表示させなくするには、showLabel="false"を追加。
idMso
[MS-CUSTOMUI]: idMso Tables | Microsoft Learn