はじめに
文字列関係のWindows APIには、ANSI文字列版(関数名:????A)とUnicode文字列版(関数名:????W)があります。VBAからWindows APIを呼ぶ方法は、ネット上にもいくつか紹介されていますが、その多くがANSI文字列版についてのものです。
ここではUnicode文字列版の呼び出し方法について紹介したいと思います。
対象読者
- VBA環境からWindows APIを利用されている方
- VBAでUnicode対応のプログラムを作成されている方
なお、ANSI文字列版のWindows APIの呼び出し方法については、以下のMSDNなどを参照してください。
- MSDN:「Office VBA と Windows API」
必要な環境
- Windows VistaまたはWindows XP
- VBA開発環境(サンプルではExcelを使います)
Unicode版が必要になる文字
Unicode版のWindows APIが必要になるのは、シフトJISコードに割り当てられていないJIS補助漢字です。具体的には以下のような文字が該当します。
これらの文字は、シフトJISに文字コードが割り当てられていませんので、Unicode(UTF-16)を使用することになります。
VBAはUnicodeに対応しているか?
APIの説明に入る前に、VBAとUnicodeの関係について説明したいと思います。
MS-Officeアプリケーション(Excel、Word、Access等)はUnicodeに対応していますが、同様にVBAはUnicodeに対応しています。文字列型(String)も、内部的にUnicode(UTF-16)が使用されていて、文字列処理関数などはそのまま利用できます。文字コードから文字が得たければ ChrW関数、逆に文字から文字コードが得たければ AscW関数を使用します。
ただ、ここから少しややこしいのですが、VBA開発環境はUnicodeに対応していません。具体的には、VBE(Visual Basic Editor)で補助漢字は編集できません。文字を入力しようとしても、「?」などに変換されてうまくいきません。MsgBox関数やイミディエイトウィンドウ(Debug.Printメソッド)も補助漢字には対応していません。
このため、文字列型(String)に補助漢字を含む文字列をセットしたり、デバッグ時に内容をチェックしたりするのが面倒です。詳しくは、以下の2つのExcel VBA コードを実行し結果を比較してみてください。
'「千代田区麹町」を表示する Dim s As String Dim i As Integer '初期化 s = "千代田区麹町" Debug.Print "例1" '1文字ずつ文字コード(UTF-16)を表示する For i = 1 To Len(s) Debug.Print "U+" & Hex(AscW(Mid(s, i, 1))) Next i 'MsgBox()関数で表示(成功) MsgBox s 'イミディエイトウィンドウに表示(成功) Debug.Print s 'ワークシートのA1セルへ書き込み(成功) ThisWorkbook.ActiveSheet.Range("A1").Value = s
'「千代田区麹町」を表示する Dim s As String Dim i As Integer '初期化 s = "千代田区" & ChrW(&H9EB4) & "町" Debug.Print "例2" '1文字ずつ文字コード(UTF-16)を表示する For i = 1 To Len(s) Debug.Print "U+" & Hex(AscW(Mid(s, i, 1))) Next i 'MsgBox()関数で表示(失敗) MsgBox s 'イミディエイトウィンドウに表示(失敗) Debug.Print s 'ワークシートのA2セルへ書き込み(成功) ThisWorkbook.ActiveSheet.Range("A2").Value = s