読者です 読者をやめる 読者になる 読者になる

Excel 職人のつぶやき

エクセルをデータベース管理ツールとして活用するための、情報、技術などを発信していくサイトです。

64ビット環境で、VBA、Declare Function で発生するエラー

Excel / Access の VBAでDeclare Functionを使っていると、Officeが64bitアプリケーションとしてインストールされている場合は、ファイルをオープンまたはVBAを実行するとエラーが発生します。

 

「Declare ステートメントが PtrSafe を指定しない場合、Declare ステートメントはWin32 プラットホーム上でのみコンパイルします。」

f:id:muramoto1041:20150227113925p:plain

 

Microsoft Officeをインストールすると既定値では32bitアプリケーションとしてインストールされるのですが、ついついOSが64bitだとアプリケーションも64bitでインストールしてしまうのです。Microsoft OfficeのVBAは、完全に32bitと64bitで完全互換ではなく、64bitアプリケーションだと制限が発生します。

 

f:id:muramoto1041:20150302132340j:plain

このエラーは、OSが64ビットの場合でのみ発生するエラーです。

OSが、64ビットの場合でも Office が 32ビットアプリケーションとしてインストールされている場合は、発生しません。

 

32ビット か 64ビットアプリケーションかを 確認するには?

エクセル または ワードのバージョン情報を表示して、下記の表示を確認して下さい。

32ビットであれば、エラーは発生しません。64ビットの場合は、一旦Officeをアンインストールして32ビットで再インストールすると、エラーを回避することが出来ます。

f:id:muramoto1041:20160414192014p:plain

 

64bit版と32bit版のどちらをインストールした方がよいのかをしわしく知りたい方は、下記のMicrosoft Officeのサポートページを参照してください。制限事項とメリットについて説明しています。


Microsoft Office の 32 ビット版と 64 ビット版を選択する

 

Declare Function のエラー回避方法

64ビットアプリケーションとしてインストールした環境でエラーを回避するには、下記のように行ってください。

 

Office2010以降のようですが、条件付きコンパイル定数が使えるようになりました。

VBA7とWin64です。

VBA 7 は旧バージョンの VBA に代わる新しいコード ベースです。VBA 7 は Office 2010 の 32 ビット バージョンと 64 ビット バージョンの両方で使用できます。VBA7 と Win64 という 2 つの条件付きコンパイル定数が用意されています。VBA7 定数を使用すると、アプリケーションで VBA 7 と旧バージョンの VBA のどちらを使用しているのかをテストすることによって、コードの下位互換性を確保できます。Win64 定数は、コードが 32 ビットとして実行されるのか、64 ビットとして実行されるのかをテストするために使用します。これらのコンパイル定数の両方について、この記事で後ほど使用例を示します。

 

 

#If VBA7 And Win64 Then

  '64bit版 Private Declare PtrSafe Function GetWindowRect Lib "user32" (ByVal hWnd As LongPtr, lpRect As RECT) As Long

#Else

  '32bit版 Private Declare Function GetWindowRect Lib "user32" (ByVal hWnd As Long, lpRect As RECT) As Long

#End If 

 

このようにして、64bit版と32bit版の処理を分割することで回避することができます。

 

SetTimer のエラー回避方法

SetTimer LibのAddressOf TimerProc変数で、発生するエラーには下記の原因がありました。

 

64Bit 版では、ポインターやハンドルのサイズが 32Bit 版に比べて大きくなったため、Long 型を使用すると予期しないエラーが発生する可能性があります。
そのため、Office 2010 以降ではその問題に対応した新しいデータ型として、
LongPtr 型(ポインターデータ型)と LongLong型(64Bit 数値型)が追加されています。
※型変換するための CLngPtr() や CLngLng() も追加されています。

 

単純に64biに対応はできません。 

 

Declare PtrSafe Function SetTimer Lib "user32" (ByVal hwnd As Long, _


ByVal nIDEvent As Long, _
ByVal uElapse As Long, _
ByVal lpTimerFunc As LongPtr) As Long


Declare PtrSafe Function KillTimer Lib "user32" (ByVal hwnd As Long, _

ByVal nDEvent As Long) As Long

つまり、32bitの Long を 64bitでは LongPtr に変更する必要があります。

 

64bit アプリケーションには制限があります

32bit での限界を感じていないのなら、Office アプリケーションは、32bitモードでのインストールをお勧めします。

 

f:id:muramoto1041:20150302082216j:plain

 

古いOfficeをお使いの方は、最新版へのバージョンアップをお勧めします。

最新版の Office を利用するだけで、業務効率が上がります。

excel-databace.hatenablog.com

 

 

Excelでのプログラム開発は、有限会社タイムへご用命ください。


システム開発|クラウド|Office365|有限会社タイム(福岡市)