Excel VBA 逆引き集 | Excel以外のアプリ制御

Excel VBA
スポンサーリンク
  1. ねらい:Excelの外へ手を伸ばし、他アプリを「安全に・確実に」動かす
    1. 重要ポイントの深掘り
  2. COMオートメーション:Word/PowerPoint/Outlookを直接操作する
    1. Wordを自動生成してPDF出力するテンプレ
    2. PowerPointを作成し、スライドに表を貼ってPDF保存
    3. Outlookでメール送信(添付・本文・下書き保存)
    4. 重要ポイントの深掘り
  3. プロセス実行:Shell/WScript.Shell/PowerShellで外部コマンドを走らせる
    1. ShellでバッチやEXEを呼び、完了を待つ(最短形)
    2. PowerShellを呼び出して柔軟な処理(JSON整形・API呼び出しなど)
    3. 重要ポイントの深掘り
  4. UI操作:最終手段のSendKeys/ウィンドウ制御(最小限・安全策)
    1. SendKeysで簡易操作(推奨は最小限)
    2. 重要ポイントの深掘り
  5. ブラウザ・Web連携:既定は外部コマンドやAPIで(VBA単体でのWeb操作は非推奨)
    1. 既存APIをPowerShellで叩き、結果ファイルで受け渡す
    2. 重要ポイントの深掘り
  6. ファイル・フォルダ操作:FileSystemObjectで外部資産と連携
    1. フォルダ走査・コピー・タイムスタンプ判定
    2. 重要ポイントの深掘り
  7. 例題の通し方:Word→PDF、PPT→PDF、メール下書き、外部コマンド
    1. 動作確認の流れ
    2. 確認ポイント
  8. 落とし穴と対策(深掘り)
    1. 権限・ポリシーで外部起動がブロックされる
    2. プロセスが残る・解放漏れ
    3. フォーカスずれ・誤操作
    4. 文字コードやロケール差
  9. 導入手順と拡張の道筋
    1. 最初の一歩
    2. 次の拡張
  10. まとめ:COMとコマンドを使い分け、「待ち・後片付け・契約」を固定する

ねらい:Excelの外へ手を伸ばし、他アプリを「安全に・確実に」動かす

Excel VBAから他アプリを制御する方法は大きく3系統です。COMオートメーション(Word/PowerPoint/OutlookなどのOffice系)、プロセス実行(Shell/PowerShell)、UI操作(SendKeys/ウィンドウハンドル)。最優先は「直接APIがあるCOM連携」を使い、次点で「コマンドライン経由」、最後に「UI操作」は避けつつ最小限に。初心者でも貼って動かせるテンプレートと、壊れにくい運用の勘所を丁寧に解説します。

重要ポイントの深掘り

制御は「待ち」と「後片付け」が命です。起動後に完了を待たずに次へ進むと壊れます。成功・失敗を判定し、例外でも必ず後片付け(アプリ終了・COM解放)まで到達する枠をコードに組み込みます。コマンドは「引数を明示」「文字コードを統一」「ログを残す」を徹底すると、現場で詰まりません。


COMオートメーション:Word/PowerPoint/Outlookを直接操作する

Wordを自動生成してPDF出力するテンプレ

' ModWordAutomation.bas
Option Explicit

Public Sub Run_WordToPdf(ByVal outPdf As String)
    On Error GoTo EH
    AppEnter "Word Export"
    Dim wd As Object, doc As Object
    Set wd = CreateObject("Word.Application")
    wd.Visible = False

    Set doc = wd.Documents.Add
    doc.Content.Text = "自動生成ドキュメント" & vbCrLf & "日付: " & Format(Now, "yyyy/mm/dd HH:nn")

    doc.ExportAsFixedFormat outPdf, 17 ' 17=wdExportFormatPDF
    doc.Close False
    wd.Quit

    AppLeave
    MsgBox "PDF出力完了: " & outPdf
    Exit Sub
EH:
    On Error Resume Next
    If Not doc Is Nothing Then doc.Close False
    If Not wd Is Nothing Then wd.Quit
    AppLeave
    MsgBox "失敗: " & Err.Description, vbExclamation
End Sub
VB
' ModApp.bas(開始・終了枠)
Option Explicit
Public Sub AppEnter(Optional ByVal status As String = "")
    Application.ScreenUpdating = False
    Application.EnableEvents = False
    Application.DisplayAlerts = False
    Application.Calculation = xlCalculationManual
    If Len(status) > 0 Then Application.StatusBar = status
End Sub
Public Sub AppLeave()
    Application.StatusBar = False
    Application.Calculation = xlCalculationAutomatic
    Application.DisplayAlerts = True
    Application.EnableEvents = True
    Application.ScreenUpdating = True
End Sub
VB

PowerPointを作成し、スライドに表を貼ってPDF保存

' ModPowerPointAutomation.bas
Option Explicit

