凛です。先日、勤めている病院の外国人患者さん向けに「よくある質問と回答」を英語にしてほしいと頼まれました。エクセルに日本語がずらっと100行以上。ひとつずつ翻訳サイトにコピペしていたら夜勤明けの眠気で意識が飛びそうになって、これは無理だと悟りました。そこでふと「GAS(Google Apps Script)で自動化できないかな」と思い立ったんです。調べてみたら、GASには翻訳専用の LanguageApp という機能が最初から備わっていて、スプレッドシートの1列をまるっと別の言語に変換できました。数十行のコードで100行が数秒。あのときの感動は忘れられません。今日はその方法を、私がつまずいたポイントも含めて丁寧にお伝えします。
GASのLanguageAppでシートの文章を一括翻訳する
「翻訳のためだけに有料APIを契約するのはちょっと…」という方でも大丈夫です。LanguageApp はGASの標準機能なので、追加のAPIキーも料金も不要。Googleアカウントとスプレッドシートさえあれば、今日から使えます。この記事では、まず1行だけ翻訳する基本から始めて、A列の日本語をB列に一括で英訳する実践パターン、さらに複数言語への同時翻訳やセルから直接呼び出すカスタム関数まで、段階を追って紹介していきます。
LanguageAppとは何か(まずは1文だけ翻訳してみる)
LanguageApp は、GASからGoogle翻訳の仕組みを呼び出すための標準サービスです。難しい準備は一切いらず、LanguageApp.translate() という命令ひとつでテキストを翻訳できます。
基本の書き方は引数3つだけ
まずは一番シンプルな例を見てみましょう。スプレッドシートを開いて「拡張機能」→「Apps Script」からエディタを開き、次のコードを貼り付けて実行してみてください。
// ※構文・API仕様を確認済み(GAS V8ランタイム向け)
function helloTranslate() {
// translate(翻訳したいテキスト, 元の言語, 訳したい言語) の順で指定する
const result = LanguageApp.translate('こんにちは', 'ja', 'en');
// 結果をログに出す(実行後「実行ログ」で確認できる)
Logger.log(result); // → Hello
}
LanguageApp.translate() の引数は次の3つです。順番を間違えると意図しない翻訳になるので、しっかり覚えておきましょう。
| 引数 | 役割 | 例 |
|---|---|---|
| 第1引数 | 翻訳したいテキスト | 'こんにちは' |
| 第2引数 | 元の言語コード | 'ja'(日本語) |
| 第3引数 | 訳したい言語コード | 'en'(英語) |
言語コードはISO 639-1という国際規格の2文字表記を使います。日本語は ja、英語は en、中国語(簡体字)は zh-CN、韓国語は ko、フランス語は fr といった具合です。
元の言語を自動判定させる
「元の言語が何か分からない」「日本語と英語が混ざっている」というときは、第2引数を空文字 '' にすると、GASが自動で言語を判定してくれます。
// ※構文・API仕様を確認済み(GAS V8ランタイム向け)
function autoDetectTranslate() {
// 第2引数を '' にすると元の言語を自動判定してくれる
const result1 = LanguageApp.translate('Bonjour', '', 'ja');
Logger.log(result1); // → こんにちは(フランス語を自動判定して日本語へ)
// 日本語混じりでも自動判定してくれる
const result2 = LanguageApp.translate('Thank you', '', 'ja');
Logger.log(result2); // → ありがとう
}
自動判定は便利ですが、短い単語だと言語の推測を外すこともあります。元の言語がはっきり分かっているなら、明示的に指定したほうが安定します。私は基本的に「元が何語か決まっている列」を扱うので、なるべく第2引数を書くようにしています。
A列の日本語をB列に一括で英訳する
ここからが本題です。1文だけなら翻訳サイトで十分ですが、何十行もある表を一気に処理できるのがGASの強みです。
読み込み・翻訳・書き戻しの3ステップ
一括処理の考え方はとてもシンプルで、次の3ステップに分かれます。
getValues()でA列の値をまとめて配列として読み込むmap()で各セルを翻訳するsetValues()で翻訳結果をB列にまとめて書き戻す
このパターンを覚えると、翻訳に限らずいろんな一括処理に応用できます。実際のコードがこちらです。
// ※構文・API仕様を確認済み(GAS V8ランタイム向け)
function translateColumnAtoB() {
// アクティブなシートを取得
const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
// データが入っている最終行を取得(1行目は見出しと仮定)
const lastRow = sheet.getLastRow();
// データが無ければ処理を終える
if (lastRow < 2) {
Logger.log('翻訳対象のデータがありません');
return;
}
// A2からA列の最終行までを2次元配列で読み込む([[値],[値]...] の形)
const source = sheet.getRange(2, 1, lastRow - 1, 1).getValues();
// 各行を翻訳して、書き戻し用の2次元配列を作る
const translated = source.map(function (row) {
const text = row[0]; // 1列分なので0番目が値
// 空セルは翻訳せずそのまま空を返す(ムダな呼び出しを避ける)
if (text === '' || text === null) {
return [''];
}
// 日本語から英語へ翻訳して、1列分の配列にして返す
return [LanguageApp.translate(text, 'ja', 'en')];
});
// B2から翻訳結果をまとめて書き込む(列数は1、行数はデータ数)
sheet.getRange(2, 2, translated.length, 1).setValues(translated);
}
このコードを実行すると、A列の日本語が一気にB列へ英訳されます。100行あっても、ボタン1回で完了です。
空セルをスキップする理由
コードの中で if (text === '' || text === null) として空セルを飛ばしているのには理由があります。空文字を翻訳しようとするとエラーにはなりませんが、翻訳呼び出しを1回消費してしまいます。後で説明するクォータ(1日あたりの上限)を節約するためにも、空セルは翻訳せずスキップするのが基本です。
また、getValues() と setValues() を使って「まとめて読んで、まとめて書く」のも大事なポイントです。1セルずつ getValue()/setValue() で読み書きすると、スプレッドシートへのアクセス回数が膨大になって、処理が何倍も遅くなります。読み書きはできるだけ1回にまとめましょう。この配列でまとめて扱う考え方は、別記事の配列操作の基本でも詳しく解説しています。
複数の言語へ同時に翻訳する
外国人の患者さんが増えてきて、英語だけでなく中国語・韓国語も欲しいと言われることがあります。そんなときは、1つのループで複数言語を横に並べて出力すると便利です。
隣り合う列に英・中・韓を並べる
A列の日本語を読み込んで、B列に英語、C列に中国語、D列に韓国語を並べて書き込む例です。
// ※構文・API仕様を確認済み(GAS V8ランタイム向け)
function translateMultiLanguages() {
const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
const lastRow = sheet.getLastRow();
if (lastRow < 2) return;
// 訳したい言語コードを配列にまとめておく
const targets = ['en', 'zh-CN', 'ko']; // 英語・中国語(簡体)・韓国語
// A2からA列の値を読み込む
const source = sheet.getRange(2, 1, lastRow - 1, 1).getValues();
// 各行について、言語ごとに翻訳した結果を横並びの配列にする
const output = source.map(function (row) {
const text = row[0];
// 空セルなら3言語分すべて空にして返す
if (text === '' || text === null) {
return ['', '', ''];
}
// targets配列を順に翻訳して [英, 中, 韓] の1行を作る
return targets.map(function (lang) {
return LanguageApp.translate(text, 'ja', lang);
});
});
// B2から3列分(英・中・韓)をまとめて書き込む
sheet.getRange(2, 2, output.length, targets.length).setValues(output);
}
targets という配列に翻訳先の言語コードを並べておけば、あとから言語を増やしたり減らしたりするのも簡単です。たとえばベトナム語 vi を加えたいなら ['en', 'zh-CN', 'ko', 'vi'] にして、書き込む列数を自動で targets.length に合わせているので、コードの他の部分を直す必要はありません。
見出し行も自動で作る
言語が増えると、どの列が何語か分からなくなります。見出し行も一緒にセットしておくと親切です。
// ※構文・API仕様を確認済み(GAS V8ランタイム向け)
function setLanguageHeaders() {
const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
// B1からD1に見出しをまとめて書き込む
const headers = [['英語', '中国語', '韓国語']];
sheet.getRange(1, 2, 1, 3).setValues(headers);
}
先にこの関数を実行して見出しを整えてから翻訳処理を走らせると、表として見やすく仕上がります。
セルから直接呼び出すカスタム関数にする
「スクリプトを実行する」という操作すら面倒に感じるときは、スプレッドシートのセルに直接 =myTranslate(A2,"en") と書いて翻訳できる「カスタム関数」を作れます。SUMやVLOOKUPと同じ感覚で使える自作の関数です。
カスタム関数の作り方
Apps Scriptエディタに次の関数を書くだけで、スプレッドシートのセルから呼び出せるようになります。
// ※構文・API仕様を確認済み(GAS V8ランタイム向け)
/**
* セルの文章を指定した言語に翻訳するカスタム関数
* @param {string} text 翻訳したいテキスト(セル参照でもOK)
* @param {string} targetLang 訳したい言語コード(例 "en")
* @return {string} 翻訳結果
* @customfunction
*/
function myTranslate(text, targetLang) {
// 空セルを指定された場合は空文字を返す
if (text === '' || text === null || text === undefined) {
return '';
}
// 元の言語は自動判定(第2引数を '')にして翻訳する
return LanguageApp.translate(text, '', targetLang);
}
保存したら、スプレッドシートのB2セルに次のように入力してみてください。
=myTranslate(A2,"en")
A2の日本語が英訳されてB2に表示されます。あとはB2をコピーして下方向にドラッグすれば、A列全体が翻訳されます。コードを実行する手間がなく、表計算の感覚だけで完結するのが魅力です。関数コメントの末尾に書いた @customfunction は、セルで関数名を入力したときに候補として表示させるための目印です。
カスタム関数の注意点(キャッシュと実行時間制限)
カスタム関数は便利ですが、いくつかクセがあります。知らないと「なんで更新されないの?」と戸惑うので、先に押さえておきましょう。
- 結果がキャッシュされる:同じ引数で呼び出すと、Googleは前回の結果を再利用します。つまり参照元のセルが変わらない限り、翻訳はやり直されません。これは処理を軽くするための仕組みですが、「関数のコードを直したのに結果が変わらない」ときはセルを一度編集し直すと再計算されます。
- 実行時間に制限がある:カスタム関数は1回あたり30秒以内に終わる必要があります。数百セルを一気に翻訳しようとすると時間切れになることがあるので、大量データにはこの後で紹介する「スクリプト実行型」のほうが向いています。
- 一部のサービスは呼び出せない:カスタム関数からは、ユーザー認証が必要な一部のサービスを呼べません。幸い
LanguageAppは問題なく使えます。
用途をまとめると、次のように使い分けるのがおすすめです。
| 使い方 | 向いている場面 | 注意 |
|---|---|---|
カスタム関数 =myTranslate() | 数行〜数十行を手軽に | キャッシュ・30秒制限あり |
| スクリプト実行型 | 数十行〜数百行を一括 | 実行ボタンが必要 |
失敗したポイントと回避策
ここからは、私が実際にやらかした失敗と、その回避策を正直にお伝えします。同じところでつまずかないよう参考にしてください。
機械翻訳ならではの精度の限界
LanguageApp はGoogle翻訳をベースにした機械翻訳です。日常会話や説明文はきれいに訳せますが、次のようなものは崩れやすいです。
- 固有名詞:人名・施設名・商品名などは、意図しないカタカナや別の単語に化けることがあります。
- 敬語のニュアンス:日本語の丁寧な言い回しは、英訳すると同じフラットな表現にまとまってしまいがちです。
- 専門用語:私の場合は医療用語で誤訳が出たことがありました。専門分野の文章は、翻訳後に必ず人の目で確認しましょう。
私は最終的に「機械翻訳でたたき台を作り、大事な部分だけ自分で直す」という使い方に落ち着きました。ゼロから翻訳するより何倍も速く、それでいて品質も保てます。
クォータ(1日あたりの上限)に注意
LanguageApp.translate() には、1日あたりに呼び出せる回数の上限(クォータ)があります。数百セル程度なら問題ないことが多いですが、数千セルを一気に処理しようとすると上限に達して、途中でエラーが出て止まってしまいます。上限はGoogleアカウントの種類(無料か有料か)によっても変わります。クォータ超過が出たときの一般的な対処はクォータ超過の対処法にまとめてあるので、あわせて読んでみてください。
大量データを扱うなら、次の3つの対策が有効です。
大量データで止まらないための3つの工夫
1. バッチに分けて少しずつ処理する
一度に全部翻訳せず、100行ずつなど区切って処理します。翻訳した分はその都度書き戻しておけば、途中で止まっても続きから再開できます。
// ※構文・API仕様を確認済み(GAS V8ランタイム向け)
function translateInBatches() {
const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
const lastRow = sheet.getLastRow();
if (lastRow < 2) return;
const source = sheet.getRange(2, 1, lastRow - 1, 1).getValues();
// 1行ずつ処理して、都度書き戻す(途中で止まっても安心)
for (let i = 0; i < source.length; i++) {
const text = source[i][0];
if (text === '' || text === null) continue; // 空はスキップ
const translated = LanguageApp.translate(text, 'ja', 'en');
// i行目の翻訳結果をB列に即書き込む(2 + i が実際の行番号)
sheet.getRange(2 + i, 2).setValue(translated);
// 呼び出しの間隔を少し空けて負荷を和らげる(0.2秒待つ)
Utilities.sleep(200);
}
}
この例では分かりやすさを優先して1行ずつ書き戻していますが、速さを重視するなら「50行ごとにまとめて書き戻す」形にすると、setValue() の回数を減らせてさらに高速になります。
2. Utilities.sleep() で間隔を空ける
Utilities.sleep(200) は0.2秒だけ処理を止める命令です。短時間に大量のリクエストを送ると制限に引っかかりやすいので、あえて少し間を空けることで安定させられます。
3. スプレッドシートのGOOGLETRANSLATE関数と併用する
実はスプレッドシートには、もともと =GOOGLETRANSLATE(A2,"ja","en") という翻訳関数が用意されています。GASのクォータを消費しないので、単純な翻訳ならこちらで済ませて、GASは「自動判定」「複数言語をまとめて処理」「他の作業と組み合わせる」といった凝った処理に絞る、という使い分けが賢いです。
| 方法 | クォータ消費 | 得意なこと |
|---|---|---|
LanguageApp(GAS) | あり | 自動化・複数言語・条件分岐 |
GOOGLETRANSLATE(関数) | GASのクォータは消費しない | 単純な列の翻訳をお手軽に |
自分でも作れるようになりたい方へ
ここまで読んでくださって、ありがとうございます。「翻訳のためだけに数十行のコードなんて自分に書けるかな」と思った方もいるかもしれません。でも、私も看護師でプログラミングは完全に独学。夜勤明けの眠い頭でも、少しずつ手を動かすうちに書けるようになりました。今日のコードをコピペして、自分のシートで動かしてみるだけでも大きな一歩です。もし体系的に学びたくなったら、独学に行き詰まる前に学べる環境を頼るのも近道ですよ。
Dive into Code(未経験からエンジニアを目指すプログラミングスクール)
関連記事
- GASの配列操作の基本:今回使った
map()や2次元配列の考え方を、基礎からじっくり解説しています。 - getValuesでシート処理を10倍速くする:1セルずつ読み書きせず、まとめて処理して高速化するテクニックをまとめました。
- GASのクォータ超過エラーの対処法:翻訳の大量処理でぶつかりやすい「上限エラー」の原因と回避策を解説しています。
この記事を書いた人:凛
2児2児のママで現役ナース。夜勤明けの細切れ時間を副業GASに投じ、月5〜8万円の副収入を継続中。「看護師でもコードは書ける」を合言葉に、家事育児とプログラミングを両立する等身大の情報を発信しています。
掲載コードは構文とAPI仕様を確認して載せていますが、お使いの環境に合わせて調整してください。