64ビットExcel起動時にコンパイルエラー。Private Declare Sub Sleep Lib “kernel32” (ByVal dwMilliseconds As Long)(Excel VBA )

【本日のミッション】

あるExcelファイルを起動したら

コンパイルエラー:
このプロジェクトのコードは、64ビット システムで使用するために更新する必要があります。Declareステートメントの確認および更新を行い、次にDeclareステートメントに、PtrSafe属性を設定してください。」

とエラーが出てしまった。
Excelが正常に動くように解決せよ。

ミッションの概要

今まで正常に使えていたExcelファイルが、ある日特定のパソコンでだけこのエラーが出るようになりました。

64ビットExcel起動時にコンパイルエラー。Private Declare  Sub Sleep Lib “kernel32” (ByVal dwMilliseconds As Long)(Excel VBA )

「コンパイルエラー:
このプロジェクトのコードは、64ビット システムで使用するために更新する必要があります。Declareステートメントの確認および更新を行い、次にDeclareステートメントに、PtrSafe属性を設定してください。」

ExcelのVBAの画面で、下記コードのところでエラーが出ているみたい・・・

Private Declare  Sub Sleep Lib “kernel32” (ByVal dwMilliseconds As Long)

とか

Private Declare  Sub Sleep Lib “kernel32” (ByVal ms As Long)

とか

Declare Function SetCurrentDirectory Lib “kernel32” Alias _
        “SetCurrentDirectoryA” (ByVal CurrentDir As String) As Long

とか・・・

Declare Function PathFileExists Lib “shlwapi” Alias _
        “PathFileExistsA” (ByVal lpszPath As String) As Double

この原因を解決し、Excelがきちんと立ち上がるようにするのが今回のミッションです。

「コンパイルエラー」エラーの原因 Excel 「64ビット版」とは

エラーの原因は、そのパソコンにインストールされていたMicrosoft Excel が

64ビット版

だった、ということです。

Microsoft OfficeはVersion2010から、「32ビット版」と「64ビット版」をリリースしています。

「64ビット版」では、「32ビット版」に比べて使用できるメモリ容量が大きくなり、2GBを超えるビッグデータを扱えるようになりました。

VBAの方も、VBA7 (Microsoft Visual Basic for Applications 7.0) にバージョンアップされています。

「64ビット版」では Declare ステートメントに PtrSafe 属性がないとコンパイル時にエラーが発生します。これが今回のエラーの原因です。

Excelのバージョン「32ビット版」か「64ビット版」か確認する方法

Excelにインストールされているのが、「32ビット版」か「64ビット版」かを確認する方法は下記の通りです。

  1. [ファイル]ー[アカウント]-「Excelのバージョン情報」をクリックします。
    64ビットExcel起動時にコンパイルエラー。Private Declare  Sub Sleep Lib “kernel32” (ByVal dwMilliseconds As Long)(Excel VBA ) 64ビットExcel起動時にコンパイルエラー。Private Declare  Sub Sleep Lib “kernel32” (ByVal dwMilliseconds As Long)(Excel VBA )
  2. Microsoft Excel のバージョン情報にあるビット数を確認します。
    下記の場合は、「64ビット」がインストールされています。
    64ビットExcel起動時にコンパイルエラー。Private Declare  Sub Sleep Lib “kernel32” (ByVal dwMilliseconds As Long)(Excel VBA )
■■■スポンサーリンク■■■

「コンパイルエラー」エラーを回避する方法

では、実際にどのようにしてこのエラーがでないようにしたらよいのでしょうか。

下記APIの、Declareステートメントを例にご説明いたします。

Private Declare Sub Sleep Lib “kernel32” (ByVal dwMilliseconds As Long)

エラー回避の方法は、Declare」の後ろに「PtrSafe」を付けます。

Private Declare PtrSafe Sub Sleep Lib “kernel32” (ByVal dwMilliseconds As Long)

もし、マクロを実行する環境が「64ビット版」「32ビット版」どちらもありうる場合は、条件分岐にします。

#If VBA7 Then 
    Private Declare PtrSafe Sub Sleep Lib “kernel32” (ByVal dwMilliseconds As Long)
#Else
    Private Declare Sub Sleep Lib “kernel32” (ByVal dwMilliseconds As Long)
#End If

他のAIPの修正例は下記の通りです。
Declare」の後ろに「PtrSafe」を付けるだけ。一括置換をすると簡単ですよ。

