Office 2010 の 32 ビット バージョンと 64 ビット バージョンとの互換性
概要 : 2GB 以上のデータを扱っているユーザーのために、Microsoft Office 2010 の 64 ビット バージョンが提供されるようになりました。この記事では、32 ビット バージョンと新しい 64 ビット バージョンとの互換性に関する問題、および以前の 32 ビット Office アプリケーションとそのソリューションについて説明します (7 ページ)。
適用対象: 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
この記事の内容
Microsoft Office 2010 の 32 ビット バージョンと 64 ビット バージョンについて
比較 : 32 ビット システムと 64 ビット システム
VBA 7 コード ベースについて
ActiveX コントロールと COM アドインの互換性
アプリケーション プログラミング インターフェイスの互換性
条件付きコンパイル属性の使用
よく寄せられる質問
まとめ
参考資料
Applies to: Microsoft Office 2010
**公開日:**2010 年 3 月
提供元: Microsoft Corporation
目次
Microsoft Office 2010 の 32 ビット バージョンと 64 ビット バージョンについて
比較 : 32 ビット システムと 64 ビット システム
VBA 7 コード ベースについて
ActiveX コントロールと COM アドインの互換性
アプリケーション プログラミング インターフェイスの互換性
条件付きコンパイル属性の使用
よく寄せられる質問
まとめ
参考資料
Microsoft Office 2010 の 32 ビット バージョンと 64 ビット バージョンについて
Microsoft Office 2010 システムには 32 ビット バージョンと 64 ビット バージョンの両方があります。64 ビット バージョンの方がはるかに大量のデータを処理できます。Microsoft Excel 2010 で大きな数を処理する場合は、特にこの点が重要になります。
新しい 64 ビット バージョンの Microsoft Office 2010 が登場したことに伴って、新バージョンの Microsoft Visual Basic for Applications (VBA) がリリースされています。これは Microsoft Visual Basic for Applications 7.0 (VBA 7) と呼ばれるもので、32 ビットと 64 ビットの両方のアプリケーションで動作します。この記事で説明している変更点は、64 ビット バージョンの Microsoft Office 2010 にのみ適用されることに注意してください。32 ビット バージョンの Office 2010 を使用すれば、以前のバージョンの Microsoft Office で作成したソリューションをそのまま修正せずに使用できます。
注意
64 ビットのシステムであっても、Office 2010 の既定のインストールでは 32 ビット バージョンがインストールされます。そのため、Office 2010 の 64 ビット バージョンのインストール オプションを明示的に選択する必要があります。
VBA 7 では、既存の Windows アプリケーション プログラミング インターフェイス (API) ステートメント (Declare ステートメント) を更新して、64 ビット バージョンで動作するようにしなければなりません。さらに、これらのステートメントで使われているユーザー定義型のアドレス ポインターおよび表示ウィンドウ ハンドルを更新することも必要です。この点については、Office 2010 の 32 ビット バージョンと 64 ビット バージョンとの間の互換性問題および推奨解決案と共に、この記事で詳しく説明します。
比較 : 32 ビット システムと 64 ビット システム
64 ビット バージョンの Office 2010 で作成するアプリケーションは、より大きなアドレス空間を参照できるので、以前よりも多くの物理メモリを使用することが可能になります。そのため、物理メモリとの間でのデータ転送に費やされるオーバーヘッドが軽減される可能性があります。
アプリケーションがデータやプログラム命令の格納に使用する物理メモリ内の特定の場所への参照 ("ポインター" とも呼ばれる) に加えて、表示ウィンドウ識別子 ("ハンドル" と呼ばれる) を参照するアドレスを使用することもできます。32 ビット システムと 64 ビット システムのどちらを使用するかに応じて、ポインターやハンドルのサイズ (バイト数) が決まります。
既存のソリューションを 64 ビット バージョンの Office 2010 で実行する場合、次に示す 2 つの基本的な問題があります。
Office 2010 のネイティブの 64 ビット プロセスは、32 ビット バイナリをロードできません。既存の Microsoft ActiveX コントロールや既存のアドインがある場合、これはよく起こる問題です。
VBA には以前はポインター データ型がなかったので、開発者はポインターとハンドルを格納するために 32 ビットの変数を使用していました。Declare ステートメントを使用した場合、API 呼び出しで返される 64 ビット値は、これらの変数で切り詰められることになります。
VBA 7 コード ベースについて
VBA 7 は旧バージョンの VBA に代わる新しいコード ベースです。VBA 7 は Office 2010 の 32 ビット バージョンと 64 ビット バージョンの両方で使用できます。VBA7 と Win64 という 2 つの条件付きコンパイル定数が用意されています。VBA7 定数を使用すると、アプリケーションで VBA 7 と旧バージョンの VBA のどちらを使用しているのかをテストすることによって、コードの下位互換性を確保できます。Win64 定数は、コードが 32 ビットとして実行されるのか、64 ビットとして実行されるのかをテストするために使用します。これらのコンパイル定数の両方について、この記事で後ほど使用例を示します。
この記事の別の箇所で示すいくつかの例外を除き、32 ビット バージョンのアプリケーションを使用して動作したドキュメント (ブックとプレゼンテーションを含む) 内のマクロは、同じアプリケーションの 64 ビット バージョンでドキュメントを読み込んだ時にも動作します。
ActiveX コントロールと COM アドインの互換性
既存の 32 ビット ActiveX コントロールは、サードパーティ製のものも Microsoft が提供しているものも、64 ビット バージョンの Office 2010 と互換性がありません。ActiveX コントロールと COM オブジェクトについては、次に示す 3 つの解決策が考えられます。
ソース コードがあれば、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) ファイルに組み込まれた外部関数を使用するのが最善策です。VBA でこれを行うには、Declare を使用して API 呼び出しを行います。
注意
Microsoft は、1,500 個の Declare ステートメントが含まれている Win32API.txt ファイルと、必要な Declare ステートメントを各自のコードに切り取って貼り付けるためのツールを提供しています。ただし、これらのステートメントは 32 ビット システム用なので、この記事で後ほど説明する情報に従って 64 ビットに変換する必要があります。既存の Declare ステートメントは、PtrSafe 属性を使用して 64 ビット向けとして安全だとマークされるまでは、64 ビット VBA にコンパイルされません。このタイプの変換のサンプルは、Excel MVP の Jan Karel Pieterse 氏の Web サイト (http://www.jkp-ads.com/articles/apideclarations.asp) にあります。
「Office Code Compatibility Inspector ユーザー ガイド」は、PtrSafe 属性の API Declare ステートメントの構文 (必要な場合) と、適切な戻り値の型の検査に利用できるツールです。
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 関数は、プロシージャを VBA コードから呼び出すときに使用する名前を表しており、DLL ファイル内のプロシージャの実際の名前に置き換えます。プロシージャの名前として AliasName 引数を指定することもできます。Lib キーワードの後ろには、呼び出すプロシージャが含まれている DLL ファイルの名前を指定します。引数リストには、プロシージャに渡す必要のあるパラメーターとデータ型を指定します。
次の 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 ビットが切り捨てられるか、他のメモリ アドレスに上書きされることがあるからです。どちらの場合も、予測できない動作やシステム クラッシュを引き起こす可能性があります。
この問題を解決するため、LongPtr という真の "ポインター" データ型が新たに VBA に導入されました。この新しいデータ型を使用すれば、次のように本来の Declare ステートメントを正しく書くことができます。
Declare PtrSafe Function RegOpenKeyA Lib "advapire32.dll" (ByVal hKey as LongPtr, ByVal lpSubKey As String, phkResult As LongPtr) As Long
このデータ型と新しい PtrSafe 属性を使用すると、この Declare ステートメントを 32 ビット システムでも 64 ビット システムでも使用できます。PtrSafe 属性は、Declare ステートメントの対象を 64 ビット バージョンの Office 2010 とすることを VBA コンパイラに指示するものです。この属性を指定せずに Declare ステートメントを 64 ビット システムで使用すると、コンパイル時エラーが発生します。ただし、PtrSafe 属性は、32 ビット バージョンの Office 2010 ではオプションです。これにより、既存の Declare ステートメントは従来どおりに動作します。
次の表では、既に説明した新しい修飾子とデータ型について再度説明すると共に、もう 1 つのデータ型と 2 つの変換演算子と 3 つの関数についても説明します。
種類 |
アイテム |
説明 |
---|---|---|
修飾子 |
PtrSafe |
Declare ステートメントが 64 ビットと互換性があることを示します。この属性は 64 ビット システムでは必須です。 |
データ型 |
LongPtr |
変数のデータ型であり、Office 2010 の 32 ビット バージョンでは 4 バイトのデータ型で、64 ビット バージョンでは 8 バイトのデータ型です。これは新しいコードでポインターやハンドルを宣言するときの推奨方法です。ただし、レガシー コードでも、64 ビット バージョンの Office 2010 で実行する場合は、やはりこれが推奨される方法です。これは 32 ビットおよび 64 ビットで VBA 7 ランタイムでのみサポートされます。そこに数値を代入することはできますが、数値型を代入することはできません。 |
データ型 |
LongLong |
これは 64 ビット バージョンの Office 2010 でのみ使用できる 8 バイトのデータ型です。数値を代入することはできますが、数値型を代入することはできません (切り詰められるのを避けるためです)。 |
変換演算子 |
CLngPtr |
単純な式を LongPtr データ型に変換します。 |
変換演算子 |
CLngLng |
単純な式を LongLong データ型に変換します。 |
関数 |
VarPtr |
バリアント コンバーター。64 ビット バージョンでは LongPtr を返し、32 ビット バージョンでは Long を返します (4 バイト)。 |
関数 |
ObjPtr |
オブジェクト コンバーター。64 ビット バージョンでは LongPtr を返し、32 ビット バージョンでは Long を返します (4 バイト)。 |
関数 |
StrPtr |
文字列コンバーター。64 ビット バージョンでは LongPtr を返し、32 ビット バージョンでは Long を返します (4 バイト)。 |
次の例は、これらのアイテムのいくつかについて、Declare ステートメントでの使用方法を示したものです。
Declare PtrSafe Function RegOpenKeyA Lib "advapi32.dll" (ByVal Key As LongPtr, ByVal SubKey As String, NewKey As LongPtr) As Long
Declare ステートメントで PtrSafe を指定しないと、64 ビット バージョンの Office 2010 と互換性がないものと見なされます。
既に述べたように、VBA7 と Win64 という 2 つの新しい条件付きコンパイル定数があります。以前のバージョンの Microsoft Office との下位互換性を確保するには、VBA7 定数を使用して、以前のバージョンの Microsoft Office で 64 ビット コードが使用されないようにします (これがより一般的なやり方です)。32 ビット バージョンと 64 ビット バージョンとでコードが異なる場合は (たとえば、64 ビット バージョンについては LongLong を使用し、32 ビット バージョンについては Long を使用する数値演算 API を呼び出す場合など)、Win64 定数を使用します。次のコードで、この 2 つの定数の使用例を示します。
#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 条件付きコンパイル定数を使用する必要があります。しかし、32 ビットのコードを書き、それを Office 2010 で使用する場合は、このコンパイル定数を使用しなくても、そのコードは以前のバージョンの 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 など) に応じて異なります。たとえば、Excel は、64 ビット バージョンの Microsoft Office ではずっと大きなワークシートを処理できます。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 では、これらの関数は 64 ビットの LongPtr を返します。これは、Declare ステートメントに渡すことができます。これらの関数の使用法は、以前のバージョンの VBA から変更されていません。唯一の違いは、LongPtr を返すようになったことです。
まとめ
64 ビット バージョンの Office 2010 が追加されたことにより、能力の向上に伴ってより多くのデータを移動させることができるようになりました。32 ビット コードを書く場合は、変更なしで 64 ビット バージョンの Microsoft Office を使用できます。しかし、64 ビット コードを書く場合は、そのコードに特定のキーワードと条件付きコンパイル定数を含めることで、以前のバーションの Microsoft Office との下位互換性が確保されるようにし、32 ビット コードと 64 ビット コードを組み合わせて使用する場合には正しいコードが実行されるように処置する必要があります。
参考資料
Declare ステートメントの詳細については、次のリソースを参照してください。