【対処方法】このプロジェクトのコードは、64ビットシステムで…【Declare,PrtSafe】

スポンサーリンク
アイキャッチ 猫Access
スポンサーリンク

今回はパソコンの入れ替え後等にVBAマクロ付きのExcelやAccessファイルを使用した際、
「このプロジェクトのコードは、64ビットシステムで使用するために更新する必要があります。
Declareステートメントの確認および更新を行い、
次にDeclareステートメントにPrtSafe 属性を設定してください。」

とエラーコードがでてしまった場合の対処方法を紹介します。

エラー

スポンサーリンク

エラーの原因は?どんな状況で発生する?

Office64bitで、
Win32API(32bitのWindows API)を呼び出す
と該当のエラーメッセージがでます。
64bitと32bitでは使用できる領域が異なるため、
通常そのまま使うと何かしら問題が発生する場合があります。
よって「使っても良いか」確認の意味も込めたエラーメッセージとなります。

例えば、パソコンの入れ替えやOfficeのバージョンアップで、
Officeが32bitから64bitに変わった際
に発生します。

スポンサーリンク

対処方法

対処方法は以下になります。

  • Declare文の変更(※1)
    ①PtrSafeを追加
    ②Long型を適宜PtrLong型に変更
  • API実行箇所をDeclare文の型に合わせる(引数・戻り値) 

※1 Office64bitでのDeclare文の記述方法は、
以下のとおりMicrosoft公式より公開されていますので、 コピーして使用します。

Microsoft Docs:Win32API_PtrSafe より、
Office 2010 ヘルプファイル:64 ビットのサポートが含まれる Win32API_PtrSafe
へのリンクにとび、
「Office2010Win32API_PtrSafe.exe」をダウンロード・インストール。
インストールすると、
「C:\Office 2010 Developer Resources\Documents\Office2010Win32API_PtrSafe」 に、
Win32API_PtrSafe.TXTが出来上がるので、こちらを開き、該当箇所をコピペする。

なお、Office2010より64bitが新しくできたためOffice2010となっていますが、
他バージョンでも同じように上記のURLからダウンロードします。

スポンサーリンク

コード変更例

例えば、以下のようなコードを記述しているとして、どのように修正するか説明します。
コード内容としては、”user32”というWin32APIを使用し、
アクティブウィンドウの名前を取得して、出力する」という単純なものです。

Declare Function GetActiveWindow Lib "user32" () As Long
Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hwnd As Long, ByVal lpString As String, ByVal cch As Long) As Long

Private Sub GetWindowName()

'アクティブウインドウのハンドル取得
Dim lWindowHwnd As Long
lWindowHwnd = GetActiveWindow()

'バッファを確保
Dim sWindowName As String
sWindowName = String(256, Chr(0))

'アクティブウインドウのウインドウ名取得
Dim lWindowNameLen As Long
lWindowNameLen = GetWindowText(lWindowHwnd, sWindowName, Len(sWindowName))

'イミディエイトに出力
Debug.Print "現在アクテイブウインドウのタイトル名は"
Debug.Print sWindowName
Debug.Print "長さは" + Str(lWindowNameLen) + "です"

End Sub

もちろん、Office32bitではエラーメッセージなしで正常に動きます。

Declare文の変更

まず、Win32API_PtrSafe.TXTを開いて該当の箇所
「GetActiveWindow」「GetWindowTextA」などで検索し、コピペします。

Declare PtrSafe Function GetActiveWindow Lib "user32" () As LongPtr
Declare PtrSafe Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hwnd As LongPtr, ByVal lpString As String, ByVal cch As Long) As Long

Declare文の変更はたったこれだけです♪
注意点は、必ず「Win32API_PtrSafe.TXT」を見てコピペすることです。
バグの元なので全てのLong型をPtrLong型にしないようにしてください。

API実行箇所をDeclare文の型に合わせる(引数・戻り値)

次にAPI実行箇所については、Declare文と睨めっこしながら変更していきます。
今回の場合、GetActiveWindowの戻り値の型であり、
GetWindowTextの第一引数であるlWindowHwndを Long型からLongPtr型に変えます。
命名規則にもよりますが、変数名のルールで型名も考慮しているのであればそちらも変更します。
lWindowHwndからlpWindowHwnd

Private Sub GetWindowName()

'アクティブウインドウのハンドル取得
Dim lpWindowHwndAs LongPtr
lpWindowHwnd = GetActiveWindow()

'バッファを確保
Dim sWindowName As String
sWindowName = String(256, Chr(0))

'アクティブウインドウのウインドウ名取得
Dim lWindowNameLen As Long
lWindowNameLen = GetWindowText(lpWindowHwnd, sWindowName, Len(sWindowName))

'イミディエイトに出力
Debug.Print "現在アクテイブウインドウのタイトル名は"
Debug.Print sWindowName
Debug.Print "長さは" + Str(lWindowNameLen) + "です"

End Sub

他にも元からLong型のものがありますが、Declare文でもLong型なので変更しません。

以上で、VBAのOffice64bit対応は完了です。

補足:PtrSafeやPtrLong型について

簡単に紹介すると以下になります。

  • PtrSafe
    Office64bitで実行しても安全であると明示するキーワード
  •  
  • PtrLong型
    Office32bitではLong型に、Office64bitではLongLong形になる型

このことから、
Office64bitで使えるようにコードを書き換えても、 Office32bitで動くようになっています。

本ブログで一押しのオンラインスクールのご紹介♪




本ブログで一押しのオンラインスクール「Udemy」
筆者も利用しているスクールで、日頃の隙間時間に好きな講座が学べるので大活躍です♪

ジャンルが豊富で学びたい講座がきっとみつかる

AI・データサイエンスなど最先端のIT技術からプレゼンなどビジネススキルに関する講座まで15.5万以上(※海外講座含む)あるため、自分が学びたい講座をみつけることができます

お手頃な価格帯

1講座あたり数千~数万円程度で実践的なスキルアップが可能です。
講座は一度購入すれば視聴期限なく受講でき、30日返金保証もついているので安心して始めることができます。

学びやすい多彩な機能

0.5~2倍の変速機能で自分のペースで受講が可能、専用アプリを使えばスマホからオフライン環境でも視聴が可能です!
また、講師に直接掲示板から質問ができるので疑問を解決し自学自習をサポートしてくれます。

購入前に視聴できますので、是非興味のある方は↓をクリックしてみてください。




AccessExcelOfficeVBA
スポンサーリンク
nyanblog
タイトルとURLをコピーしました