【VBA×C#】VBAで漢字をひらがな/ひらがなを漢字に変換する

漢字をひらがな/カタカナに変換したり、ひらがな/カタカナを漢字に変換したりしたい場合、Excel VBAであればApplicationオブジェクトのGetPhoneticメソッドを使うことで漢字からカタカナに変換することはできますがその逆はできません。また、Excel以外のVBAでは利用できないためAccessやそれ以外のアプリケーションのVBAでは変換することすらできません。

WindowsにはMicrosoft IMEを使用した言語処理操作を行うためのIFELanguageインターフェイスというAPIが存在しており、本ページではこのインターフェースを利用して漢字⇔ひらがな変換処理を実現させる方法を紹介していきます。WindowsAPIのインターフェースはVBAでは直接アクセスすることが出来ないため、C#でexeファイルを開発して処理の一部として組み込ませます。これによりIFELanguageインターフェイスの機能をVBAから利用することが可能になります。

C#開発にはVisualStudioやVSCodeなどの専用のエディタをインストールする必要があるように思われがちですが、Windowsの標準機能としてC#コンパイラが用意されているため、メモ帳で書いたC#コードをコマンドプロンプトでコンパイルするだけで誰でも簡単に開発が可能です。

本ページではWindowsの標準機能のC#コンパイラ「csc.exe」を利用する想定のコード紹介となっています。メモ帳&コマンドプロンプトでC#開発する方法としてあわせて下記リンクも参照下さい。

 

漢字 ⇔ ひらがな変換処理

WindowsにはMicrosoft IMEを使用した言語処理の操作を行うためのIFELanguageインターフェイスというAPIが用意されています。このインターフェースを使うことで漢字をひらがなに変換したり、ひらがなを漢字に変換、文字列の形態素解析を行うなどの様々な言語処理を行うことができます。

しかし、VBAはWindowsAPIの"関数"を直接呼び出すことはできますが、インターフェースやクラス等を呼び出すことができません。この問題はインターフェースの呼び出しが可能なC#言語でexeファイルを開発し、VBAからそのexeファイルを実行させることで解決します。(他言語を使う手法もあります)

処理の大まかなフローとしては下記の流れになります。

① VBAからexeファイル実行
② exeファイルでIFELanguageインターフェイスを使った文字列変換処理を実行
③ 変換した文字列をテキストファイルに出力
④ VBAでテキストファイル内の文字列を読み込み

 

IFELanguageインターフェイスの機能としてはGetPhoneticメソッドを使うことで漢字→ひらがな変換GetConversionメソッドを使うことでひらがな→漢字変換を行うことができます。

処理にはIMEを利用しているため「大和(やまと)」や「日和(ひより)」のような熟字訓であっても、キーボード入力時の変換で出るものであれば基本的には変換可能です。ただし、ひらがな→漢字変換で「せんせい(先生,宣誓,先制)」のような同音異義語が存在する場合はスペースキーで変換する際に一番初めに変換されるものが取得されます。(必要であれば任意でIMEのカスタマイズを行ってください)

 

サンプルコード

以下ではIFELanguageインターフェイスの機能を使ったC#コード、及びそのコードから生成されたexeファイルをVBAから呼び出すことで、指定の文字列に対してひらがな⇔漢字​​を変換するためのサンプルコードです。C#コードのコンパイルはWindows標準装備のC#コンパイラ「csc.exe」を使い、exeファイル名は「ConverrtKanaKanji.exe」を想定しています。
 

C#コード

下記はIFELanguageインターフェイスを使って、ひらがな⇔漢字​​を変換するためのC#コードです。VBAから入力される3つの引数(変換文字列結果出力先パス変換タイプ)をもとに文字列の変換を行うためのコードです。各引数は下記の文字列(String型)データが入力される想定です。

変換文字列  ひらがなもしくは漢字の文字列
結果出力先パス:変換結果をVBAに渡すための一時的なテキストファイルのパス
変換タイプ  :漢字→ひらがな変換の場合は"ToKana"、ひらがな→漢字変換の場合は"ToKanji" 

 

using System;
using System.Runtime.InteropServices;
using System.IO;