Public Sub Run_PptExport()
    On Error GoTo EH
    AppEnter "PPT Export"
    Dim ppt As Object, pres As Object, slide As Object
    Set ppt = CreateObject("PowerPoint.Application")
    ppt.Visible = True

    Set pres = ppt.Presentations.Add
    Set slide = pres.Slides.Add(1, 12) ' ppLayoutBlank=12

    ' Excelの範囲をコピーして貼り付け(Pictureとして安定)
    Worksheets("Input").Range("A1").CurrentRegion.Copy
    slide.Shapes.PasteSpecial 2 ' ppPasteJPG=2

    Dim outPdf As String: outPdf = ThisWorkbook.Path & "\slide.pdf"
    pres.SaveAs outPdf, 32 ' ppSaveAsPDF=32
    pres.Close
    ppt.Quit

    AppLeave
    MsgBox "PPT→PDF完了: " & outPdf
    Exit Sub
EH:
    On Error Resume Next
    If Not pres Is Nothing Then pres.Close
    If Not ppt Is Nothing Then ppt.Quit
    AppLeave
    MsgBox "失敗: " & Err.Description, vbExclamation
End Sub
VB

Outlookでメール送信(添付・本文・下書き保存)

' ModOutlookAutomation.bas
Option Explicit

Public Sub Run_SendMail(ByVal toAddr As String, ByVal subject As String, ByVal body As String, Optional ByVal attachPath As String = "")
    On Error GoTo EH
    Dim ol As Object, mail As Object
    Set ol = CreateObject("Outlook.Application")
    Set mail = ol.CreateItem(0) ' olMailItem=0
    With mail
        .To = toAddr
        .Subject = subject
        .Body = body
        If Len(attachPath) > 0 Then .Attachments.Add attachPath
        .Save ' 下書き保存(自動送信は運用に合わせて)
        '.Send ' 自動送信する場合
    End With
    MsgBox "メールを下書き保存しました。"
    Exit Sub
EH:
    MsgBox "失敗: " & Err.Description, vbExclamation
End Sub
VB

重要ポイントの深掘り

Office系はCOMで「正式に制御」できます。終了順序(ドキュメント→アプリ)と非表示(Visible=False)が基本。PDF変換は各アプリのExport/SaveAsを使うと精度が高く、UI操作が不要です。送信は「下書き保存→人が確認→送信」にすると事故が激減します。


プロセス実行:Shell/WScript.Shell/PowerShellで外部コマンドを走らせる

ShellでバッチやEXEを呼び、完了を待つ(最短形)

' ModShellExec.bas
Option Explicit

Public Sub Run_ShellWait(ByVal cmd As String)
    Dim sh As Object: Set sh = CreateObject("WScript.Shell")
    Dim ret As Long
    ret = sh.Run(cmd, 0, True) ' 0=非表示, True=待つ
    If ret <> 0 Then Err.Raise 8001, , "外部コマンドが失敗: " & ret
End Sub

Public Sub Demo_Shell()
    On Error GoTo EH
    AppEnter "Shell"
    Run_ShellWait "cmd /c echo Hello> """ & ThisWorkbook.Path & "\hello.txt"""
    AppLeave
    MsgBox "完了"
    Exit Sub
EH:
    AppLeave
    MsgBox "失敗: " & Err.Description, vbExclamation
End Sub
VB

PowerShellを呼び出して柔軟な処理(JSON整形・API呼び出しなど)

' ModPowerShell.bas
Option Explicit

