VBA(Access)アプリにMicroSoftのTranslator APIを使って翻訳機能付けてみた

こんにちは、えんぞーです。
普段から使ってる業務用アプリに「あ~、ここに翻訳ボタンあれば便利だな~・・コピペすんのめんどい」とか文句垂れていたので付けてみました。
とりあえず動いているので「同じような事したい人がいるかも知れない」ということで参考までにやり方書いときます。簡単に。
マイクロソフトの Access を使用しているので VBA での記述となります。
必要なもの
必要というか下準備みたいなものですが・・・。
Microsoft Azure Marketplace への登録
API 使うことになるのでWindows Azure Marketplaceへの登録が必要です。なんか難しそうな名前になってますけど WindowsLive アカウントで OK です。
持っている人はそのままログインして、持っていない人は無料登録しておきましょう。
Microsoft Translator API の登録
ここから翻訳 API の登録を行います。(もしくはログイン後の検索で探すと出てきます。)
下の画像のような画面になっているはずですので無料版で登録します。
(すでに押した後だったので画像は「キャンセル」と書いてますがこの位置です)

無料版は月に 2,000,000 文字の翻訳が可能となっています。
ちなみにログイン後のマイデータの項目で現在どのくらい使っているのかが確認できます。

アプリケーションの登録
ここからアプリケーションを登録します。
各項目の説明は次の通りです。
- クライアント ID
既にされている ID 以外であれば好きなの付けて大丈夫です。 - 名前
好きなの入れてください。 - 顧客の秘密
アプリケーションのパスワード。自分の好きなパスワードにも出来ます。 - リダイレクト URI
この API では不要っぽいですが必須らしいので適当に「http://localhost/」とか入れておく。https じゃないと・・・とか言われますが無視して大丈夫です。 - 説明
お好きな説明を入れてください。空でも大丈夫です。
Translator API を使ってみる
ようやく本番です。
この API を使用する際の流れは、「access_token を取得する」→「翻訳する」という流れになるそうで。
まずは access_token を取得する為に指定された URL へ POST メソッドをつかってパラメーターを投げてやりましょう。
access_token 取得に必要な各種パラメーター
・リクエスト URL
https://datamarket.accesscontrol.windows.net/v2/OAuth2-13
・メソッド POST
・パラメーター
- grant_type
client_credentials - client_id
アプリケーションの登録時に指定したクライアント ID - client_secret
アプリケーションの登録時に取得した顧客の秘密 - scope
http://api.microsofttranslator.com
この部分を VBA でコードにしてみると
1Dim xmlHttp As Object 'HTTPリクエストオブジェクト
2Dim url As String 'リクエストを送るURL
3Dim strParam As String 'リクエストパラメータ
4Dim strRes As String '結果を受け取る変数
5Set xmlHttp = CreateObject("MSXML2.XMLHTTP")
6
7url = "https://datamarket.accesscontrol.windows.net/v2/OAuth2-13"
8
9strParam = "grant_type=client_credentials&client_id=クライアントID&client_secret=クライアントのパスワード(顧客の秘密)&scope=http://api.microsofttranslator.com"
10
11With xmlHttp
12 .Open "POST", url, False
13 .setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
14 .send (strParam)
15 strRes = .responseText
16End With
17
18MsgBox strParam
これを実行すると JSON 形式の返り値があるのであとはそこから「access_token」を抜き出します。
ポイントとすれば RepuestHeader には「application/x-www-form-urlencoded」を指定する所でしょうか。
あと、顧客のパスワード部分ですが最初に決められたものを使う場合は注意して下さい。文字列の中に「=」とか入っているとそれを考慮した書き方しないといけないかも知れません。
なんか上手くいかない・・・って言う場合はパスワードを英数字のみにして試して見てください。
JSON 形式から「access_token」を取り出す
返り値取得出来たならあとは好きに料理してくれれば OK って感じですがずぼらな私の場合でご紹介。
JSON からの取り出しはそれように関数作っちゃいました。
1Function tokentype(jsonword As String) As String
2 'JSON渡すとaccess_token返す関数
3 Dim sc As Object
4 Dim strFunc As String
5 Dim objJSON As Object
6
7 Set sc = CreateObject("ScriptControl")
8
9 sc.Language = "JScript"
10
11 'jsonにパースする関数文字列
12 strFunc = "function jsonParse(s) { return eval('(' + s + ')'); }"
13 '関数を追加
14 sc.AddCode strFunc
15 '追加した関数を実行して、結果を変数に格納する
16 Set objJSON = sc.CodeObject.jsonParse(jsonword)
17
18 tokentype = objJSON.access_token
19
20 Set objJSON = Nothing
21 Set sc = Nothing
22
23End Function
これで「access_token」が入手出来たので、やっと翻訳作業に入れます。
翻訳してみる
翻訳は GET メソッドを使って行いました。
なにやら POST でも良いらしいっていうのも見た気がしますが GET でやって動いちゃったのでこれで良いです。
翻訳に必要なパラメーター
・リクエスト URL
http://api.microsofttranslator.com/V2/Http.svc/Translate
・メソッド GET
・パラメーター
- from
翻訳元言語のコード - to
翻訳先言語のコード - text
翻訳するテキスト
あと先程取得した access_token をリクエストヘッダに組み込んであげれば OK。
1'この例だと英語から日本語に翻訳
2url = "http://api.microsofttranslator.com/V2/Http.svc/Translate?from=en&to=ja&text=翻訳したい文"
3
4With xmlHttp
5 .Open "GET", url, False
6 .setRequestHeader "Authorization", "Bearer " & tokentype(strRes)'先述したJSON関数に最初の返り値をセットしたもの
7 .send
8 strRes = .responseText
9End With
リクエストヘッダに指定する際、”Authorization”をヘッダ名にして値に”Bearer “を入れてから access_token を入れると言うルールみたいです。
“Bearer”のあとに半角で 入っているので気を付けて下さい。
これで翻訳したものが返り値として帰ってきます。
後は自分の要望に合わせて翻訳メソッド自体を関数にしたりして自由に使えるかと思います。
私は単純に一行文の翻訳だけしたかったのでそのまま関数にして使ってます。

