空談録

世界で5人くらいに役立ちたい

PowerPointのスライドの配色を変更しやすくするアドイン

誰が得するんだって?
とりあえず世界で一人は得するらしいですよ

というわけでいつも通りVSTOアドインです
PowerPointでユーザー定義の配色を作りやすくする + 配色をスライドに適用する
の二つをメインとしたよくわからない粗大ゴミとなっております

見た目はこんな感じ

f:id:fantasticswallow:20150311184657p:plain

機能としては
・配色をカラーコードで設定できる
・スライドの見た目を確認しながら配色を変更できる
・元の配色を維持するので気に入らなければ適用しないことも可能
・選択範囲、もしくはスライド全体の配色に指定したものを適用できる
・選択しているスライドの配色情報を取得して編集できる
・ユーザー定義の配色を取得、編集できる
・ユーザー定義の配色を追加も可能

こんな感じです
ペイントみたいな色を細かく変更したりはできませんのでそういうのがほしい場合はデフォルトの方法で変更しましょう
逆にカラーコードはあるけど設定が面倒くさいって方にはとてもおすすめです

ダウンロードは http://artfulplace.net/files/ThemeColorPicker.zip から
インストールはいつも通り.vstoを実行。アンインストールはプログラムと機能から

よくわからないQ&A集
・インストールできない!
→zip回答してない or 前に書いた方法で

・どこから表示するの
リボンのデザインタブの右端にある何もアイコンがないボタン

・コンボボックスは何を表しているの?
→ユーザー定義の配色。隣の更新でユーザー定義の配色を更新する。選択されたらその配色を展開

・コンボボックスが空なんだけど
→ユーザー定義の配色がない or フォルダが違う。後者の場合はソースがおかしいので報告されれば対応します

・カラーコードって#FFFFFFみたいなフォーマットにだけ対応するの?
→一応、#はあってもなくてもよくて#FFFFFF, #FFFFFFFFと255,255,255みたいにカンマ区切りでRGBを指定することもできます
全角は読めません、ごめんなさい

・色を戻したい
→全部適用してもPowerPoint本体の元に戻すで一発で戻せます
Ctrl+Zなどでどうぞ

とりあえず使い方としてはこんな感じです
以下どうでもいい開発ネタを少し。よくわからなければこの辺まで読んでれば大丈夫です



ThemeColorSchemeとユーザー設定

正直泣きたくなるレベルだったのが今回ですね
毎回クソすぎてつらくなってる気もしますが

さて、テーマの配色を変更するのはThemeColorSchemeであることはオブジェクトブラウザから大体想像がつくのですが、毎度恒例のどこからインスタンスを取得するのかは謎というあれです
インターフェースなのでこっちで作ることもできないおまけつき。VSTOはやはりクソ

というわけでみんな大好きマクロで配色をいじってみます
結果はこれ

ActiveWorkbook.Theme.ThemeColorScheme.Load ( _
        "%APPDATA%\Microsoft\Templates\Document Themes\Theme Colors\ユーザー定義 7.xml" _
        )

あ、%APPDATA%とは本当には出ませんよ。一応書きかえただけです

なるほどユーザー設定の配色はRoamingの中のxmlを見ればいいのか~なるほど~~

なかなか予想外の仕様ですがまあフォルダ分かればあとはそれを見るだけなのでそこまで難しくはないですね。ええ
この.xmlっぽいのが全部配色なのは大体わかるので、xmlを読んで色の情報を取得するだけです
xml自体はそこまで難しくないので頑張って読みます
このときsrgbClrとsysClrの二つが許容されてるのを無視すると死にます。しかもsysClrはlastClrに値があるので互換性なし
なおThemeColorSchemeは使えないのでたぶん自前のColorSchemeに保存する形になるかと思います。正直そっちのほうが平和です

新しく保存するのは正直xmlを構築するのも面倒なのでstring.Formatで組んだりすればいいと思います
幸い要素の数は固定なのでxmlを一つコピペして値の部分を抜けば完成

ここまででも何とも言えない感じですがThemeColorScheme自体がかなりクソです
まずThemeColorSchemeにはSlideRange、Slideからアクセス可能ですが、SlideRangeは「要素数が1の時」のみThemeColorSchemeにアクセスできます
正直何を言っているんだ感しかないわけですがまあそういうことなのでしょう
(1つのときしか動かないならSlideにアクセスすればいいじゃんって思ったりしてはいけない)

このため複数のスライドのThemeColorSchemeを変更する場合foreachで一つずつSlideにアクセスして変更する必要があります。複数のスライドをSlideRangeで変更できればいいのに…
まあSlideRangeで複数枚許容すると値が違うときに困るわけですが

とりあえず一つずつSlideとって、そのThemeColorSchemeにたどり着くわけですが、こっからも地雷
ThemeColorSchemeはGetEnumeratorを実装していますが、foreachすると落ちます
原因不明。むしろなんでGetEnumeratorがあるのかも謎
このため全部の色をコピーする場合、12回Colorsのプロパティにアクセスすることになります

またThemeColorも癖が強く、RGB値をintで持ちます
これはおそらく過去の遺物であるVisual Basicの仕様だと思われるのですが、変換方法がわかりません
追記:下の追記に書いてある通りです
MSDNによるとVBRGB関数を使えとか出るのですがこんなことのためだけにMicrosoft.VisualBasic.dllを参照したくないので自前で実装します
ILゲフンによると、このRGB値は32bitの1~8bitが未使用、9~16bitが青、17~24bitが緑、25~32bitが赤らしいです。個人的には色の順序逆だと思うんですがまあきっと何かがあるのでしょう

追記:@tmyt大先生にこの#AABBGGRRの並びがWin32のCOLORREFが基になってるといわれました
COLORREF (Windows)
特にVB関係ないらしいですね。何も調べない私とてもあれだ
構造体なのでその並びに依存してるとか歴史的なものもあるらしいですがわかりません、ごめんなさい

ざっくりとC#で実装するとこんな感じ

private static int rgbCode(int r, int g, int b)
{
    if (r > 255) { r = 255; }
    if (g > 255) { g = 255; }
    if (b > 255) { b = 255; }
    return b * 65536 + g * 256 + r;
}


後半文章になってないですね…
PowerPointでストレスがたまりすぎた…

ただこんな感じにユーザーコードでforeachして一個ずつ色変えるとかしてもCtrl+Z一発で戻るのには感動しましたね
てっきり一つずつ戻っていくのかと思ったのですが

なんか某べやでVSTOスペシャルなるものが噂になってるのでもしやるならOutlookとかでのアドイン関係の話聞いてみたいですね
普段ExcelPowerPointしか触らないのでいろいろ面白そう

この辺で