背景
これは「自由研究室 AIRS-Lab」の Advent Calendar、22日目の記事です。
C# で DeepL API を使った翻訳ツールを作った私だったが、VBA でも同様のことができないか?との要請があり、いったんは難しいのじゃないかと諦めかけたが、よくよく考えたら難しい理由がわからなかったので、なんとなく調べたらできるようになった。せっかくなので、記事としてまとめることとした。そんな感じ。
C#の記事はこちら↓
C#)DeepL API で翻訳した結果をボイスロイドにしゃべってもらいたい!(1)
C#)DeepL API で翻訳した結果をボイスロイドにしゃべってもらいたい!(2)
やりたいこと
Excel VBA で DeepL API を使って翻訳したい。
【最終的な完成イメージ】
DeepL
DeepL API 認証キーの取得
DeepL API を利用するには、認証キーを取得する必要がありますので、事前に準備を済ませておきましょう。(参考)
Excel
Excel シート
このような感じでソーステキストの入力欄と翻訳結果の表示欄を作りましょう。
VBA
では、VBAを書いていきましょう。
参照設定
まずは参照設定をしておきます。「Microsoft XML, v6.0」のチェックを入れておきましょう。
オブジェクト:Sheet1
Worksheet_Change()
ワークシートのチェンジイベントに、ソーステキストに入力されたら翻訳結果をクリアする処理を組み込んでおきます。今回は面倒だったのでセル番地を直書きしちゃってます。
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Address(False, False) = "B3" Then
Range("D3").ClearContents
End If
End Sub
オブジェクト:Module1
標準モジュールを追加し、メインのコードを書いていきます。
認証キー
認証キーを定数として宣言しておきましょう。ここでは xxxx… としていますが、実際は取得した認証キーを書きます。
Const AUTH_KEY As String = "xxxxxxxxxxxx"
翻訳部分
ソーステキストを受け取って翻訳結果を返す処理です。HTTP REQUEST で文字列を送って結果を受け取っているだけですね。
Private Function deepL_translate(ByVal srcText As String) As String
Dim httpReq As XMLHTTP60
Set httpReq = New XMLHTTP60
Call httpReq.Open("POST", _
"https://api-free.deepl.com/v2/translate?auth_key=" & AUTH_KEY & _
"&text=" & srcText & "&target_lang=ja")
Call httpReq.send
Do While httpReq.readyState < 4
DoEvents
Loop
deepL_translate = httpReq.responseText
Set httpReq = Nothing
End Function
srcTextに「test」を渡して翻訳を実行すると、次のようなJSON形式で結果が返ってきます。
{"translations":[{"detected_source_language":"EN","text":"テスト"}]}
ここから「テスト」の部分を取り出す必要があります。
翻訳結果のテキスト抽出
本来はJSONをきちんと扱ってやった方がよいのでしょうが、面倒なので力業で処理しちゃいました。簡単に言うと、{"translations":[{"detected_source_language":"EN","text":"テスト"}]}
から、文字列 text
の位置を調べて、その位置を起点に必要な部分を取得しています。
Private Function getResultText(ByVal resText As String) As String
Dim pos As Long
Dim res As String
pos = InStr(resText, "text")
If pos > 0 Then
res = Mid(resText, pos + Len("text") + 3)
res = Left(res, Len(res) - 4)
Else
res = ""
End If
getResultText = res
End Function
メインルーチン
【翻訳実行】ボタンを押したときの処理です。上で作った処理を呼び出して最終結果を翻訳結果のセルに表示させています。【翻訳実行】ボタンにマクロを登録しておきましょう。
Public Sub 翻訳実行()
Dim srcText As String
Dim res As String
srcText = Range("B3").Value
srcText = WorksheetFunction.EncodeURL(srcText) '追記:「&」があると正しくテキストを渡せないと教えていただきました。
res = deepL_translate(srcText)
Range("D3").Value = getResultText(res)
End Sub
完成!?
これで完成です!
で、、英語 → 日本語翻訳はできたけど、日本語 → 英語翻訳は…? (WorksheetFunction.EncodeURL()を使ったらできました。)target_lang=ja
を target_lang=en
にすればいけるかも?と思いきや、実は日本語文字列を UTF-8 に変換してから渡す必要があります。この記事では触れませんが、興味のある方は「VBA UTF-8 変換」あたりでググってみてください。
参考にさせていただいたサイト
いつも隣にITのお仕事:エクセルVBAでHTTPリクエストをする最も簡単なプログラム