32 位元和 64 位元版本的 Office 2010 相容性

**摘要:**針對處理 2GB (含) 以上資料的客戶,Microsoft Office 2010 現在提供 64 位元版本。本文討論 32 位元版本與 64 位元新版本的相容性問題,以及舊版 32 位元 Office 應用程式的問題及其解決方法 (7 頁列印頁面)。

前次修改時間: 2015年4月24日

適用於: Excel 2010 | Office 2007 | Office 2010 | Open XML | PowerPoint 2010 | SharePoint Server 2010 | VBA | Visual Basic for Applications 7.0 (VBA 7.0) | Word 2010

本文內容
關於 32 位元和 64 位元版本的 Microsoft Office 2010 簡介
關於 32 位元系統與 64 位元系統的比較
VBA 7 程式碼基底簡介
ActiveX 控制項和 COM 增益集相容性
應用程式開發介面相容性
使用條件式編譯屬性
常見問題集
結論
其他資源

Applies to:   Microsoft Office 2010

**發行日期:**2010 年 3 月

提供者: Microsoft Corporation

內容

  • 關於 32 位元和 64 位元版本的 Microsoft Office 2010 簡介

  • 關於 32 位元系統與 64 位元系統的比較

  • VBA 7 程式碼基底簡介

  • ActiveX 控制項和 COM 增益集相容性

  • 應用程式開發介面相容性

  • 使用條件式編譯屬性

  • 常見問題集

  • 結論

  • 其他資源

關於 32 位元和 64 位元版本的 Microsoft Office 2010 簡介

Microsoft Office 2010 系統提供 32 位元和 64 位元版本。64 位元版本可讓您處理更大型的資料集,特別是在 Microsoft Excel 2010 中處理大型數字時。

自引進新的 64 位元版本 Microsoft Office 2010 以來,已發行可同時搭配 32 位元和 64 位元應用程式使用的新版 Microsoft Visual Basic for Applications (VBA) (又稱為 Microsoft Visual Basic for Applications 7.0 (VBA 7))。請注意,本文所討論的變更僅適用於 64 位元版本的 Microsoft Office 2010。使用 32 位元版本的 Office 2010 可讓您使用舊版 Microsoft Office 內建的解決方案,而不需要進行修改。

注意

在 Office 2010 的預設安裝中,已安裝 32 位元版本,即使是在 64 位元系統上亦然。您必須「明確」選取 Office 2010 64 位元版本安裝選項。

在 VBA 7 中,您必須更新現有的 Windows 應用程式開發介面 (API) 陳述式 (Declare 陳述式),才能搭配 64 位元版本使用。此外,您必須更新位址指標,並在這些陳述式所使用的使用者定義類型中顯示視窗控制碼。本文將就此更進一步地討論,並將討論 32 位元與 64 位元版本 Office 2010 之間的相容性問題及建議的解決方法。

關於 32 位元系統與 64 位元系統的比較

使用 64 位元版本 Office 2010 建立的應用程式可以參照較大型的位址空間,因此有機會使用比過去更多的實體記憶體,而可能降低將資料移入及移出實體記憶體的經常費用。

您除了可以使用位址參照應用程式在實體記憶體中,用來儲存資料或儲存程式設計指令的特定位置 (又稱為「指標」) 之外,還可以使用位址參照顯示視窗識別碼 (又稱為「控制碼」)。根據您使用的是 32 位元或 64 位元系統,會決定指標或控制碼的大小 (位元組)。

當您使用 64 位元版本的 Office 2010 執行現有的解決方案時,有兩個基本問題:

  • Office 2010 中的原生 64 位元處理序無法載入 32 位元二進位檔案。當您具有現有的 Microsoft ActiveX 控制項和現有的增益集時,通常預期會有此問題。

  • VBA 先前沒有指標資料類型,因此開發人員使用 32 位元變數來儲存指標和控制碼。這些變數現在會在使用 Declare 陳述式時,截斷 API 呼叫傳回的 64 位元值。

VBA 7 程式碼基底簡介

VBA 7 是取代舊版 VBA 的新程式碼基底。32 位元和 64 位元版本的 Office 2010 均提供 VBA 7。VBA 7 提供兩個條件式編譯常數:VBA7 和 Win64。VBA7 常數透過測試您的應用程式使用 VBA 7 或舊版 VBA,來協助確保程式碼的回溯相容性。Win64 常數可用來測試程式碼是以 32 位元或 64 位元執行。本文稍後將示範這兩個編譯常數。

除了本文其他地方顯示的特定例外狀況之外,如果文件 (也包含活頁簿和簡報) 中的巨集過去使用 32 位元版本的應用程式來執行,當您在 64 位元版本的相同應用程式中載入文件之後,也能執行此巨集。

