【VBA機能拡張】ExcelVBAでWindows APIを呼び出す方法まとめ

VBAでの開発において、標準の機能だけでは解決できない課題に直面することは珍しくありません。そんなときに頼りになるのがWindowsAPIです。WindowsAPIを使うことで、VBAでWindowsの機能を直接活用し、より柔軟でパワフルなアプリケーションを作ることができます。

本ページでは、VBA開発者のためにWindowsAPIの利用方法をわかりやすく解説しています。基本的な概念から始めて、API関数の呼び出し方、引数の設定、戻り値の取得方法などを具体的なコード例を交えて説明します。Windows APIはメモリやポインタ、ハンドルというようなC++寄りの考えが出てくるためVBAだけを触っていた人からすると少しだけ難しい内容となっています。

ただし、その分できることの範囲も大きく広がるのでぜひ理解を深めてみて下さい。

 icon-warning 注意事項 

基本的にサンプルコードは64bit環境向けのコードとなっています。
Excel VBAと謳っていますがVBAであればどのアプリケーションでも同様の方法で利用可能です。

 

Windows APIとは

Windows APIとは簡単にいえばWindowsに用意されている機能がまとまっているセットのようなもので、VBAからそれらを呼び出すことでWindowsに用意されている様々な機能を使用することができます。これら機能はほとんどの場合、VBAだけでは実現できないものばかりです。

たとえば下画像のように画面上のピクセルのRGB値を取得するようなツールも作成が可能です。
これだけのツールでもVBAだけでは実現できない機能がふんだんに盛り込まれています。

 
Windows APIの実態はDLLファイルというアプリケーション拡張ファイルです。
このDLLファイルの中身には様々な種類の関数がいくつもつまっています。

Windows APIと呼ばれる機能を持つDLLファイルは [C:\Windows\System32]フォルダに格納されています。このディレクトリにはWindowsのOSの稼働に直結するような重要なシステム関連のプログラムファイルがいくつも存在しています。このディレクトリ内にあるDLLファイルの関数をVBAで呼び出すことで、通常VBAでは行うことのできない様々な処理を行うことができるようになります。

VBAでは特定の”おまじない”を書くことで、参照設定等は行わずにいつでも簡単にWindowAPIを呼び出すことができます。以降ではWindowAPIの基本的な使い方をはじめ、いくつもの関数の使い方やそれらを連携させたサンプルコードなどを解説していきます。

ちなみに名前からわかると思いますが、Windows APIではWindowsの機能を呼び出しているだけので基本的にはWindows以外のOSでは使用することはできません。([C:\Windows\System32]フォルダに該当のDLLファイルが存在している必要があるということ)

  Windows APIの呼び出し 

Windows APIはDLLファイル内の関数を呼び出しているわけなのですが、VBAでDLLファイル内の関数を呼び出すには下記のような定型文を書いておく必要があります。プログラマー界隈では聞き馴染みのある”おまじない”というやつです。この定型文はモジュールの上部に記載します。

icon-code  API呼び出し(戻り値なし) 