Public Sub Run_PowerShellScript(ByVal ps1Path As String, ByVal args As String)
    Dim sh As Object: Set sh = CreateObject("WScript.Shell")
    Dim cmd As String
    cmd = "powershell -ExecutionPolicy Bypass -File """ & ps1Path & """ " & args
    Dim ret As Long: ret = sh.Run(cmd, 0, True)
    If ret <> 0 Then Err.Raise 8002, , "PowerShell失敗: " & ret
End Sub
VB

重要ポイントの深掘り

外部コマンドは「戻り値で成否判定」します。Run(…, …, True)で必ず待機し、失敗時はメッセージではなく「コード」で分岐すると安定。PowerShellでJSON/HTTP/APIを扱い、結果をファイルで受け渡すと、VBA側はファイルI/Oだけに集中できます。


UI操作:最終手段のSendKeys/ウィンドウ制御(最小限・安全策)

SendKeysで簡易操作(推奨は最小限)

' ModUiControl.bas
Option Explicit

Public Sub SendKeysToNotepad()
    Dim sh As Object: Set sh = CreateObject("WScript.Shell")
    sh.Run "notepad", 1, False
    Application.Wait Now + TimeValue("0:00:01")
    sh.AppActivate "メモ帳"
    SendKeys "自動入力です。{ENTER}"
End Sub
VB

重要ポイントの深掘り

UI自動化は「フォーカスずれ」で誤操作しやすく、極力避けます。やむを得ない場合は、対象アプリ起動→待機→ウィンドウアクティブ化→最小限のキー送出。必ず待機を入れ、他の操作を挟まない運用にします。継続運用ならUI自動化より「COM/コマンドライン/API」に置き換えるのが王道です。


ブラウザ・Web連携:既定は外部コマンドやAPIで(VBA単体でのWeb操作は非推奨)

既存APIをPowerShellで叩き、結果ファイルで受け渡す

# call_api.ps1
param([string]$url, [string]$outPath)
$resp = Invoke-RestMethod -Uri $url -Method GET
$resp | ConvertTo-Json -Depth 5 | Out-File -FilePath $outPath -Encoding UTF8
' ModWebBridge.bas
Option Explicit

Public Sub Run_CallApi()
    Dim ps1 As String: ps1 = ThisWorkbook.Path & "\call_api.ps1"
    Dim outPath As String: outPath = ThisWorkbook.Path & "\resp.json"
    Run_PowerShellScript ps1, "-url ""https://api.example.com/data"" -outPath """ & outPath & """"
    ' ここでJSONを読み込む処理へ(外部で整形→VBAで集計の分担)
End Sub
VB

重要ポイントの深掘り

VBAでブラウザ操作(旧IE)を模倣するのは現代では非推奨です。Webは認証・JS・CORSなど複雑です。APIをPowerShell/専用ツールで扱い、結果をファイルで受け渡すと、壊れにくく運用品質が上がります。


ファイル・フォルダ操作:FileSystemObjectで外部資産と連携

フォルダ走査・コピー・タイムスタンプ判定

' ModFSO.bas
Option Explicit

Public Sub Run_FolderCopy(ByVal src As String, ByVal dst As String)
    On Error GoTo EH
    Dim fso As Object: Set fso = CreateObject("Scripting.FileSystemObject")
    If Not fso.FolderExists(dst) Then fso.CreateFolder dst

    Dim f As Object
    For Each f In fso.GetFolder(src).Files
        fso.CopyFile f.Path, fso.BuildPath(dst, f.Name), True
    Next
    MsgBox "コピー完了"
    Exit Sub
EH:
    MsgBox "失敗: " & Err.Description, vbExclamation
End Sub

Public Function GetLastModified(ByVal path As String) As Date
    Dim fso As Object: Set fso = CreateObject("Scripting.FileSystemObject")
    If fso.FileExists(path) Then GetLastModified = fso.GetFile(path).DateLastModified
End Function
VB

重要ポイントの深掘り

外部資産(CSV/画像/ZIP)との連携はFileSystemObjectが定番です。存在確認→フォルダ作成→上書き可否を明示し、失敗時は例外で止めると事故が減ります。大容量は「チャンク処理+ログ」に分割すると安定します。


例題の通し方:Word→PDF、PPT→PDF、メール下書き、外部コマンド

動作確認の流れ

  • Run_WordToPdfでPDFが生成されるか確認(出力パスに注意)。
  • Run_PptExportでスライドPDFが生成されるか確認(Inputの表を準備)。
  • Run_SendMailで下書きメールが作成されるか確認(添付任意)。
  • Demo_Shellで外部コマンド完了を待てるか確認(戻り値で成否判定)。

確認ポイント

終了後にアプリが残らないか(Word/PowerPoint/Outlookのプロセス)、出力ファイルが正しく更新されたか、失敗時に後片付けまで到達しているか。実行環境(権限・パス・ウイルス対策ソフト)に依存するため、運用PCでの検証を推奨します。


落とし穴と対策(深掘り)

権限・ポリシーで外部起動がブロックされる

企業環境では実行ポリシーやメール送信が制限されます。IT管理者のルールに合わせ、送信は下書き保存、PowerShellはExecutionPolicy Bypass、実行場所は信頼済みフォルダに。

プロセスが残る・解放漏れ

COMはリークしがち。終了順序(ドキュメント→アプリ)と例外時のQuitを徹底。Shellは待機(Run(…, True))必須。

フォーカスずれ・誤操作

UI自動化は極力避け、API/コマンドに移行。どうしても必要なら、待機・AppActivate・最小限SendKeys、他操作禁止の運用を徹底。

文字コードやロケール差

ファイル入出力はUTF-8に統一。日時・数値の整形は明示的にFormatを使用。海外OSや別ロケールでの実行も見据え、ハードコードされた全角/半角依存を排除。


導入手順と拡張の道筋

最初の一歩

Word/PowerPoint/OutlookのCOMテンプレをそのまま貼り、出力パスだけ自分の環境に合わせる。Shellでバッチを呼び、戻り値で成否判定まで確認。

次の拡張

PowerShellへ橋渡ししてAPIや複雑処理を外出し。ログを追加し、失敗時の再試行やアラートを運用ルールに組み込む。UI自動化は撤退し、API/コマンドへ置き換える。


まとめ:COMとコマンドを使い分け、「待ち・後片付け・契約」を固定する

Excelの外を動かすカギは、COMオートメーションで「正式に制御」、Shell/PowerShellで「コマンドとして確実に実行」、UI自動化は最小限にして「誤操作を防ぐ」。開始・終了枠、完了待ち、後片付け、UTF-8や引数契約の徹底で、初心者でも壊れにくい連携が作れます。

タイトルとURLをコピーしました