AccScan
技術

Access VBAが64bit版Officeで動かない原因と修正手順

PC入れ替えで64bit版Officeになると、Windows APIのDeclare文にPtrSafe追加とLongPtr型への変更が必須です。通常のVBAコードは修正不要。mscomctl.ocxはM365バージョン1707で64bit対応済みなど、影響範囲と修正手順を解説します。

まずは、自社のAccessが「解析できるか」を無料で確認できます。

約2分・ファイル送信不要・発注義務なし

結論:32bit前提のDeclare文は64bit版Officeで動かない

PC入れ替えのタイミングで意図せず64bit版のOfficeがインストールされ、Accessを開いたらVBAがコンパイルエラーで止まった。当社への相談で多いパターンです。原因の筆頭は、Windows APIを呼び出すDeclare文(Windows API宣言)が32bit前提のままになっていることです。

MicrosoftのVBA公式ドキュメントによると、Office 2019とMicrosoft 365以降は64bit版が既定でインストールされます。Office 2010より前(VBA6以前)のコードで書かれたDeclare文は32bit前提で、そのままでは64bit版Officeでエラーになります。

一方、Declare文を使っていない通常のVBAコード(テーブル操作・フォーム制御・SQL実行など)は、原則として変更なく動きます。「64bitになるとVBAが全部書き直しになる」という心配は過剰です。影響を受けるのは主に、Windows APIを直接呼ぶDeclare文と、一部のActiveXコントロールです。ただし、32bit版でコンパイルされたMDE/ACCDE形式のファイルは64bit版Officeでは実行できない点も注意が必要です。

まず確認:今のOfficeは32bitか64bitか

Accessを開き、「ファイル」→「アカウント」→「Accessのバージョン情報」を選ぶと、バージョン番号の後ろに「32ビット」または「64ビット」と表示されます。64bitと出たら、VBAコードにDeclare文があるかどうかを確認してください。

VBE(VBAの編集画面)で確認する方法は、Alt+F11でVBEを開き、「編集」→「検索」で「Declare」を検索するだけです。ヒットした行が点検対象です。Declareが見つからなくても、ActiveXコントロールの問題、MDE/ACCDE形式のファイルが32bit環境でコンパイルされている問題、参照ライブラリの64bit非対応なども確認対象です。

Declare文の書き直し:PtrSafe・LongPtr・LongLongの使い分け

64bit版VBAで32bit前提のDeclare文を動かすには、主に3つの修正が必要です。

修正内容対象具体例
PtrSafeキーワードを追加すべてのDeclare文Declare PtrSafe Function ...
ポインター・ハンドルをLongPtrに変更ウィンドウハンドル(hWnd)、メモリアドレスなどを受け取る引数・戻り値As LongAs LongPtr
64bit整数が必要な場合はLongLong64bitの整数値そのものを扱う場合(ファイルサイズなど)。64bit版Officeのみで有効。32bitとの両対応コードではWin64条件分岐が必要As LongLong

Declare文で変えるのはポインターやハンドルを受け渡す引数・戻り値です。カウンタやフラグ値など通常の32bit整数はそのままで構いません。ただし正確にはWindows APIの型定義(WPARAM・LPARAMなどポインター幅で変化する型)を確認するのが確実で、変数名だけで判断しないほうが安全です。なお、Declare文の引数に対応する呼び出し側の変数(UDTメンバーを含む)も同様にLongPtrへの変更が必要な場合があります。PtrSafeを追加するだけでは「64bitを対象にする」と宣言しただけで、引数の型が32bitのままなら動作が不正になります。Declare文を修正したら、呼び出し側の変数宣言も一緒に点検してください。

実際によく出てくる例を挙げます。ウィンドウハンドルを取得する関数の宣言は次のように変わります。

修正前(32bit前提)修正後(64bit対応)
Declare Function GetActiveWindow Lib "user32" () As LongDeclare PtrSafe Function GetActiveWindow Lib "user32" () As LongPtr

公式ドキュメントにあるとおり、LongPtrは32bit版Office(VBA7以降)ではLongとして動き、64bit版ではLongLongとして動くエイリアスです。つまりVBA7対応のDeclare文でLongPtrを使えば、32bitと64bitの両方で同じコードが動きます。32bitと64bitの両方で動かしたい場合、条件分岐(VBA7より古い環境も含めてカバーする必要があるなら)は次のようにも書けます。

#If VBA7 Then
    Declare PtrSafe Function GetActiveWindow Lib "user32" () As LongPtr
#Else
    Declare Function GetActiveWindow Lib "user32" () As Long
#End If

VBA7 はOffice 2010以降で真になる条件定数です。Office 2007以前(VBA6)はLongPtrを認識しないため、この分岐でカバーします。当社の移行案件でも、この条件分岐に書き換えるだけで新旧環境を共存できたケースが多いです。

32bit専用ActiveXコントロールの問題

Declare文と並んで問題になるのが、古いActiveXコントロールです。Microsoftの互換性情報によると、VB6世代(Visual Basic 6.0時代)に作られた32bit専用のコントロールは64bitプロセスには読み込めません(Event ID 10000/10001)。

