64 位元 Visual Basic for Applications 概觀

Microsoft Visual Basic for Applications (VBA) 是與 Microsoft Office 所一起發行的 Visual Basic 版本。 在 Microsoft Office 2010 中,VBA 包含讓 VBA 程式碼在 32 位元和 64 位元環境中,都能正確地執行的的語言功能。

注意事項

預設安裝 Office 2010、2013和2016 的 32位元版本。 您必須在安裝期間明確地選擇要安裝 64 位元版本。 從 Office 2019 和 Microsoft 365 開始,預設安裝為64位版本。

如果程式碼沒有修改以便在 64 位元版本的 Office 中執行,則在 64 位元平台上執行 Office 2010 之前版本所撰寫的 VBA 程式碼 (VBA 6 或更早的版本),可能會導致錯誤。 因為 VBA 6 或更早的版本是隱含以 32 位元平台為目標,而且通常包含 Declare 陳述式,會使用指標和控制代碼的 32 位元資料類型來呼叫 Windows API,因此將產生錯誤。 由於 VBA 第 6 版或更早的版本並沒有指標或控制代碼的特定資料類型,因此會使用 Long 資料類型 ( 32 位元 4 個位元組的資料類型),來參考指標和控制代碼。 在 64 位元環境中,指標和控制代碼是 8 位元組 64 位元的數量。 32 位元資料類型中,無法保存這些 64 位元數量。

注意事項

只有在 Microsoft Office 的 64 位元版本中執行時,您才需要修改 VBA 程式碼。

在 64 位元的 Office 執行舊版 VBA 程式碼的問題是,若嘗試將 64 位元載入到 32 位元資料類型時,會截斷 64 位元數量。 這可能會導致記憶體滿溢、程式碼中未預期的結果,以及可能的應用程式失敗。

若要解決這個問題,並讓 VBA 程式碼在 32 位元和 64 位元的環境中正常運作,已新增許多語言功能到 VBA 之中。 在這份文件底部的表格摘要說明了新的 VBA 語言功能。 三個重要的新增部分是 LongPtr 類型別名、LongLong 資料類型,以及 PtrSafe 關鍵字。

  • LongPtr。 VBA 現在包含變數的類型別名 LongPtrLongPtr 所解析的目標實際資料類型是根據其所執行的 Office 版本;LongPtr 以 32 位元版本的 Office 解析為 Long,且 LongPtr 以 64 位元版本的 Office 解析為 LongLong。 將 LongPtr 用於指標和控制代碼。

  • LongLongLongLong 是帶正負號的 64 位元整數資料類型,只可以在 64 位元版本的 Office 中使用。 將 LongLong 用於64 位元整數。 轉換函數必須用來將 LongLong (包括在 64 位元平台上的 LongPtr ) 明確地指派為較小的整數類型。 不允許將 LongLong 隱含轉換為較小的整數。

  • PtrSafePtrSafe 關鍵字會判斷提示 Declare 陳述式是否能夠安全地在 64 位元版本的 Office 中執行。

重要事項

所有 Declare 陳述式,在 64 位元版本的 Office 中執行時,現在都必須包含 PtrSafe 關鍵字。 請務必了解,僅將 PtrSafe 關鍵字新增至 Declare 陳述式只表示 Declare 陳述式明確地將目標設定為 64 位元。 必須儲存 64 位元 (包括傳回值和參數) 的陳述式內所有資料類型仍必須修改為存放 64 位元的數量。

注意事項

具有 PtrSafe 關鍵字的 Declare 陳述式是建議的語法。 包括 PtrSafeDeclare 陳述式,在 32 位元和 64 位元的平台上的 VBA7 開發環境中,都可以正確運作。

若要確保回溯為 VBA7 或更早版本的相容性,請使用下列建構︰

 #If VBA7 Then 
 Declare PtrSafe Sub... 
 #Else 
 Declare Sub... 
 #EndIf

請考慮下列 Declare 陳述式範例。 如果在 64 位元版本的 Office 中執行未修改的 Declare 陳述式會導致錯誤,這表示 Declare 陳述式中不包括 PtrSafe 限定詞。 已修改的 VBA 範例包含了 PtrSafe 限定詞,但請注意,傳回的值 (使用中視窗的指標) 傳回了 Long 資料類型。 在 64 位元版本的 Office 中這不正確,因為指標是 64 位元。 PtrSafe 限定詞會告訴編譯器 Declare 陳述式是以 64 位元為目標,因此不會發生錯誤的陳述式執行。 但因為傳回的值尚未更新為 64 位元資料類型,所以傳回值會截斷,導致傳回值不正確。

以下是未修改的舊版 VBA Declare 陳述式範例︰

Declare Function GetActiveWindow Lib "user32" () As Long

