Amazonで商品を見るセール会場へ

Googleスライド│図形・表の文字を英語に翻訳する方法

Googleスライドの日本語を英語へ置き換えるGASの例です。

図形の文字、グループ内の図形、表の文字を対象にし、元資料から作った練習用コピーで試します。

目次

翻訳する対象と対象外

画像に埋め込まれた文字、グラフ、スピーカーノート、マスターやレイアウトの文字はこのコードの対象外です。

資料全体の見た目を保ったまま翻訳する機能ではありません。

条件結果
図形・テキストボックス空でない文字を対象にする
グループ子要素をたどり、図形・表を探す
表各セルを確認し、結合セルの先頭以外など文字列のないセルは飛ばす
画像・グラフ・ノートなど翻訳しない。別途確認が必要

要素の取得方法は公式のGroup、Table、TableCellを参照しています。

元資料を残してコピーを作る

練習用の資料に「資料を確認します」というテキストボックス、グループ化した図形、短い日本語を入れた表を作ります。

機密資料や顧客情報は使いません。

「ファイル→コピーを作成→プレゼンテーション全体」を使い、名前を「英語翻訳の練習コピー」などに変更します。

翻訳後に見比べられるよう、元資料は編集しません。

コピーのURLがhttps://docs.google.com/presentation/d/資料ID/editという形なら、/d/と/editの間が資料IDです。

元資料とコピーでIDが異なることを確認し、コピーのIDだけを以下のcopyPresentationIdへ設定します。

コードだけでコピーかどうかを判別することはできません。

書き換えずに対象件数を確認する

練習コピーの「拡張機能→Apps Script」でエディタを開き、Code.gsに次のコードを貼り付けて保存します。

const TRANSLATE_DEMO = Object.freeze({
  copyPresentationId: 'COPY_PRESENTATION_ID',
  apply: false,
  maxSlides: 10,
  maxTexts: 50,
  maxTextLength: 1000
});

function translateSlides() {
  if (!/^[A-Za-z0-9_-]{20,}$/.test(TRANSLATE_DEMO.copyPresentationId) ||
      TRANSLATE_DEMO.copyPresentationId === 'COPY_PRESENTATION_ID') {
    throw new Error('元資料ではなく、練習用コピーのIDを設定してください。');
  }
  const deck = SlidesApp.openById(TRANSLATE_DEMO.copyPresentationId);
  const slides = deck.getSlides();
  if (slides.length > TRANSLATE_DEMO.maxSlides) throw new Error('この練習は10枚までです。');
  const jobs = [];
  const skipped = [];
  function add(range, label) {
    if (!range) return; // 結合セルの先頭以外には文字列がない。
    const before = range.asString();
    if (!before.trim()) return;
    if (before.length > TRANSLATE_DEMO.maxTextLength) throw new Error('1対象1000文字までです。');
    jobs.push({range: range, before: before, label: label});
    if (jobs.length > TRANSLATE_DEMO.maxTexts) throw new Error('文字対象は50件までです。');
  }
  function visit(element, label, depth) {
    if (depth > 10) throw new Error('グループの入れ子が深すぎます。');
    const type = element.getPageElementType();
    if (type === SlidesApp.PageElementType.SHAPE) {
      add(element.asShape().getText(), label);
    } else if (type === SlidesApp.PageElementType.GROUP) {
      element.asGroup().getChildren().forEach((child, i) => visit(child, label + '/group' + i, depth + 1));
    } else if (type === SlidesApp.PageElementType.TABLE) {
      const table = element.asTable();
      for (let r = 0; r < table.getNumRows(); r++) {
        for (let c = 0; c < table.getNumColumns(); c++) {
          add(table.getCell(r, c).getText(), label + '/cell' + r + ',' + c);
        }
      }
    } else {
      skipped.push(label + ':' + String(type));
    }
  }
  slides.forEach((slide, i) => slide.getPageElements().forEach((element, j) => visit(element, 'slide' + (i + 1) + '/element' + j, 0)));
  console.log('対象=' + jobs.length + '、対象外=' + skipped.length + '、apply=' + TRANSLATE_DEMO.apply);
  if (!TRANSLATE_DEMO.apply) return;
  // すべての翻訳を取得してから書き換える。翻訳取得失敗なら本文は変更しない。
  const translated = jobs.map(job => {
    const after = LanguageApp.translate(job.before, 'ja', 'en');
    if (typeof after !== 'string' || !after.trim()) throw new Error('翻訳結果が空です。');
    return {...job, after: after};
  });
  if (translated.some(job => job.range.asString() !== job.before)) throw new Error('翻訳中に元の文字が変わりました。書き換えを中止します。');
  const completed = [];
  try {
    for (const job of translated) {
      job.range.setText(job.after);
      completed.push(job.label);
    }
  } catch (error) {
    console.error('書換済み=' + JSON.stringify(completed));
    throw new Error('途中で停止しました。練習用コピーを確認し、新しいコピーからやり直してください。原因: ' + error.message);
  }
  console.log('書換完了=' + completed.length + '。原文との照合とレイアウト確認が必要です。');
}