ActiveX 控制項和 COM 增益集相容性

現有的 32 位元 ActiveX 控制項 (包括協力廠商和 Microsoft 提供的控制項) 與 64 位元版本的 Office 2010 不相容。針對 ActiveX 控制項和 COM 物件,有三種可能的解決方法:

  • 如果您具有原始程式碼,您可以自行產生 64 位元版本。

  • 您可以連絡廠商取得更新版本。

  • 您可以尋求替代解決方案。

Office 2010 中的原生 64 位元處理序無法載入 32 位元二進位檔案。這包括 MSComCtl 的通用控制項 (TabStrip、Toolbar、StatusBar、ProgressBar、TreeView、ListViews、ImageList、Slider、ImageComboBox),以及 MSComCt2 的控制項 (Animation、UpDown、MonthView、DateTimePicker、FlatScrollBar)。舊版 Microsoft Office 已安裝這些控制項,且 32 位元 Office 2010 會繼續安裝。當您將程式碼移轉至 64 位元 Office 2010 時,必須找到使用這些控制項之現有 Microsoft Office VBA 解決方案的替代解決方案。64 位元 Office 2010 不提供通用控制項的 64 位元版本。

應用程式開發介面相容性

VBA 和型別程式庫的組合提供您許多功能以建立 Microsoft Office 應用程式。但是,有時您必須直接與電腦的作業系統及其他元件通訊,例如管理記憶體或處理序時、使用視窗和控制項等使用者介面時,或修改 Windows 登錄時,在這些情況下,您的最佳作法是使用動態連結程式庫 (DLL) 檔案中內嵌的外部函數之一。您可以透過使用 Declare 陳述式呼叫 API,在 VBA 中執行這項操作。

注意

