Officeバージョンの変更
Office2010以前は、Microsoftは32ビットバージョンしか提供していませんでしたが、2010年以降は、32ビットと64ビットの2つのバージョンのOfficeがありました。後者はより大きなデータを処理でき、VBAコードの実行速度が向上します。コードの互換性、特にAPI宣言も複雑になっています。
Office 2010以降、Officeには2つのバージョンがあります。64ビットExcelはより大きなデータを処理でき、パフォーマンスが向上しました。64ビットの導入に伴い、VBAまたはVBA7の新しいバージョンも導入されました。2つのバージョンで同時に実行できます。Office2010をインストールする場合、デフォルトのインストールバージョンは32ビットです。64ビットバージョンが必要な場合は、手動で選択する必要があります。
VBA 7では、64ビットで実行するために以前のバージョンのAPIを再宣言する必要があります。ステートメントで使用されているアドレスポインタとウィンドウハンドル宣言を更新する必要があります。
Windowsシステムバージョン
64ビットオフィシャルは、以前よりも大きなメモリアドレス空間を参照し、より多くの物理メモリを使用する可能性があります。データの保存やコード命令(ポインタ)の保存のためにアプリケーションプログラムを参照することに加えて、アドレスを使用して、表示されたウィンドウハンドルを参照することもできます。32ビットシステムと64ビットシステムのどちらを使用しているかに応じて、ポインターまたはハンドルのサイズ(バイト単位)を決定します。
64ビットOfficeを実行している場合、2つの基本的な問題に直面します。
- オフィスのネイティブ64ビットプロセスは、32ビットバイナリファイルをロードできません。ActiveXコントロールと既存のプラグインを使用する場合、それらは互換性がありません。
- VBA 7は、以前はポインターデータ型を提供していませんでした。開発者が32ビット変数を使用してポインターまたはハンドルを格納する場合、Declareで定義されたAPIによって返される64ビット値を使用すると、値の一部が破棄されます。
VBA7コードの変更
VBA7は新しいコードベースであり、以前のバージョンのVBAに置き換わるものであり、32ビットおよび64ビットのOfficeに適しています。これは、VBA7とWin64の2つの条件付きコンパイル定数を提供します。
VBA7定数:
コードの下位互換性を確保するために、アプリケーションがVBA7を使用するか以前のバージョンのVBAを使用するかを決定します。
Win64定数:
コードを32ビット形式で実行するか64ビット形式で実行するかを決定します。
ActiveXコントロールとCOMアドインの互換性
既存の32ビットActiveXコントロール(サードパーティおよびMicrosoftが提供するものを含む)は、64ビットバージョンのOfficeと互換性がありません。ActiveXコントロールとComオブジェクトの場合、次の3つの解決策が考えられます。
- ソースコードが利用できる場合は、64ビットバージョンを生成できます。
- 更新については、サプライヤにお問い合わせください。
- 他の解決策を探してください。
Officeのネイティブ64ビットプロセスは、32ビットバイナリファイルをロードできません。MSComCtl共通コントロール(TabStrip、Toolbar、StatusBar、ProgressBar、TreeView、ListViews、ImageList、Slider、ImageComboBox)およびMSComCt2コントロール(Animation、UpDown、MonthView、DateTimePicker、FlatScrollBar)を含め、これらのコントロールは以前のOfficeまたは現在の32によってインストールされます。 -ビットオフィス、64ビットオフィスに移行する場合は、既存のコントロールを置き換える必要があります。64ビットOfficeは、64ビットユニバーサルコントロールを提供していません。
WindowsAPIインターフェイスの互換性
VBAタイプライブラリは多くの機能を提供しますが、メモリやプロセスを管理するとき、ユーザーインターフェイスを使用するとき、レジストリを変更するときなど、コンピュータのオペレーティングシステムやその他のコンポーネントと直接通信する必要がある場合があります。これらの使用シナリオでは、最良の選択これは、組み込み動的リンクライブラリ(DLL)の発信機能です。Delcareステートメントを使用して、VBAにDLL関数をインポートします。
Delareステートメントの構文構造は、戻り値の型があるかどうかを確認するために次のとおりです。
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内のエクスポートされた関数名を置き換えます。APIのASCIIまたはUnicodeバージョンを呼び出す場合は、エイリアス(AliasName)を指定できます。Libの後に、インポートされた関数が配置されているDll名が続きます。 。パラメータリストには、DLLに渡されるエクスポートされた関数と同じものが含まれている必要があります。
次のAPI関数は、Windowsレジストリでサブキーを開き、その値を置き換えます。
Declare Function RegOpenKeyA Lib "advapi32.dll" (ByVal Key As Long, ByVal SubKey As String, NewKey As Long) As Long
この関数は、Windows APIダイナミックリンクライブラリAdvapi32.dllにあり、その関数名はRegOpenKeyWです。プロトタイプは次のように定義されています。
LSTATUS RegOpenKeyW(HKEY hKey,LPCWSTR lpSubKey,PHKEY phkResult);
CおよびC ++では、APIは32ビットおよび64ビット用にコンパイルできます。これは、HKEYがポインタとして定義されているためです。ポインタは、コンパイルされたコードが配置されているプラットフォームのメモリサイズを正しく反映できます。
初期のVBAバージョンでは、特定のポインタデータ型がないため、Longデータ型が使用され、Long型は32ビットです。64ビットメモリのシステムで使用される場合、この状況は中断されます。 32ビット切り捨てられるか、他のメモリアドレスを上書きする可能性があります。これらの状態は、予期しない動作やシステムクラッシュにつながる可能性があります。
この問題を解決するために、VBAには実際のポインタデータ型LongPtrが含まれるようになりました。この新しいデータ型は、APIインポートステートメントを正しく記述できます。
Declare PtrSafe Function RegOpenKeyW Lib "advapi32.dll" (ByVal hKey as LongPtr,ByVal lpSubKey as string,Byval phkResult as LongPtr) as Long
LongPtrデータ型とPtrSafe機能は、32ビットおよび64ビットシステムでAPIインポート関数を正しく宣言できます。PtrSafe機能は、宣言ステートメントが64ビットOfficeに当てはまることをVBAコンパイラに示します。この機能がないと、Delcareステートメントによって64ビットシステムでコンパイルエラーが発生します。PtrSafeステートメントはOfficeの32ビットの性質ではオプションであることに注意してください。次の表に、関数とデータ型の説明を示します。
タイプ | 項目 | 説明 |
---|---|---|
修飾子 | PtrSafe | APIが64ビットと互換性があることを示します。これは64ビットシステムで必要です。 |
データ・タイプ | LongPtr | これは実際のデータ型ではありません.32ビットバージョンでは4バイトのデータ型(Long)であり、64ビットバージョンでは8バイトのデータ型(LongLong)です。これは、VBA 7の後にポインターとハンドルを宣言するための推奨される方法です。これは、32ビットおよび64ビットのVBA7でのみサポートされています。 |
データ・タイプ | LongLong | 8バイトのデータ型は、64ビットのOfficeでのみ使用できます。 |
変換演算子 | CLngPtr | 式をLongPtrタイプに変換します。 |
変換演算子 | CLngLng | 式をLongLong型に変換します。 |
関数 | VarPtr | バリアント型アドレス変換。64ビットでLongPtrを返し、32ビットでLongデータ型を返します。 |
関数 | ObjPtr | オブジェクトアドレス変換。64ビットでLongPtrを返し、32ビットでLongデータ型を返します。 |
関数 | StrPtr | 文字列アドレスアドレス変換、LongPtrは64ビットで返され、Longデータ型は32ビットで返されます。 |
注:PtrSafe機能のないAPI宣言ステートメントは、64ビットOfficeと互換性がないと見なされます。
要約すると、VBA7とWin64の2つの条件付きコンパイル定数があります。以前のバージョンのOfficeとの下位互換性を確保するために、VBA7定数を使用して、64ビットコードが以前のバージョンで使用されないようにすることができます。64ビットバージョンでLongLongを使用し、32ビットバージョンでLongを使用するAPIなど、32ビットバージョンと64ビットバージョンの間の異なるコードの場合、Win64定数を使用できます。次の例ではこれらを使用しています。 2つの定数:
#if Win64 Then
Declare PtrSafe Function MyTestFunc Lib "DllName"(Byval N as LongLong) as LongLong
#else
Declare MyTestFunc Lib "DllName"(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ビットコードを記述していて、以前のOfficeとの互換性が必要な場合は、VBA7条件付きコンパイル定数を使用してください。32ビットのOfficeコードを記述している場合、コードは、条件付きコンパイル定数を除いて、以前のバージョンのOfficeと同じように機能します。互換性のある32ビットおよび64ビットのOfficeを作成する場合は、Win64を使用して定数をコンパイルします。
StrPtr、VarPtr、ObjPtrを使用する
これらの関数を使用して、文字列型、バリアント型、およびオブジェクト型のポインタ(メモリアドレス)を返します。
ダイナミックリンクライブラリの基礎知識
ダイナミックリンクライブラリ(DLL)は、別のモジュールまたはアプリケーションで使用できる関数とデータを含むモジュールです。
DLLは、エクスポート関数と内部関数の2つの関数を定義します。エクスポートされた関数は他のアプリケーションで使用でき、内部関数は内部でのみ使用されます。
Windows APIはDLLのセットであり、各DLLモジュールは外部モジュール用に異なる関数をエクスポートします。
Dllをロードする各プロセスは、Dllを仮想メモリアドレス空間にマップします。プロセスがDllを仮想アドレスにロードした後、改善されたプログラムはDllのエクスポート関数を呼び出すことができます。
VBA宣言API
まず、Microsoftの公式WebサイトでAPI関数プロトタイプを見つけてから、VBA構文規則に従って関数をインポートします。次の機能:
int MessageBox(
HWND hWnd,
LPCTSTR lpText,
LPCTSTR lpCaption,
UINT uType
);
API関数はC言語形式で定義されています。ポインタ型の場合はVBA長整数として定義され、セカンダリポインタの場合はAny型として定義されます。Office 2010以降、LongPtrは、32ビットおよび64ビットのポインタータイプとの互換性のために定義されています。
API関数には通常ASCIIとUnicodeの2つのバージョンがあり、エイリアスは特定のバージョンを指定します。UnicodeバージョンとWで終わるAPI関数を使用することをお勧めします。
Office 2010 以后定义方式:
'选择VBA变量和C语言字节一致的变量,如 C的int是4Byte等同于VBA的long。VBA7以后多了一个LongPtr类型,在32位为Long类型在64位为LongLong类型。
#if VBA7 Then
public declare ptrSafe Function MessageBox lib "user32.dll" alias MessageBoxW _
(byval hWnd as LongPtr,byval lpText as string,byval lpCaption as string, byval uType as long) as long
#else
public declare Function MessageBox lib "user32.dll" alias MessageBoxW _
(byval hWnd as Long,byval lpText as string,byval lpCaption as string, byval uType as long) as long
#end if
'上面定义一个Unicode版本的API,同时能兼容各个版本的Office。
グループに参加して、一緒にコミュニケーションをとることができます:794568082。