[ComImport]
[Guid("019F7152-E6DB-11d0-83C3-00C04FDDB82E")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IFELanguage {
    int Open();
    int Close();
    int GetJMorphResult(uint dwRequest, uint dwCMode, int cwchInput, [MarshalAs(UnmanagedType.LPWStr)] string pwchInput, IntPtr pfCInfo, out IntPtr ppResult);
    int GetConversionModeCaps(ref uint pdwCaps);
    int GetPhonetic([MarshalAs(UnmanagedType.BStr)] string @string, int start, int length, [MarshalAs(UnmanagedType.BStr)] out string result);
    int GetConversion([MarshalAs(UnmanagedType.BStr)] string @string, int start, int length, [MarshalAs(UnmanagedType.BStr)] out string result);
}

internal class Program {
  [STAThread]
  static void Main(string[] args) {

    if(args.Length != 3 ){
        Console.WriteLine("Arguments Error");
        Environment.Exit(0);
    }

    string sReturn;

    //引き数を変数に格納
    string sKanji = args[0];
    string sKana = args[0];
    string sPathTxt = args[1];
    string sType = args[2];

    IFELanguage IFELang = null;
    try {
        IFELang = Activator.CreateInstance(Type.GetTypeFromProgID("MSIME.Japan")) as IFELanguage;
        IFELang.Open();
        
        if( sType == "ToKana" ){
            //漢字→かな
            IFELang.GetPhonetic(sKanji, 1, -1, out sKana);
            sReturn = sKana;
            System.Console.WriteLine(sKana);
        } else if ( sType == "ToKanji" ) {
            //かな→漢字
            IFELang.GetConversion(sKana, 1, -1, out sKanji);
            sReturn = sKanji;
            System.Console.WriteLine(sKanji);
        } else {
            sReturn = "";
        }

        //テキスト出力
        File.WriteAllText(@sPathTxt, sReturn);
    } finally {
        if(IFELang != null){
            IFELang.Close();
        }
    }
  }
}

 

  VBAコード

VBAコードではC#で作成したexeファイルに引数として値を渡し、テキストファイル経由で変換結果を受け取るという処理を行います。コード内の定数「EXE_PATH」にはC#で作成したexeファイルのフルパス、定数「TXT_PATH」には結果の受け渡しをするための一時的なテキストファイルのフルパスをそれぞれ入力して下さい。(いずれも定数ではなく動的に取得したパスに変更しても問題ありません)

上記の値を変更後「main関数」を実行することで「sWord1」をかな→漢字変換、「sWord2」を漢字→かな変換します。任意の文字列に書き換えれば、その文字列に対してかなと漢字の変換も可能です。

Option Explicit

'変換タイプ
Enum CONV_TYPE
    TO_KANJI = 1    'かな→漢字
    TO_KANA = 2     '漢字→かな
End Enum

'------------------------------------------------------------------
'-  メイン処理
'------------------------------------------------------------------
Sub main()

    Dim sWord1 As String
    Dim sWord2 As String
    Dim sKanji As String
    Dim sKana As String
    Dim sMsg As String
    
    'かな→漢字変換
    sWord1 = "きさらぎ"
    sKanji = Convert(sWord1, TO_KANJI)
    
    '漢字→かな変換
    sWord2 = "五月雨"
    sKana = Convert(sWord2, TO_KANA)
    
    sMsg = "かな:" & sWord1 & " → " & "漢字:" & sKanji & vbLf & _
           "漢字:" & sWord2 & " → " & "かな:" & sKana
    
    Call MsgBox(sMsg)

End Sub
'------------------------------------------------------------------
'-  かな→漢字/漢字→かな変換を行う
'-      sWord   :変換対象文字列
'-      lType   :変換タイプ
'-      戻り値  :変換後文字列
'------------------------------------------------------------------
Private Function Convert(ByVal sWord As String, ByVal lType As CONV_TYPE) As String

    'exeファイルパス...
    Const EXE_PATH As String = "C:\...\ConverrtKanaKanji.exe"
    Const TXT_PATH As String = "C:\...\temp.txt"
    
    Dim oWSH As Object
    Dim oFSO As Object
    Dim sCmd As String
    Dim sType As String
    Dim sRet As String
    
    Set oWSH = CreateObject("WScript.Shell")
    Set oFSO = CreateObject("Scripting.FileSystemObject")
    
    'exeファイルの結果受け取り用テキストファイルの作成
    Call oFSO.CreateTextFile(TXT_PATH)
    
    '変換タイプの設定
    If lType = TO_KANA Then
        sType = "ToKana"
    ElseIf lType = TO_KANJI Then
        sType = "ToKanji"
    End If
    
    'コマンド作成
    sCmd = EXE_PATH & " " & sWord & " " & TXT_PATH & " " & sType
    
    'exe実行
    Call oWSH.Run(sCmd, 0, True)
    
    'テキストファイルからexeファイルの結果読み込み
    sRet = ImportFileText(TXT_PATH)
    Convert = sRet
    
    Call Kill(TXT_PATH)
    Set oWSH = Nothing
    Set oFSO = Nothing
    
End Function
'------------------------------------------------------------------
'-  指定のテキストファイル内の文字列を読み込む
'-      sPathFile   :テキストファイルのフルパス (UTF-8)
'-      戻り値      :ファイル内のテキスト
'------------------------------------------------------------------
Private Function ImportFileText(ByVal sPathFile As String) As String

    Dim oADO As Object
    Dim sRet As String
    
    Set oADO = CreateObject("ADODB.Stream")
    With oADO
        .Charset = "UTF-8"
        .Open
        .LoadFromFile sPathFile
        sRet = .ReadText
        .Close
    End With
    Set oADO = Nothing
    
    ImportFileText = sRet
    
End Function

 

まとめ

今回はC#を使ってVBAの処理の中でかなと漢字を変換する方法についての解説でした。
WindowsにはIFELanguageインターフェイスのような汎用的なインターフェースがいくつも用意されています。これらインターフェースはVBAから直接アクセスすることはできませんが、C#などの別言語を経由させることでVBAの処理の一部として利用することができるようになり、VBAだけでは実現できなかった様々な処理を実現することができるようになります。

C#は専用の環境をインストール等する必要があるように感じられますが、VBScriptやバッチファイルと同じようにメモ帳だけで開発可能な言語です(別途コマンドプロンプトからのコンパイルは必要ですが)。メモ帳でC#開発する方法は下記にまとめているので合わせて参照ください。

 

 関連書籍

C#,Excel,VBA,Windows API