ふとしたアイデアを形にしてみる|最近作ったもの3選

昔は、「こんなことをやってみたい」と思っても、
実現までにいくつものハードルがありました。

①アイデア→②実現方法を学ぶ→③試す⇔改善→④実現

特に、②③の壁が高く、途中で挫折することも多かったかなと。


一方で、いまはAIと壁打ちすることで、このハードルはずいぶん下がりました。

「こんなこと、やってみたいかも」

ということが見つかったら、すぐに試してみるのがおすすめです。

Contents

PowerPointの選択スライドを1キーでPDF・画像化

ちょうど、この記事を書く直前に浮かんだアイデアです。

  • YouTubeのサムネイル画像
  • Kindle本の表紙

などは、スクショを撮ったりして対応していました。

手間がたくさんかかるわけではないのですが、
地味にストレスが溜まるのです。

YouTubeは毎日の対応が必要ですし、
Kindle本だと「.png」から「.jpeg」形式に変換が必要で…。


これはAutoHotkeyを使って解決しました。

スライドを選択して『無変換キー+P/N/J』を押すだけで、PDF・PNG・JPEGに変換して保存できます。
※P→PDF/N→PNG/J→JPEG
※通常はPowerPointファイルと同じフォルダに、未保存ファイルなどはデスクトップに保存

作るのに使った時間は、たぶん10分くらい。
でも、効果は絶大です。


もし使ってみたい方は以下からどうぞ。

◇導入方法の参考記事

◇今回作ったコード

クリックして詳細表示
#Requires AutoHotkey v2.0
#SingleInstance Force

; ============================================================
; PowerPoint:現在のスライドを1枚だけ書き出す
;
; 無変換 + P = PDF
; 無変換 + N = PNG
; 無変換 + J = JPEG
;
; ・PowerPoint使用中のみ有効
; ・スライド枠の外にはみ出した部分は出力されない
; ・PNG/JPEGは横1920pxで出力
; ・スライドの縦横比は自動維持
; ・同名ファイルがある場合は上書き
; ・複数スライド選択時は処理しない
; ============================================================


#HotIf WinActive("ahk_exe POWERPNT.EXE")

vk1D & p::ExportCurrentSlide("PDF")
vk1D & n::ExportCurrentSlide("PNG")
vk1D & j::ExportCurrentSlide("JPG")

#HotIf


; ============================================================
; メイン処理
; ============================================================

ExportCurrentSlide(exportFormat)
{
    try {

        ; ----------------------------------------------------
        ; PowerPointを取得
        ; ----------------------------------------------------
        try {
            ppt := ComObjActive("PowerPoint.Application")
        }
        catch {
            throw Error("PowerPointが見つかりません。")
        }


        ; ----------------------------------------------------
        ; アクティブなプレゼンテーションを取得
        ; ----------------------------------------------------
        try {
            pres := ppt.ActivePresentation
        }
        catch {
            throw Error(
                "開いているPowerPointファイルがありません。"
            )
        }


        ; ----------------------------------------------------
        ; PowerPointウィンドウを取得
        ; ----------------------------------------------------
        try {
            win := ppt.ActiveWindow
        }
        catch {
            throw Error(
                "PowerPointのウィンドウを取得できません。"
            )
        }


        ; ----------------------------------------------------
        ; 現在のスライドを取得
        ;
        ; 通常表示:
        ;     View.Slide
        ;
        ; スライドソーター等:
        ;     Selection.SlideRange
        ;
        ; 複数選択の場合は処理しない
        ; ----------------------------------------------------
        try {
            slide := win.View.Slide
        }
        catch {

            try {
                slideRange := win.Selection.SlideRange
            }
            catch {
                throw Error(
                    "現在のスライドを取得できません。`n"
                    . "スライドを表示または1枚だけ選択してください。"
                )
            }

            if (slideRange.Count > 1) {
                throw Error(
                    "複数のスライドが選択されています。`n"
                    . "書き出したいスライドを1枚だけ選択してください。"
                )
            }

            slide := slideRange.Item(1)
        }


        slideIndex := slide.SlideIndex


        ; ----------------------------------------------------
        ; 出力先を決定
        ;
        ; 通常:
        ;     PowerPointファイルと同じフォルダ
        ;
        ; 未保存:
        ;     デスクトップ
        ;
        ; OneDrive / SharePoint等でPathがURL:
        ;     デスクトップ
        ; ----------------------------------------------------
        presPath := ""

        try {
            presPath := pres.Path
        }


        if (
            presPath = ""
            || RegExMatch(presPath, "i)^https?://")
        ) {
            outDir := A_Desktop
        }
        else {
            outDir := presPath
        }


        ; ----------------------------------------------------
        ; ファイル名
        ;
        ; 例:
        ; Sample_p03.pdf
        ; Sample_p03.png
        ; Sample_p03.jpg
        ; ----------------------------------------------------
        baseName := RegExReplace(
            pres.Name,
            "\.[^.]+$"
        )

        basePath :=
            outDir
            . "\"
            . baseName
            . "_p"
            . Format("{:02}", slideIndex)


        ; ----------------------------------------------------
        ; 形式別に書き出し
        ; ----------------------------------------------------
        switch exportFormat {

            case "PDF":

                outPath := basePath ".pdf"

                ExportSlideAsPDF(
                    pres,
                    outPath
                )


            case "PNG":

                outPath := basePath ".png"

                ExportSlideAsImage(
                    pres,
                    slide,
                    outPath,
                    "PNG"
                )


            case "JPG":

                outPath := basePath ".jpg"

                ExportSlideAsImage(
                    pres,
                    slide,
                    outPath,
                    "JPG"
                )


            default:

                throw Error(
                    "未対応の形式です: "
                    . exportFormat
                )
        }


        ; ----------------------------------------------------
        ; 完了通知
        ; ----------------------------------------------------
        ShowTip(
            exportFormat
            . "で保存しました`n"
            . outPath
        )
    }


    catch as err {

        MsgBox(
            "書き出しできませんでした。`n`n"
            . err.Message,
            "PowerPoint Export Error"
        )
    }
}