Declare PtrSafe Sub 関数名 Lib “DLL名” (引数

icon-code  API呼び出し(戻り値あり) 

Declare PtrSafe Function 関数名 Lib “DLL名” (引数) As 戻り値の型

基本的には上記の関数名, DLL名, 引数, 戻り値の型の部分をAPI関数の内容にあわせて書き換えるだけで、VBAのコード内でその関数を使用することが可能となります。

実際のAPI関数を例にみると下記のように記載します。

【64bit 戻り値なしの場合】
 Declare PtrSafe Sub Sleep Lib “kernel32” (ByVal dwMilliseconds As Long)
【32bit 戻り値ありの場合】
 Declare Function GetCursorPos Lib “User32” (lpPoint As POINTAPI) As Long
 

開発(実行)環境が64bitの場合は「Declare」の後ろに「PtrSafe」を記載する必要があります。これが無いとコンパイルエラーとなりマクロを実行することもできません。もうあまりありませんが環境が32bitの場合は記載不要です。(参考:PtrSafe キーワード (VBA) – Microsoft Learn)

また「Declare PtrSafe ~」の後ろにはVBAのプロシージャと同じく戻り値のありなしで「Sub」と「Function」を書き替える必要があるので注意しましょう。

ちなみに「Declare」の前に「Private」「Public」を記載することでVBAの変数や関数と同じようにスコープ範囲を変更することも可能です。API関数の使用範囲に合わせて任意で設定しておきましょう。

基本的にWindowsAPIの関数宣言は決まり切った文言であるためコピペが基本になります。
WindowsAPIの各関数の宣言の文言は『Win32API_PtrSafe.TXT』にまとまっています。
上記リンク先で使用したい関数名で検索すれば64bitで使うときの宣言文を見つけることができます。

上記ファイルはMicrosoft公式「Office 2010 Help Files: Win32API_PtrSafe with 64-bit Support」よりダウンロードできるインストーラーを実行することで手に入れることが可能です。

Windows API一覧

ここではVBAで呼び出すことでよりマクロの幅が広がるようなWindowsAPIを抜粋して紹介します。
※[現在更新中]ページでき次第、順次リンクを追加していきます。

ウィンドウ関連関数

FindWindow関数:キャプション名とクラス名から特定のウィンドウハンドルを取得する
FindWindowEx関数:キャプション名とクラス名から特定の子ウィンドウハンドルを取得する
GetWindowText関数:指定のウィンドウのキャプション名を取得する
GetClassName関数:指定のウィンドウのクラス名を取得する
SetWindowText関数:指定のウィンドウのキャプション名を任意の文字列に変更する
GetWindowLongPtr関数:指定のウィンドウの情報(ウィンドウスタイル等)を取得する
SetWindowLongPtr関数:指定のウィンドウの情報(ウィンドウスタイル等)をセットする
SetLayeredWindowAttributes関数
SetForegroundWindow関数:指定のウィンドウを最前面に表示する
GetActiveWindow関数:アクティブウィンドウのウィンドウハンドルを取得する
GetNextWindow関数
GetParent関数:指定のウィンドウの親(もしくは所有者)のウィンドウハンドルを取得する
FlashWindowEx関数:指定のウィンドウ(&タスクバー)を点滅させる
CloseWindow関数:指定のウィンドウを最小化する
 

デバイスコンテキスト(DC)関連関数

GetDC関数:指定ウィンドウの非クライアント領域のDCへのハンドルを取得する
GetWindowDC関数:指定ウィンドウのDCへのハンドルを取得する
ReleaseDC関数:デバイスコンテキスト(DC)を解放する
GetPixcel関数:指定のスクリーン座標のピクセルのRGB値を取得する
ClientToScreen関数:クライアント領域座標をスクリーン座標に変換する
ScreenToClient関数:スクリーン座標をクライアント領域座標に変換する
GetDeviceCaps関数:デバイスコンテキスト情報を取得する
CreateCompatibleDC関数
DeleteDC関数
SelectObject関数
DeleteObject関数
 

マウスカーソル関連関数

SetCursorPos関数:カーソル位置を指定の座標に移動する
GetCursorPos関数 :現在のカーソル位置の座標を取得する
 

BMP/DIB関連関数

GetDIBits関数
SetDIBits関数
CreateCompatibleBitmap関数
CreateDIBSection関数
BitBlt関数
LoadImage関数
 

サウンド操作系API関数

Beep関数:指定周波数のビープ音(警告音)

midiOutGetNumDevs関数 
midiOutOpen関数
midiOutShortMsg関数
midiOutClose関数 
mciSendString関数:指定の音楽ファイルを再生/停止する
 

クリップボード関連

OpenClipboard関数
EmptyClipboard関数
CloseClipboard関数
GetClipboardData関数
SetClipboardData関数
IsClipboardFormatAvailable関数

 

VBA × Windows API サンプルコード (工事中)

※[現在更新中]ページでき次第、順次リンクを追加していきます。

クリップボード操作関連

クリップボード内のテキストデータ(文字列)を取得する
クリップボード内にテキストデータ(文字列)をセットする

VBAでクリップボードにビットマップ画像をセットする

 

ウィンドウ操作関連

VBAでウィンドウ名(キャプション)をまとめて取得する

VBAで指定のウィンドウを最前面に表示する
VBAで指定のウィンドウを常に最前面に表示する
VBAのユーザーフォーム(UserForm)サイズを可変化させる

VBAでウィンドウ(UserForm)を透明/半透明にする

UserFormに回転させたテキスト(文字列)を描画する

VBAで指定のウィンドウ(UserForm)に図形を描画する

 

その他 

VBAで使用可能なフォント名をすべて列挙する

VBAとWindows APIでMIDI操作

midiOutGetNumDevs関数
midiOutOpen関数
midiOutShortMsg関数
midiOutClose関数

VBAでマウスを操作(カーソル移動/クリック)する

SetCursorPos関数
GetCursorPos関数 
mouse_event関数

VBAで指定した秒数だけ処理を止める方法【Sleep関数(API)】
VBAで押されたキーボードを取得する方法【GetAsyncKeyState関数(API)】
VBAで音楽ファイル(.mp3/.wav)を再生する方法【mciSendString関数(API)】
VBAでインターネット上の画像ファイルをダウンロードする方法【URLDownloadToFile関数(API)】
VBAでビープ音(警告音)を鳴らす方法【Beep関数(API)】

 

Windows APIの応用

Windows APIはWindowsの標準システムとして用意されているDLLファイルにアクセスすることでその中にある関数をVBAで呼び出しているだけです。

そして、このDLLファイルというものはVisual StudioとC++言語を使って自作することができます。つまりは、Windows APIに無くVBAでも実現できないような関数を作り上げ自作DLL経由でVBAで使用することも可能という訳です。

たとえばC++のOpenCVライブラリを使ったDLLを作成すれば、文字認識や顔認識をはじめとした画像処理全般の処理をVBAで簡単に行うことができるようになります。

C++やVisual Studioなどを利用するため、VBAのみで開発している人にとっては少しレベルが上がった内容となっていますが、下記ページではそういった方向けにVBAで自作DLL関数を呼び出す方法の基本を紹介しているので興味のある方はぜひ合わせて読んでみて下さい。

 

2024年3月10日Excel, VBA, Windows API

Posted by Lic