追記:日本語から英語へ翻訳するときの注意
コメント欄に頂いた質問(日本語 → 英語が文字化けしてしまう現象)が気になったので試してみました。KOJI さんありがとうございます^^
考えてみたら自分の場合「英 → 日」の翻訳しか必要なかったので「日 → 英」は試していませんでした。
結果、

見事に文字化けしました。
文字化けすると言う事は渡す文字列のエンコードに問題あるので UTF-8 にエンコードして渡せば・・・と言うことで下記のページでまとめられているようにエンコードする関数を用意しました。
文字列を UTF-8 でエンコードするユーザー定義関数 | You Look Too Cool
注意点としては
VisualBasic エディタの設定をする必要があります。
ツール-参照設定-参照設定ダイアログで「Microsoft ActiveX Data Objects 2.8 Library」にチェックを入れます。
2.5 以上であれば動くようです。
参照設定が必要になるのでそこを忘れないようにしてください。
肝心のコードはありがたくそのまま使わせて頂きます。
1Function encodeUTF8(mytext As String) As String
2 Dim mystream As New ADODB.Stream
3 Dim mybinary, mynumber
4 With mystream
5 .Open
6 .Type = adTypeText
7 .Charset = "UTF-8"
8 .WriteText mytext
9 .Position = 0
10 .Type = adTypeBinary
11 .Position = 3
12 mybinary = .Read
13 .Close
14 End With
15 For Each mynumber In mybinary
16 encodeUTF8 = encodeUTF8 & "%" & Hex(mynumber)
17 Next
18End Function
この関数を使って再度試してみると・・・・

はい、正常に翻訳してくれました。
API に渡す文字列は UTF-8 にして渡す必要があるようです。
とりとめのないまとめ
1ヶ月で2,000,000文字もあれば十分過ぎるのでちょっと翻訳機能を組み込みたいっていう人にはオススメです。
今回はVBAでしたけど基本的にはどんな言語になっても一緒なので参考にはなるだろうと思います。
翻訳に頼らなくとも大丈夫なくらいの英語力があればそれで話は済むのですけれどもね(身も蓋も無い・・・)。