練習コードと模擬テストをダウンロードできます。

初期状態のapply:falseでは、資料を読み取って対象を数えるだけで、翻訳サービスへの呼び出しや本文の書き換えはしません。

コピーのIDを設定してtranslateSlidesを実行し、表示される権限が処理と一致するか確認します。

ログの「対象」「対象外」とapply=falseを見て、翻訳する要素が想定と合うか確かめます。

この練習の制限は10枚・文字対象50件・1対象1000文字です。

Googleのサービス割当とは別の、意図しない大量処理を避けるための制限です。

翻訳後の意味とレイアウトを確認する

練習コピーで翻訳を試す段階でapply:trueに変更し、translateSlidesを実行します。

LanguageApp.translateへ日本語の文字列を渡し、英語の結果を取得します。

LanguageAppの公式仕様を確認してください。

すべての翻訳結果を取得した後、取得中に元の文字が変わっていないか確かめてから書き換えます。

翻訳結果の取得に失敗した場合は、本文を書き換える前に停止します。

書き換えは一括で取り消せる処理ではありません。

setTextの途中で失敗すると、一部だけが英語になったコピーが残る場合があります。

TextRange.setTextは先頭側の文字スタイルを基準にするため、部分的な太字や文字色などの混在した装飾をそのまま保つとは限りません。

文字のはみ出し、改行、フォント、表の幅も確認します。

「資料を確認します」のような短文でも、文脈により翻訳結果は変わります。

固有名詞・数値・指示内容を原文と照合し、公開や共有の前に人が確認してください。

条件結果
対象が0件空文字か、画像・グラフなど対象外の要素か確認する
IDのエラーコピーのURLからIDを取り直し、資料へのアクセスを確認する
翻訳取得に失敗実行履歴を確認する。本文変更前に停止していればコピーの内容を照合する
途中で書き換え停止書換済みログとコピーを確認する。同じコピーで連続実行せず、元資料から新しいコピーを作る
元の状態へ戻したい元資料を使う。翻訳用コピーを本番資料と取り違えない

検証範囲と次の操作

2026年10月3日時点で、練習資料の実コピーとコピー前後の内容一致を確認しました。

翻訳コードの要素走査・対象制限・翻訳取得失敗・競合・途中書き込みはローカルの模擬テストで確認しており、実サービスのSlidesAppとLanguageAppを組み合わせた実行は未確認です。

スライド以外の作業はGoogleの目的別ガイドから探せます。

関連記事と旧資料

関連記事は目的が合うものから確認してください。

旧資料や外部ツールの説明は、本稿の練習コード・検証範囲と異なる場合があります。

次に学ぶ・作業環境を選ぶ

学習を続けたい方や、作業環境を整えたい方は、目的に合うガイドをご覧ください。

スプレッドシート・GASのおすすめ書籍

作業環境の作り方

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次