ただし、AccessでよくつかうTreeView・ListView・ProgressBarが含まれるmscomctl.ocxについては例外があります。Microsoft 365のバージョン1707(2017年7月)のリリースノートに「Add 64-bit support for mscomctl.ocx」と明記されており、Microsoft 365を最新に更新すればmscomctl.ocxの64bit版が利用可能になります。PCを入れ替えてOfficeの更新が滞っていた場合は、まず更新と参照設定の確認を試してください。

カレンダーコントロール(Mscal.ocx)はOffice 2013以降提供されていません。新しいPCには部品の実体がないので、32bitのままにしても復活しません。ActiveXコントロールの詳しい切り分け手順はこちらでまとめています。

サードパーティ製の32bit専用部品への対応

外部ベンダーが提供した32bit専用のActiveXコントロール(印刷コンポーネント、帳票コントロール、グラフ部品など)は、ベンダーが64bit版を出していない限り動きません。この場合の選択肢は2つです。

  • ベンダーが64bit版を提供しているか確認し、あれば差し替える。
  • 64bit版が存在しない場合は、32bit版のOfficeを選択する。Microsoftの案内にも「32bitコントロールに64bit代替がない場合は32bit版Officeを使う」と明記されています。

32bit版Officeに戻す選択肢は時間稼ぎとして有効ですが、次のPC入れ替えでまた同じ問題が出ます。コントロールの棚卸しをして、依存している部品の64bit対応状況を先に調べておくと、計画が立てやすくなります。

点検の全体像はAccess延命チェックリスト10項目でまとめています。参照設定の確認とActiveXコントロールの一覧化は、PC入れ替え前に済ませておくと事前に手が打てます。

事前点検と移行の進め方

64bit化で影響を受ける可能性があるのは、VBEで「Declare」がヒットするファイル、MDE/ACCDE形式のファイル、32bit専用部品を使っているファイルです。PC入れ替え前に次の順で確認しておくと、切り替え後の混乱を防げます。

  1. VBEでDeclare文を検索し、ヒットした行を書き出す。
  2. 引数・戻り値がウィンドウハンドルやメモリポインターかどうかを確認する。該当するものはLongPtrに変更し、PtrSafeを追加する。呼び出し側の変数宣言も忘れずに確認する。
  3. VBEの「ツール」→「参照設定」で参照しているコントロール一覧を確認し、サードパーティ製のものを書き出す。
  4. フォームのデザインビューでActiveXコントロールの種類を確認する(右クリック→「ActiveXコントロールのプロパティ」)。
  5. MDE/ACCDE形式のファイルがあれば、32bit環境でのコンパイル済みかどうかを確認する。64bitへの再コンパイルには、MDEなら元のMDB、ACCDEなら元のACCDBが必要です。
  6. テスト環境(同じビット数のOffice)でDeclare文修正後の動作を確認する。

「作成者が退職済みで、どこでDeclare文やActiveXを使っているか誰にも分からない」という場合は、解析から始める必要があります。無料の解析可否チェックで、まず手をつけられる状態かどうかだけ確かめられます。

よくある質問

Q. PtrSafeを追加しただけでエラーが消えましたが、これで完成ですか。

コンパイルエラーは消えますが、それだけでは不十分なことがあります。公式ドキュメントにあるとおり、PtrSafeはDeclare文が64bitを対象にしていると宣言するだけで、引数や戻り値の型まで自動で変えてくれるわけではありません。Declare文でポインターを受け取る戻り値がAs Longのままなら、64bit環境では64bitのアドレスが32bitに収まらず動作が不正になります(公式ドキュメントでは「truncates the 64-bit quantity」と説明)。エラーなく動いているように見えても実行結果がおかしい場合は、ポインター関係のLongをLongPtrに変えたか、呼び出し側の変数宣言も含めて確認してください。

Q. 通常のVBAコード(テーブル操作・クエリ実行など)も書き直しが必要ですか。

Declare文を使っていない通常のVBAコードは、原則として修正不要です。AccessのオブジェクトモデルはDoCmd、Recordset、Queryなど32bitと64bitで互換性があります。64bit移行で影響を受けるのはDeclare文と一部のActiveXコントロールが中心なので、まずVBEで「Declare」の検索から始めるのが効率的です。

Q. 32bitに戻せますか。Microsoft 365でも選べますか。

可能です。Microsoft 365はインストール時に32bit版を選べます。インストール後に変更する場合は一度アンインストールし、32bit版を選んで再インストールします。ただし、32bit版を選ぶ理由として「32bitコントロールに64bit代替がない」場合が公式に挙げられており、一時的な回避策として機能します。根本的な対応は部品の置き換えか、64bit対応版への更新です。

Q. Office更新が原因でAccess VBAが突然動かなくなることもありますか。

ビット数変更が原因でないVBAの不具合は、月例のOffice更新で起きることもあります。Office更新後にAccessが動かなくなった場合の対処でロールバック手順などを解説しています。

触れないAccessが「診断できるか」だけ、確かめませんか。

顧客データは送信不要。発注の義務もありません。

約2分・ファイル送信不要・発注義務なし/説明はオンライン・売り込みはしません