; ============================================================
; PDF出力
; ============================================================

ExportSlideAsPDF(pres, outPath)
{
    ; --------------------------------------------------------
    ; PowerPoint定数
    ; --------------------------------------------------------
    ppFixedFormatTypePDF := 2
    ppFixedFormatIntentPrint := 2

    ppPrintHandoutHorizontalFirst := 1
    ppPrintOutputSlides := 1
    ppPrintCurrent := 3

    msoFalse := 0


    ; --------------------------------------------------------
    ; COMの Nothing 相当
    ;
    ; VT_DISPATCH = 9
    ; Pointer = 0
    ;
    ; PowerPointのPrintRange引数には
    ; Nothingを明示的に渡す
    ; --------------------------------------------------------
    nothing := ComValue(9, 0)


    ; --------------------------------------------------------
    ; PDF出力
    ;
    ; RangeType = ppPrintCurrent
    ; → 現在のスライドのみ
    ;
    ; PrintRange = Nothing
    ; → Type mismatch回避
    ;
    ; Intent = Print
    ; → 高品質
    ; --------------------------------------------------------
    pres.ExportAsFixedFormat(
        outPath,                        ; Path
        ppFixedFormatTypePDF,           ; PDF
        ppFixedFormatIntentPrint,       ; 高品質
        msoFalse,                       ; FrameSlides
        ppPrintHandoutHorizontalFirst,  ; HandoutOrder
        ppPrintOutputSlides,            ; OutputType
        msoFalse,                       ; PrintHiddenSlides
        nothing,                        ; PrintRange = Nothing
        ppPrintCurrent                  ; RangeType
    )
}



; ============================================================
; PNG / JPEG出力
; ============================================================

ExportSlideAsImage(
    pres,
    slide,
    outPath,
    exportFormat
)
{
    ; --------------------------------------------------------
    ; 出力サイズ
    ;
    ; 横幅1920px
    ; 高さはスライド比率から自動計算
    ;
    ; 例:
    ; 16:9 → 1920 × 1080
    ; 4:3  → 1920 × 1440
    ; --------------------------------------------------------
    targetWidth := 1920


    ; --------------------------------------------------------
    ; PowerPointのスライドサイズを取得
    ; --------------------------------------------------------
    slideWidth := pres.PageSetup.SlideWidth
    slideHeight := pres.PageSetup.SlideHeight


    ; --------------------------------------------------------
    ; アスペクト比を維持して高さを計算
    ; --------------------------------------------------------
    targetHeight := Round(
        targetWidth
        * slideHeight
        / slideWidth
    )


    ; --------------------------------------------------------
    ; 画像を書き出し
    ;
    ; Slide.Exportなので、
    ; スライド枠外にはみ出した部分は出力されない
    ; --------------------------------------------------------
    slide.Export(
        outPath,
        exportFormat,
        targetWidth,
        targetHeight
    )
}



; ============================================================
; 完了通知
; ============================================================

ShowTip(text, duration := 1500)
{
    ToolTip(text)

    SetTimer(
        HideTip,
        -duration
    )
}


HideTip()
{
    ToolTip()
}

WordPress|ダッシュボードでプラグイン操作をかんたんに

いま、WordPressのプラグイン自作にハマっているのですが、
その検証のために、プラグイン追加画面を開くのが手間でした。

管理画面
→プラグイン
→プラグインを追加
→プラグインのアップロード
→ファイルを選択
→インストール

みたいな手順です。

これ、少し改善する都度にクリックしていくと、だんだん疲れるのです…。


そこで、ダッシュボードから直接「インストール・検索・削除」をできるようにしました。

各項目を開くと、こんな感じ。


「ここまでしなくてもいいでしょ…」
と思われる方もいるかもしれません。

でも、自分に役立つのであれば、それでいいのではないかなと。

もし、同じようなことで困っている人がいれば、提供することもできますしね。

足立区の国民健康保険シミュレーションツール

以下の記事で、国民健康保険の試算をExcelでしています。
足立区で夫婦で個人事業|一緒に働く配偶者の給料はいくらにすればいい?

こんなものです。

これ、実は足立区公式でも試算ツールがありました。
足立区HPからアクセス可能

必要な項目を入力すれば試算できるのですが、
ちょっとこれはしんどいなぁと。

計算結果だけ見ても、計算ロジックまでは追いにくいですし。

これ、AIに任せて試算してもらうことも可能です。
ただ、その場合でも計算が合っているかは検証が必要ですし、結局自分で理解しながら作った方がいいなぁと。

「自分が作ったものを、AIと答え合わせをする」

こういった形が、私は好きです。

これも最近作ったものの1つです。

まとめ

他にもいろいろとあるのですが、
今回は切り口の違う3つを書いてみました。

サッと作るためには、日々の鍛錬が大事だったりします。

地味にコツコツと作ってきた経験があるから、
サッと作れるようになる。

そのためにも、浮かんだアイデアをサッと形にする訓練をしていきましょう。

では、また次回。

編集後記

◇日記
 昨日は、久しぶりに遅めの起床。
 前日のビーチバレーボールの夜練が響き…。
 個別コンサルティング、事務所ホームページの見直しなどを中心に。
 8月決算のお客様対応も。

◇ブログネタ経緯
 自作ネタで書きたいと思い。

◇1日1新
 夫婦でまんぷくへ。酸辣湯麵を。

よかったらシェアしてね!
  • URLをコピーしました!
Contents