#If VBA7 Then 
    Declare PtrSafe Function PathFileExists Lib “shlwapi” Alias _
        “PathFileExistsA” (ByVal lpszPath As String) As Double
#Else  
    Declare Function PathFileExists Lib “shlwapi” Alias _ 
        “PathFileExistsA” (ByVal lpszPath As String) As Double
#End If

とか・・・

#If VBA7 Then
    Declare PtrSafe Function SetCurrentDirectory Lib "kernel32" Alias _
          "SetCurrentDirectoryA" (ByVal CurrentDir As String) As Long
#Else
    Declare Function SetCurrentDirectory Lib "kernel32" Alias _
          "SetCurrentDirectoryA" (ByVal CurrentDir As String) As Long
#End If

とか・・・

#If VBA7 Then 
    Private Declare PtrSafe Sub Sleep Lib “kernel32” (ByVal ms As Long)
#Else
    Private Declare Sub Sleep Lib “kernel32” (ByVal ms As Long)
#End If

になります。

今まで使えたマクロが急に使えなくなるなんて、心臓止まりますよね・・・。

【参考】

指定したフォルダ内のファイル名全てを取得(Excel VBA)
変数でよく使われる「buf」「tmp」の意味
Dir関数が取得するファイルの順番
指定したフォルダ内のフォルダ名全てをGetAttrを使って「エラー53 ファイルが見つかりません。」を出さずに取得(Excel VBA)
GetAttrとは?「= vbDirectory」ではなく「And vbDirectory」となるビット演算の疑問
フォルダ名だけを取得したい時に出てくる 「.」 と 「..」 とは?
指定したフォルダ内とサブフォルダ内全てのファイル名を取得(Excel VBA)
CreateObject(“Scripting.FileSystemObject”) を使ってサブフォルダを取得
再帰処理とは?フォルダ内とサブフォルダ内全てのファイル名を取得(Excel VBA)
指定したフォルダ内のサブフォルダのフォルダ名を全部取得(Excel VBA)
再帰処理とは?フォルダ内のサブフォルダのフォルダ名を全部取得(Excel VBA)
参照渡し「ByRef」と値渡し「ByVal」の違い(Excel VBA)
ファイルのフルパスからファイル名のみを取得 InStrRev関数(Excel VBA)
指定したフォルダの全ての階層のフォルダ名・サブフォルダ名・ファイル名を取得(Excel VBA)
FileSystemObjectとは?CreateObject 関数 FolderExists・GetFolderの使い方
FileSystemObject CreateObject関数を使う方法・ 参照設定を使う方法 違いを理解してエラー防止
再帰処理とは?指定したフォルダの全ての階層のフォルダ名・サブフォルダ名・ファイル名を取得(Excel VBA)
ファイルのフルパスからファイル名のみを取得 Split関数(Excel VBA)
Callステートメントとは 引数 括弧()の使い方(Excel VBA)
指定したフォルダ内から「特定の文字を含まないファイル名」を取得(Excel VBA)
ワイルドカードとは。使い方いろいろ。(Excel)
Dir関数の使い方。ファイル名やフォルダ名の取得方法。(Excel VBA)
指定したフォルダのファイル名を取得し、そのファイル名を一括で変換(Excel VBA)
Excel起動時に「コンパイルエラー」。64ビット システムで Declareステートメントに、PtrSafe属性を設定(Excel VBA )
「ファイルを開く」ダイアログボックス から ファイル名を取得(Excel VBA)
「ファイルを開く」ダイアログボックス から 複数 ファイル名を取得(Excel VBA)
指定フォルダ内のサブフォルダ全てをフォルダ構成のみ(空フォルダ)を別フォルダにコピー(Excel VBA)
再帰処理とは?指定フォルダ内のサブフォルダ全てをフォルダ構成のみ(空フォルダ)を別フォルダにコピー(Excel VBA)
エクセル Dir関数 を使ってファイルの存在(有無)を確認する(Excel VBA)
エクセル FileSystemObject を使ってファイルの存在(有無)をチェックする(Excel VBA)
Excel Dir関数 存在しないファイル・フォルダが「存在している」と判定される理由(Excel VBA)
64ビットExcel起動時にコンパイルエラー。Private Declare Sub Sleep Lib “kernel32” (ByVal dwMilliseconds As Long)(Excel VBA )

■■■スポンサーリンク■■■