Google Spreadsheet の googletranslate 関数の代わりに LanguageApp を使うワークシート関数を作ってイケてる翻訳ができるようにする

# イケてない googletranslate 関数を使いたくない

[Google Spreadsheet で使えるワークシート関数 googletranslate](https://support.google.com/docs/answer/3093331?hl=ja)、便利といえば便利です。でも、翻訳がイケてないと思うんです。

ではどれくらいイケてないかを確認するために https://translate.google.com/ と Google Spreadsheet の googletranslate 関数で翻訳した結果を比較してみることにします。また、これらの機械翻訳と人力による翻訳も比較してみましょう。

## GPL v3 冒頭の文章で比較してみる

一つの例として GPL v3 https://www.gnu.org/licenses/gpl-3.0.en.html 冒頭の下記の文を使用します。

> The GNU General Public License is a free, copyleft license for software and other kinds of works.
> 
> The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too.


### 人力による日本語訳

この英文の日本語訳は下記ページにあり、次のように訳されています。
https://www.ipa.go.jp/files/000028332.html

> GNU一般公衆利用許諾書は，ソフトウェアおよびその他の著作物について，フリーかつコピーレフトを主張するライセンスです。
> 
> ソフトウェアやその他の実用的な著作物を対象とするライセンスの大半は，著作物を多くの者で共有したり著作物を変更する自由を奪い去るように作られています。これに対して，GNU一般公衆利用許諾書は，プログラムの全てのバージョンを共有し変更できる自由を保証すること，すなわち，ソフトウェアがユーザ全てにとってフリーであり続けることを保証することを目的としています。私たちフリーソフトウェア財団（Free Software Foundation）は，私たちのソフトウェアの大半にGNU一般公衆利用許諾書を適用しています。他の著作物についても，作成者が私たちと同様の方法で著作物を公開するのであれば，GNU一般公衆利用許諾書を適用することが可能です。あなたのプログラムにも適用することができます。


ではこれを 次の２種類で機械翻訳して比べてみましょう。

- translate.google.com による翻訳
- Google Spreadsheet の googletranslate 関数による翻訳

### translate.google.com による翻訳
まずは translate.google.com から。ただし原文の "By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. " の部分は "program--to" を "program to" に置換しておきます。機械翻訳はこのような記述をうまく処理できない場合があるので、そういう場合は原文を調整すると翻訳結果が変わります。

実際にやってみるとこうなります。

> GNU一般公衆利用許諾契約書は、ソフトウェアやその他の種類の著作物に対する無料のコピーレフトライセンスです。
>
> ほとんどのソフトウェアやその他の実用的な作品のライセンスは、作品の共有や変更の自由を奪うように設計されています。 対照的に、GNU一般公衆利用許諾契約書は、プログラムのすべてのバージョンを共有したり変更したりする自由を保証することを目的としています。 フリーソフトウェア財団は、当社のソフトウェアのほとんどにGNU一般公衆利用許諾契約書を使用しています。 それはその著者によってこのようにリリースされた他の作品にも適用されます。 あなたもあなたのプログラムにそれを適用することができます。
> (2018/04/07時点の動作)

IPAのサイトの日本語訳に比べてイケてない部分はあれども、それなりに適切な日本語が出力されていると思います。ただし、最新の翻訳内容は上記とは違うかもしれません。[現在の翻訳内容はこちらで確認できます。](https://translate.google.com/#view=home&op=translate&sl=en&tl=ja&text=The%20GNU%20General%20Public%20License%20is%20a%20free%2C%20copyleft%20license%20for%20software%20and%20other%20kinds%20of%20works.%0A%0AThe%20licenses%20for%20most%20software%20and%20other%20practical%20works%20are%20designed%20to%20take%20away%20your%20freedom%20to%20share%20and%20change%20the%20works.%20By%20contrast%2C%20the%20GNU%20General%20Public%20License%20is%20intended%20to%20guarantee%20your%20freedom%20to%20share%20and%20change%20all%20versions%20of%20a%20program%20to%20make%20sure%20it%20remains%20free%20software%20for%20all%20its%20users.%20We%2C%20the%20Free%20Software%20Foundation%2C%20use%20the%20GNU%20General%20Public%20License%20for%20most%20of%20our%20software%3B%20it%20applies%20also%20to%20any%20other%20work%20released%20this%20way%20by%20its%20authors.%20You%20can%20apply%20it%20to%20your%20programs%2C%20too.)


### Google Spreadsheet の googletranslate 関数による翻訳
続いて Google Spreadsheet の googletranslate 関数で翻訳してみると、どうなるでしょうか。

> GNU一般公衆利用許諾契約書は、ソフトウェアと作品の他の種類の自由、コピーレフトライセンスです。
>
> ほとんどのソフトウェアおよびその他の実用的な作品のライセンスは、作品を共有したり変更し、あなたの自由を奪うように設計されています。これとは対照的に、GNU一般公衆利用許諾契約書を共有し、それはすべてのユーザーのためのフリーソフトウェアのまま確認するために、プログラムのすべてのバージョンを変更するには、あなたの自由を保証することを意図しています。私たちは、フリーソフトウェア財団、私たちのソフトウェアのほとんどのGNU一般公衆利用許諾契約書を使用します。それは、その著者がこの方法を発表し、他の作業にも適用されます。あなたも、あなたのプログラムに適用することができます。
> （2018/04/07時点の動作）

なんか微妙ですねえ。読んでいて辛くなる部分が目立ってきました。

このように、便利なようで微妙なところが残る Google Spreadsheet の google translate 関数ではなく、translate.google.com の翻訳品質を Google Spreadsheet でも使えると便利ですよね？

# Google Apps Script の LanguageApp なら translate.google.com と同等の品質が得られます。

Google Apps Script で、このように実行してみます。これは翻訳結果をログに出力するだけのコードです。

```javascript
var originalString = "The GNU General Public License is a free, copyleft license for software and other kinds of works." +
      "The licenses for most software and other practical works are designed to take away your freedom " +
      "to share and change the works. By contrast, the GNU General Public License is intended to guarantee " +
      "your freedom to share and change all versions of a program to make sure it remains free software " +
      "for all its users. We, the Free Software Foundation, use the GNU General Public License for most of " +
      "our software; it applies also to any other work released this way by its authors. You can apply it " +
      "to your programs, too.";


function testrun() {
  Logger.log(
    LanguageApp.translate( originalString, "en", "ja" )
  );
}
```

するとログにはこんな出力が出ました。

> GNU一般公衆利用許諾契約書は、ソフトウェアやその他の種類の著作物に対する無料のコピーレフトライセンスです。
>
ほとんどのソフトウェアやその他の実用的な著作物のライセンスは、作品の共有と変更の自由を奪うように設計されています。対照的に、GNU一般公衆利用許諾契約書は、プログラムのすべてのバージョンを共有したり変更したりする自由を保証して、すべてのユーザにとってフリーソフトウェアであることを保証することを意図しています。フリーソフトウェア財団は、当社のソフトウェアのほとんどにGNU一般公衆利用許諾契約書を使用しています。それはその著者によってこのようにリリースされた他の作品にも適用されます。あなたもあなたのプログラムにそれを適用することができます。

LanguageApp を使えば translate.google.com の結果に近い結果になることが分かりました。では、これをワークシート関数として使えるようにしましょう。

# Google Spreadsheet のワークシート関数として使えるようにする

実は特別なことは何もなく、Google Spreadsheet のスクリプトエディタで Gooogle Apps Script の関数を書くと、それはワークシートのセルからも実行できるようになります。

したがって、こんな関数を書いておけば、

```javascript
function translate(originalValue, translateFrom, translateTo) {
  if ( originalValue.length > 0 ) {
    return LanguageApp.translate(originalValue, translateFrom, translateTo);
  } else {
    return '';
  }
}
```

こんな風にワークシート側から使えるわけですね。(※コードは2019/1/26にアップデートしています。このワークシート関数を作業用にたくさん貼り付ける場合を想定し、翻訳したい文字列が実在する場合だけ翻訳結果を返すようにしました)

<img width="1027" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/149350/b0116fb0-2d56-177a-02db-1baa3cfc9d78.png">


これは下記の３段階の手順で作ります。(※この部分は2019/1/26に追記したため、記事を最初に投稿した時点とは翻訳文字列の内容が違う点にご注意ください)

1.スプレッドシートの「ツール」メニューから「スクリプトエディタ」を選びます
![image.png](https://qiita-image-store.s3.amazonaws.com/0/149350/64ab2ddd-50c7-6d97-0fef-fc7d87e0df24.png)

2.スクリプトエディタにコードを貼り付けて保存します
![image.png](https://qiita-image-store.s3.amazonaws.com/0/149350/47ed3489-c1f1-7dcb-1f9c-f316c8d800ae.png)

保存するときは、プロジェクト名は適切につけましょう。例えば、もとのスプレッドシートに "Translate Helper" のような名前を付けて使うとしたら、スクリプトエディタでは "Translate Hepler 向けスクリプト" のように命名したりするとよいでしょう。

3.動作確認します
![licecap.gif](https://qiita-image-store.s3.amazonaws.com/0/149350/94dfb125-6b96-80c1-b519-4a8b353a4ccb.gif)


# googletranslate関数でも、自作の関数でも、翻訳結果を出力したいセルに計算式を貼り付けるのは地味にめんどくさいです……

そういう場合は、次の実装を行ってみてください。
https://qiita.com/kazinoue/items/c0f974de716ab7db7b83

これはA列に入力すると自動的にB列に翻訳結果を出力する仕組みを提供します。ワークシートに対するonEdit()イベントで動作し、入力されたA列のセルに対応する翻訳結果をB列に出力しますので各セルに計算式を貼り付ける必要はありません。


# 利用上の注意について

Google Apps Script ではスクリプトから利用する機能についての、１日あたりの実行回数等に制約があります。使いすぎると制限にひっかかる場合がありますのでご注意ください。


# 指定可能な言語一覧は？

この方法で指定可能な言語コードは、たぶんこの一覧の通りです。
https://cloud.google.com/translate/docs/languages

この一覧には、次のように遷移すると到達できます。

|順番|URL|
|---|---|
|1|Google Apps Script の LanguageApp の説明を開く。<br>https://developers.google.com/apps-script/reference/language/language-app|
|2|"A list of language codes is available here." の "here" のリンク先に移動する。<br>https://cloud.google.com/translate/docs/translating-text#language-params|
|3|Translation API の説明ページで「テキストの翻訳」の項目が開き、「translations 配列には、リクエストされた target 言語（de: ドイツ語）に翻訳された 2 つの translatedText フィールドが含まれます。翻訳は、リクエスト内の対応するソースの配列と同じ順序で表示されます。」の説明箇所 の "target" のリンク先に移動する。<br>https://cloud.google.com/translate/docs/reference/translate#body.QUERY_PARAMETERS.target|
|4|Translation API の説明ページで "translate" の説明が開き、API の Query Parameter "target" の説明部分、"Required The language to use for translation of the input text, set to one of the language codes listed in Language Support." の "LanguageSupport" のリンク先に移動する。<br>https://cloud.google.com/translate/docs/languages|
|5|Translation API の説明ページで「言語のサポート」の項目が開き、目的のリストに到達できる。 |


本来は、Google Apps Script の LanguageApp の説明のところから最終的なページに到達できるべきのような気がしますが、これで目的の一覧は手に入ったので、この一覧の範囲で利用してみてください。