以下 VBA Declare 陳述式範例修改為包括 PtrSafe 限定詞,但仍在使用 32 位元的傳回值︰

Declare PtrSafe Function GetActiveWindow Lib "user32" () As Long

再次提醒您,您必須修改 Declare 陳述式以包含 PtrSafe 限定詞,且您必須更新陳述式內任何需要保留 64 位元數量的變數,以便使變數使用 64 位元資料類型。

以下是 VBA Declare 陳述式範例修改為包括 PtrSafe 關鍵字和更新,以使用適當的 64 位元 (LongPtr) 資料類型︰

Declare PtrSafe Function GetActiveWindow Lib "user32" () As LongPtr

總而言之,若要讓程式碼在 64 位元版本的 Office 中運作,您需要找出並修改所有現有的 Declare 陳述式,以使用 PtrSafe 限定詞。 您還需要找出並修改這些參考指標和控制代碼的 Declare 陳述式內的所有資料類型,以使用新的 64 位元相容的 LongPtr 類型別名,而且需要以新的 LongLong 資料類型來保留 64 位元整數。 此外,您必須更新任何包含指標或控制代碼和 64 位元整數的使用者定義類型 (UDT),以使用 64 位元資料類型,並確認所有變數的指派都是正確的,來避免類型不符的錯誤。

撰寫在 32 位元和 64 位元的 Office 上都能運作的程式碼

若要撰寫可在 32 位元和 64 位元的 Office之間移植的程式碼,您只需要針對所有的指標和控制代碼值,使用新的 LongPtr 類型別名,而不是 LongLongLong。 根據執行 LongPtr 類型別名的Office 版本,會解析為正確的 LongLongLong 資料類型。

請注意,如果您需要執行不同的邏輯 (例如您需要操縱大型的 Excel 專案中的 64 位元值),您可以使用 Win64 條件式編譯常數,如下一節中所示。

撰寫在 Office 2010 (32 位元或 64 位元) 及先前的 Office 版本中都能運作的程式碼

若要撰寫在新的和較舊版本的 Office 中都能運作的程式碼,您可以使用新的 VBA7Win64 條件式 編譯器常數組合。 Vba7 條件式編譯器常數,是用來判斷程式碼是否正在第 7 版 VB 編輯器中執行 (在 Office 2010 發行的 VBA 版本)。 Win64 條件式編譯常數,是用來判斷所執行的 Office 哪一個版本 (32 位元或 64 位元)。

#if Vba7 then 
'  Code is running in the new VBA7 editor 
     #if Win64 then 
     '  Code is running in 64-bit version of Microsoft Office 
     #else 
     '  Code is running in 32-bit version of Microsoft Office 
     #end if 
#else 
' Code is running in VBA version 6 or earlier 
#end if 
 
#If Vba7 Then 
Declare PtrSafe Sub... 
#Else 
Declare Sub... 
#EndIf 

VBA7 語言更新的摘要

下表摘要說明新 VBA 語言每個新增的項目,並提供說明。

名稱 類型 描述
PtrSafe 關鍵字 判斷提示 Declare 陳述式是否以 64 位元系統為目標。 在 64 位元系統中為必要。
LongPtr 資料類型 在 32 位元系統上對應至 Long,或在 64 位元系統上對應至 LongLong 的類型別名。
LongLong 資料類型 8 位元組資料類型別只有在 64 位元系統上可用。 數字類型。 在以下範圍內的整數數字:9,223,372,036,854,775,808 to 9,223,372,036,854,775,807。

LongLong 只有在 64 位元平台上是有效的宣告類型。 此外,LongLong 可能不會隱含地轉換成較小的類型 (例如,您不能將 LongLong 指派給 Long)。 這麼做是為了避免指標不小心遭截斷。

允許明確的強制型轉,如此在上述範例中,您可以將 CLng 套用到 LongLong,並將結果指派給 Long (僅限 64 位元平台上有效)。
^ LongLong 類型宣告字元 明確宣告為常值 LongLong。 要宣告 LongLong 常值大於 Long 的最大值時為必要 (否則就會隱含轉換成 double)。
CLngPtr 類型轉換函數 將簡單運算式轉換成 LongPtr 資料類型。
CLngLng 類型轉換函數 將簡單運算式轉換成 LongLong 資料類型 (僅限 64 位元平台上有效)。
vbLongLong VarType 常數 LongLong 整數 (僅限 64 位元平台上有效)。
DefLngPtr DefType 陳述式 將範圍中變數的預設資料型設為 LongPtr
DefLngLng DefType 陳述式 將範圍中變數的預設資料型設為 LongLong

另請參閱

支援和意見反應

有關於 Office VBA 或這份文件的問題或意見反應嗎? 如需取得支援服務並提供意見反應的相關指導,請參閱 Office VBA 支援與意見反應