Microsoft 提供 Win32API.txt 檔案,其中包含 1,500 個 Declare 陳述式,以及剪下您需要的 Declare 陳述式並貼到程式碼中的工具。但是,這些陳述式適用於 32 位元系統,必須使用本文稍後討論的資訊轉換成 64 位元。您必須使用 PtrSafe 屬性,將現有的 Declare 陳述式標示為可安全用於 64 位元,該陳述式才會以 64 位元 VBA 編譯。您可以在 Excel MVP Jan Karel Pieterse 的網站 (網址為 http://www.jkp-ads.com/articles/apideclarations.asp) 中找到此轉換類型的範例。

Office 程式碼相容性檢查使用者指南是檢查 API Declare 陳述式的語法中是否有 PtrSafe 屬性,以及適當傳回類型 (如有必要) 的實用工具。

Declare 陳述式類似下列其中一項,視您呼叫副程式 (不具有傳回值) 或函數 (具有傳回值) 而定。

  Public/Private Declare Sub SubName Lib "LibName" Alias "AliasName" (argument list)
  Public/Private Declare Function FunctionName Lib "Libname" alias "aliasname" (argument list) As Type

SubName 函數或 FunctionName 函數會取代成 DLL 檔案中的程序實際名稱,以代表從 VBA 程式碼呼叫程序時所使用的名稱。如有需要,您也可以指定 AliasName 引數做為程序的名稱。包含所呼叫之程序的 DLL 檔案名稱會跟在 Lib 關鍵字之後。最後,引數清單包含必須傳遞至程序的參數和資料類型。

下列 Declare 陳述式開啟 Windows 登錄中的「子機碼」,並取代其值。

  Declare Function RegOpenKeyA Lib "advapi32.dll" (ByVal Key As Long, ByVal SubKey As String, NewKey As Long) As Long

RegOpenKeyA 函數的 Windows.h (視窗控制碼) 項目如下:

  LONG RegOpenKeyA ( HKEY hKey, LPCSTR lpSubKey, HKEY *phkResult );

在 Microsoft Visual C 和 Microsoft Visual C++ 中,前一範例會同時正確地編譯 32 位元和 64 位元。這是因為 HKEY 會定義為指標,其大小反映程式碼編譯所在之平台的記憶體大小。

在舊版 VBA 中,並沒有特定的指標資料類型,因此會使用 Long 資料類型。此外,由於 Long 資料類型一律為 32 位元,因此在具有 64 位元記憶體的系統上使用時,會因為截斷上方 32 位元或複寫其他記憶體位址而損毀。這些情況會導致無法預期的行為或系統當機。

為了解決這個問題,VBA 現在包含正確的「指標」資料類型:LongPtr。此新資料類型可讓您正確地寫入原始 Declare 陳述式,如下所示:

  Declare PtrSafe Function RegOpenKeyA Lib "advapire32.dll" (ByVal hKey as LongPtr, ByVal lpSubKey As String, phkResult As LongPtr) As Long

此資料類型和新的 PtrSafe 屬性可讓您在 32 位元或 64 位元系統上使用此 Declare 陳述式。PtrSafe 屬性會向 VBA 編譯器指示 Declare 陳述式是針對 64 位元版本的 Office 2010。如果沒有此屬性,在 64 位元系統中使用 Declare 陳述式會導致編譯時期錯誤。請注意,PtrSafe 屬性在 32 位元版本的 Office 2010 上為選用。這讓現有的 Declare 陳述式可如往常般運作。

下表提供已討論的新限定詞和資料類型,以及其他資料類型、兩個轉換運算子和三個函數的詳細資訊。

類型

項目

描述

限定詞

PtrSafe

表示 Declare 陳述式與 64 位元相容。此屬性在 64 位元系統上為強制。

資料類型

LongPtr

變數資料類型,在 32 位元版本的 Office 2010 上為 4 位元組資料,在 64 位元版本的 Office 2010 上為 8 位元組資料類型。這是為新程式碼宣告指標或控制碼的建議方式,但是也適用於必須在 64 位元版本的 Office 2010 上執行的舊版程式碼。僅 32 位元和 64 位元上的 VBA 7 執行階段才會支援。請注意,您可以指派數值給此資料類型,但不可以指派數字類型。

資料類型

LongLong

這是 8 位元組資料類型,僅適用於 64 位元版本的 Office 2010。您可以指派數值,但不可以指派數字類型 (以避免截斷)。

轉換運算子

CLngPtr

將簡單運算式轉換成 LongPtr 資料類型。

轉換運算子

CLngLng

將簡單運算式轉換成 LongLong 資料類型。

函數

VarPtr

變數轉換器。在 64 位元版本上傳回 LongPtr,在 32 位元版本 (4 位元組) 上傳回 Long。

函數

ObjPtr

物件轉換器。在 64 位元版本上傳回 LongPtr,在 32 位元版本 (4 位元組) 上傳回 Long。

函數

StrPtr

字串轉換器。在 64 位元版本上傳回 LongPtr,在 32 位元版本 (4 位元組) 上傳回 Long。

下列範例顯示如何在 Declare 陳述式中使用上述部分項目。

  Declare PtrSafe Function RegOpenKeyA Lib "advapi32.dll" (ByVal Key As LongPtr, ByVal SubKey As String, NewKey As LongPtr) As Long

請注意,不具有 PtrSafe 屬性的 Declare 陳述式被視為與 64 位元版本的 Office 2010 不相容。

如前所述,新增了兩個條件式編譯常數:VBA7 和 Win64。若要確保與舊版 Microsoft Office 的回溯相容性,您可以使用 VBA7 常數 (這是較一般的情況),以避免在舊版 Microsoft Office 中使用 64 位元程式碼。針對在 32 位元版本與 64 位元版本之間不同的程式碼 (例如在呼叫數學 API 時,若是 64 位元版本則使用 LongLong,若是 32 位元版本則使用 Long),您可以使用 Win64 常數。下列程式碼將示範這兩個常數的用法。

  #if Win64 then
     Declare PtrSafe Function MyMathFunc Lib "User32" (ByVal N As LongLong) As LongLong
  #else
     Declare Function MyMathFunc Lib "User32" (ByVal N As Long) As Long
  #end if
  #if VBA7 then
     Declare PtrSafe Sub MessageBeep Lib "User32" (ByVal N AS Long)
  #else
     Declare Sub MessageBeep Lib "User32" (ByVal N AS Long)
  #end if

總而言之,如果您撰寫 64 位元程式碼並想在舊版 Microsoft Office 中使用,則需要使用 VBA7 條件式編譯常數;但是,如果您在 Office 2010 中撰寫 32 位元程式碼,該程式碼會像在舊版 Microsoft Office 中一樣運作,而不需要編譯常數。如果您想確保針對 32 位元版本使用 32 位元陳述式,並針對 64 位元版本使用 64 位元陳述式,最好使用 Win64 條件式編譯常數。

使用條件式編譯屬性

下列程式碼是需要更新之舊版 VBA 程式碼的範例。請注意,舊版程式碼中的資料類型已更新為使用 LongPtr,因為這些資料類型參照控制碼或指標。

舊版 VBA 程式碼

  Declare Function SHBrowseForFolder Lib "shell32.dll" _
    Alias "SHBrowseForFolderA" (lpBrowseInfo As BROWSEINFO) As Long
    
  Public Type BROWSEINFO
    hOwner As Long
    pidlRoot As Long
    pszDisplayName As String
    lpszTitle As String
    ulFlags As Long
    lpfn As Long
    lParam As Long
    iImage As Long
  End Type

新的 VBA 程式碼

  #if VBA7 then    ' VBA7 
  Declare PtrSafe Function SHBrowseForFolder Lib "shell32.dll" _
    Alias "SHBrowseForFolderA" (lpBrowseInfo As BROWSEINFO) As Long
  
  Public Type BROWSEINFO
    hOwner As LongPtr
    pidlRoot As Long
    pszDisplayName As String
    lpszTitle As String
    ulFlags As Long
    lpfn As LongPtr
    lParam As LongPtr
    iImage As Long
  End Type
   
  #else    ' Downlevel when using previous version of VBA7
  
  Declare Function SHBrowseForFolder Lib "shell32.dll" _
    Alias "SHBrowseForFolderA" (lpBrowseInfo As BROWSEINFO) As Long
  
  Public Type BROWSEINFO
    hOwner As Long
    pidlRoot As Long
    pszDisplayName As String
    lpszTitle As String
    ulFlags As Long
    lpfn As Long
    lParam As Long
    iImage As Long
  End Type
   
  #end if
  Sub TestSHBrowseForFolder ()
      Dim bInfo As BROWSEINFO
      Dim pidList As Long
  
      bInfo.pidlRoot = 0&
      bInfo.ulFlags = &H1
      pidList = SHBrowseForFolder(bInfo)
  End Sub

常見問題集

以下是與 32 位元和 64 位元版本 Microsoft Office 相關的常見問題集。

  • 何時應該使用 64 位元版本的 Microsoft Office?
    真正的問題在於您使用的主應用程式為何 (Excel、Word 等)。例如,搭配 64 位元版本的 Microsoft Office,Excel 可以處理較大型的工作表。

  • 我是否可以並排安裝 64 位元和 32 位元版本的 Microsoft Office?
    否。

  • 何時應該將 Long 參數轉換成 LongPtr?
    您必須在 Microsoft Developers Network 上的 Windows API 文件中,查看您要呼叫的函數。控制碼和指標需要轉換成 LongPtr。例如,RegOpenKeyA 文件提供下列簽章:

    LONG WINAPI RegOpenKeyEx(
      __in        HKEY hKey,
      __in_opt    LPCTSTR lpSubKey,
      __reserved  DWORD ulOptions,
      __in        REGSAM samDesired,
      __out       PHKEY phkResult
    );
    

    參數的定義如下:

    參數

    描述

    hKey [in]

    開啟登錄機碼的「控制碼」。

    lpSubKey [in, optional]

    要開啟之登錄子機碼的名稱。

    ulOptions

    此參數會予以保留且必須為零。

    samDesired [in]

    指定機碼所需存取權限的遮罩。

    phkResult [out]

    接收已開啟機碼的控制碼之變數的「指標」。

    Win32API_PtrSafe.txt 中,Declare 陳述式的定義如下:

    Declare PtrSafe Function RegOpenKeyEx Lib "advapi32.dll" Alias "RegOpenKeyExA" (ByVal hKey As LongPtr, ByVal lpSubKey As String, ByVal ulOptions As Long, ByVal samDesired As Long, phkResult As LongPtr) As Long
    
  • 我是否應該轉換結構中的指標和控制碼?
    是。請參閱 Win32API_PtrSafe.txt 中的 MSG 類型:

    Type MSG
        hwnd As LongPtr
        message As Long
        wParam As LongPtr
        lParam As LongPtr
        time As Long
        pt As POINTAPI
    End TypeF
    
  • 何時應該使用 strptr、varpt 和 objptr?
    您應該使用這些函數來分別擷取字串、變數和物件的指標。在 64 位元版本的 Microsoft Office 上,這些函數會傳回可傳遞至 Declare 陳述式的 64 位元 LongPtr。這些函數的用法自舊版 VBA 以來未曾變更。唯一的差異在於現在會傳回 LongPtr。

結論

新增 64 位元版本的 Office 2010 可讓您四處移動資料以增加容量。撰寫 32 位元程式碼時,您可以使用 64 位元版本的 Microsoft Office,而不需要進行任何變更。但是撰寫 64 位元程式碼時,您應該確定程式碼包含特定關鍵字和條件式編譯常數,以確保程式碼可與舊版 Microsoft Office 相容;您也應該確定混合 32 位元和 64 位元程式碼時,會執行正確的程式碼。

其他資源

如需 Declare 陳述式的詳細資訊,請參閱下列資源: