はじめに
Excel 2010以降、Officeには32bit版と64bit版が存在します。VBAのコード、特にWindows API関数を呼び出す Declare
ステートメントは、このbit数の違いによって書き方を変える必要があります。もし対応しないコードを書くと、他の人の環境でマクロがエラーになってしまう可能性があります。
VBAの「条件付きコンパイル」には、ユーザーの環境を自動で判別するための、あらかじめ定義された特別な定数が用意されています。
Vba7
: VBAのバージョン7以降(Excel 2010以降)であるかWin64
: 実行中のOfficeが64bit版であるか
この記事では、これらの定数を使って、32bit版と64bit版のExcel双方で正しく動作する、互換性の高いマクロを作成する方法を解説します。
Vba7
と Win64
を使った互換性対応コード
Windows API関数を呼び出す際、VBA7 (Excel 2010) 以降の64bit版Officeでは、Declare
ステートメントに PtrSafe
というキーワードを追加する必要があります。
以下のサンプルコードは、Vba7
を使って Declare
ステートメントを切り替え、Win64
を使って現在の実行環境をイミディエイトウィンドウに出力します。
完成コード
'--- 1. Vba7でAPI関数の宣言を切り替える ---
' Vba7 = Excel 2010 以降のVBA
#If Vba7 Then
' 64bit版も考慮し、PtrSafeを付けて宣言
Declare PtrSafe Function GetTickCount Lib "kernel32" () As Long
#Else
' Excel 2007 以前の古いVBA用の宣言
Declare Function GetTickCount Lib "kernel32" () As Long
#End If
' 実行環境をチェックし、API関数を呼び出す
Sub CheckEnvironmentAndRunAPI()
'--- 2. Win64で実行中のOfficeのbit数を判定 ---
#If Win64 Then
' 64bit版のOfficeで実行されている場合の処理
Debug.Print "このExcelは64bit版です。"
#Else
' 32bit版のOfficeで実行されている場合の処理
Debug.Print "このExcelは32bit版です。"
#End If
'--- 3. API関数を呼び出す ---
' GetTickCountは、PCが起動してからの経過時間をミリ秒単位で返す関数
Debug.Print "PC起動からの経過時間: " & GetTickCount() & " ミリ秒"
End Sub
コードの解説
1. Vba7
条件付きコンパイル定数
#If Vba7 Then
: この条件式は、コードを実行しているVBAのバージョンが7以降(Excel 2010以降)の場合にTrue
となります。PtrSafe
: 64bit環境でAPI関数を安全に呼び出すために必要なキーワードです。VBA7より前のバージョンではPtrSafe
は認識されないため、この#If
ブロックで古い環境ではPtrSafe
が含まれないDeclare
ステートメントがコンパイルされるように分岐させています。- これにより、古いExcelでも新しいExcelでも、このファイルを開いた際に構文エラーが発生するのを防ぎます。
2. Win64
条件付きコンパイル定数
#If Win64 Then
: この条件式は、マクロが64bit版のOfficeで実行されている場合にTrue
となります。32bit版の場合はFalse
です。- これを使えば、bit数に依存するデータ型(
LongPtr
など)の扱いを分けたり、ユーザーに現在の環境を通知したりといった、より細かい制御が可能になります。
まとめ
今回は、条件付きコンパイル定数 Vba7
と Win64
を使って、異なるExcel環境に対応できる互換性の高いマクロを作成する方法を解説しました。
#If Vba7 Then
: VBAのバージョン(主にExcel 2007以前か、2010以降か)で処理を分岐させる。API宣言のPtrSafe
の有無を切り替えるのに必須。#If Win64 Then
: Officeのbit数(32bitか64bitか)で処理を分岐させる。
特に、Windows API関数を利用するマクロを作成し、それを他の人に配布する可能性がある場合は、このテクニックを使って、様々な環境でエラーが出ないように配慮することが非常に重要です。