最新の投稿

いろどり初級1/ 2課(Y02)

📋 更新履歴 2026.05.31 ページ作成. ▼ もっと見る 目次に戻る Y02S1 趣味は料理をすることです 趣味や好きなことについて、簡単に話すことができる Can talk in simple terms about your hobbies and favorite things to do. 動画 練習問題 語彙 (教師作成用 Google Formコピー ) (生徒用 Google Form ) 趣味は何ですか (教師作成用 Google Formコピー ) (生徒用 Google Form ) 文法 Y02G1 V-ることです Google Form Coming Soon Y02G2 V-るのが好きです (教師作成用 Google Formコピー ) (生徒用 Google Form ) スクリプト Y02S2 休みの日は何をしますか? 休みの日の過ごし方について、質問したり、質問に答えたりすることができる Can ask and answer questions about how you spend your days off. 動画 練習問題 (教師作成用 Google Formコピー ) (生徒用 Google Form ) 文法 Y02G3 【人】と【場所】でV-ます Google Form Coming Soon Y02G4 V1-て、V2 Google Form Coming Soon スクリプト Y02S3 スタッフ紹介 店や施設などに貼られているスタッフ紹介を読んで、家族や趣味などについて理解することができる Can read sta...

複数のスライドの内容をまとめて書き出す

GAS活用

プロンプトからスライドをAIで自動作成というのが話題ですが、反対にすでに作成したスライドの内容にさっと目を通したり、そこから教案やシラバスを作成したりしたい場合、どうしますか?

スライドファイルが一つだったらそれほどの手間ではないでしょうが、たくさんのスライドファイルがある場合いちいちスライドをひとつずつ開いたり、PDFに書き出したものを参照するのは面倒ですよね?

私はスライドを作成しながら授業展開を考えるので、1レッスン1スライドファイルという形式になっています。次に使う機会がある場合(いわゆる再利用)、そのスライドファイルを開いてちょっと変更したりしながら使っているのですが、まとめて30レッスン分のスライドの内容をまとめたい(そしてGeminiかChatGPTに改善点があれば聞いてみたい)と思い立ちました。そこで、登場するのがGAS (Google Apps Script)です。GASでフォルダーの中にあるスライドファイルの内容をGoogle Documentに一括に書き出して!と、Geminiさんにお願いしました。

私はスライドファイルをコースごとにフォルダにまとめて、さらに授業ごとにサブフォルダに入れてあるので、指定したフォルダ(親フォルダ)とサブフォルダに入っているすべてのスライドGoogle Documentに書き出してもらうことから始めました。もっと頑張れば画像も書き出せるかもしれませんが、テキスト(タイトルも含める)だけを書き出してもらうGASコードを作成しました。

次のコードをコピーして使えます。

注意: このスクリプトを実行する前に、コード内の 'フォルダーのID' を、対象のGoogleフォルダーのIDに書き換えてください。

(一定のファイル名を指定する場合は『GASコード2』を参照)

GASコード1:フォルダからスライドを書き出す
▼ 開く
function exportSlidesFromFolderAndSubfolders() {
  const folderId = '1F3-0ZtHRr2WraadUCMa2UX195kDR-kvn'; // 親フォルダのID
  const doc = DocumentApp.create('フォルダ内のスライド内容');
  const body = doc.getBody();

  const processedFolders = new Set();
  const foldersToProcess = [folderId];

  while (foldersToProcess.length > 0) {
    const currentFolderId = foldersToProcess.shift();
    if (processedFolders.has(currentFolderId)) continue;
    processedFolders.add(currentFolderId);

    try {
      const folder = DriveApp.getFolderById(currentFolderId);
      const files = folder.getFilesByType(MimeType.GOOGLE_SLIDES);
      while (files.hasNext()) {
        const file = files.next();
        processSlide(file, body);
      }
      const subfolders = folder.getFolders();
      while (subfolders.hasNext()) {
        foldersToProcess.push(subfolders.next().getId());
      }
    } catch (e) {
      Logger.log(`エラー: フォルダID ${currentFolderId} を見つけることができませんでした。` + e.message);
      body.appendParagraph(`エラー: フォルダID ${currentFolderId} の処理中に問題が発生しました。`)
          .setHeading(DocumentApp.ParagraphHeading.NORMAL_TEXT);
    }
  }
  Logger.log(`ドキュメントが作成されました: ${doc.getUrl()}`);
}

// スライドを処理し、ドキュメントに書き出すヘルパー関数(修正版)
function processSlide(file, body) {
  try {
    const presentation = SlidesApp.openById(file.getId());
    body.appendParagraph(`=== ${presentation.getName()} ===`)
        .setHeading(DocumentApp.ParagraphHeading.HEADING1);

    const slides = presentation.getSlides();
    slides.forEach((slide, index) => {
      const pageElements = slide.getPageElements();
      let titleFound = false;

      for (let i = 0; i < pageElements.length; i++) {
        const element = pageElements[i];
        if (element.getPageElementType() === SlidesApp.PageElementType.SHAPE) {
          const shape = element.asShape();
          if (shape.getShapeType() === SlidesApp.ShapeType.TEXT_BOX || shape.getShapeType() === SlidesApp.ShapeType.TEXT_BOX) {
            const text = shape.getText().asString().trim();
            if (text !== '') {
              body.appendParagraph(`スライド ${index + 1}: ${text}`)
                  .setHeading(DocumentApp.ParagraphHeading.HEADING2);
              titleFound = true;
              break; // タイトルが見つかったらループを抜ける
            }
          }
        }
      }
      if (!titleFound) {
        body.appendParagraph(`スライド ${index + 1}: タイトルなし`)
            .setHeading(DocumentApp.ParagraphHeading.HEADING2);
      }

      // テキストボックスのコンテンツを抽出
      for (let i = 0; i < pageElements.length; i++) {
        const element = pageElements[i];
        if (element.getPageElementType() === SlidesApp.PageElementType.SHAPE) {
          const shape = element.asShape();
          const text = shape.getText().asString().trim();
          if (text !== '') body.appendParagraph(text);
        }
      }
      body.appendHorizontalRule();
    });
  } catch (e) {
    Logger.log(`エラー: スライド ${file.getName()} (${file.getId()}) の処理中に問題が発生しました。` + e.message);
    body.appendParagraph(`エラー: スライド ${file.getName()} の処理中に問題が発生しました。`)
        .setHeading(DocumentApp.ParagraphHeading.NORMAL_TEXT);
  }
}

指定したフォルダーの中に他にもたくさんのスライドファイルがある場合、どうするか。私の場合、生徒と活動で使うスライドファイルとか、これはやらなかったスライドファイル、みたいなのもごちゃごちゃ入っていましたので、必要なスライドファイルの名前の前にIM01タイトル、IM02タイトル、のように、IM+数字を入れました。そして、IMで始まるタイトルのスライドファイルを番号順に書き出す、というGASコードを作りました。

注意: このスクリプトを実行する前に、コード内の 'フォルダーのID' を、対象のGoogleフォルダーのIDに書き換えてください。
GASコード2:IMスライドを番号順に書き出す
▼ 開く
function exportIMSlidesFromFolderAndSubfolders() {
  const folderId = 'フォルダーのID';
  const doc = DocumentApp.create('IMスライド内容の書き出し (番号順)');
  const body = doc.getBody();

  // 抽出したスライドの情報を保存する配列
  const imSlides = [];

  const processedFolders = new Set();
  const foldersToProcess = [folderId];

  // フォルダとサブフォルダを巡回してスライドを抽出
  while (foldersToProcess.length > 0) {
    const currentFolderId = foldersToProcess.shift();
    if (processedFolders.has(currentFolderId)) continue;
    processedFolders.add(currentFolderId);

    try {
      const folder = DriveApp.getFolderById(currentFolderId);
      const files = folder.getFilesByType(MimeType.GOOGLE_SLIDES);

      while (files.hasNext()) {
        const file = files.next();
        const fileName = file.getName();
        // ファイル名が "IM" で始まり、その後に数字が続くかチェック
        const match = fileName.match(/^IM(\d+)/);
        if (match) {
          const number = parseInt(match[1], 10);
          imSlides.push({ id: file.getId(), name: fileName, number: number });
        }
      }

      const subfolders = folder.getFolders();
      while (subfolders.hasNext()) {
        foldersToProcess.push(subfolders.next().getId());
      }
    } catch (e) {
      Logger.log(`エラー: フォルダID ${currentFolderId} を見つけることができませんでした。` + e.message);
      body.appendParagraph(`エラー: フォルダID ${currentFolderId} の処理中に問題が発生しました。`)
          .setHeading(DocumentApp.ParagraphHeading.NORMAL_TEXT);
    }
  }

  // 番号順にソート
  imSlides.sort((a, b) => a.number - b.number);

  // ソートされた順にスライドを処理
  imSlides.forEach(slideInfo => {
    processSlide(slideInfo.id, slideInfo.name, body);
  });

  Logger.log(`ドキュメントが作成されました: ${doc.getUrl()}`);
}

// スライドを処理し、ドキュメントに書き出すヘルパー関数
function processSlide(slideId, slideName, body) {
  try {
    const presentation = SlidesApp.openById(slideId);
    body.appendParagraph(`=== ${slideName} ===`)
        .setHeading(DocumentApp.ParagraphHeading.HEADING1);

    const slides = presentation.getSlides();
    slides.forEach((slide, index) => {
      const pageElements = slide.getPageElements();
      let titleFound = false;

      for (let i = 0; i < pageElements.length; i++) {
        const element = pageElements[i];
        if (element.getPageElementType() === SlidesApp.PageElementType.SHAPE) {
          const shape = element.asShape();
          if (shape.getShapeType() === SlidesApp.ShapeType.TEXT_BOX) {
            const text = shape.getText().asString().trim();
            if (text !== '') {
              body.appendParagraph(`スライド ${index + 1}: ${text}`)
                  .setHeading(DocumentApp.ParagraphHeading.HEADING2);
              titleFound = true;
              break;
            }
          }
        }
      }
      if (!titleFound) {
        body.appendParagraph(`スライド ${index + 1}: タイトルなし`)
            .setHeading(DocumentApp.ParagraphHeading.HEADING2);
      }
      for (let i = 0; i < pageElements.length; i++) {
        const element = pageElements[i];
        if (element.getPageElementType() === SlidesApp.PageElementType.SHAPE) {
          const shape = element.asShape();
          const text = shape.getText().asString().trim();
          if (text !== '') body.appendParagraph(text);
        }
      }
      body.appendHorizontalRule();
    });
  } catch (e) {
    Logger.log(`エラー: スライド ${slideName} (${slideId}) の処理中に問題が発生しました。` + e.message);
    body.appendParagraph(`エラー: スライド ${slideName} の処理中に問題が発生しました。`)
        .setHeading(DocumentApp.ParagraphHeading.NORMAL_TEXT);
  }
}

Office系のPowerPointだと、PowerPointを文書に書き出すと言う方法もありますが、それだと一つずつの作業となります。GASと同じくVBAを使えば可能だと思います。スライドはPowerPointだけどGASでやってみようかな、という人はGoogle Driveにアップロードして(設定でデフォルトで自動的にGoogle Slidesに変換されるようになっているはずですが、なっていない場合はGoogle Driveの設定で『自動的に変換』にチェックしてください。Google Driveで同期されている場合は自動で変換されません。アップロードが必要です。)やってみてください。

そして書き出されたDocumentをLM Notebookなどでまとめてもらうことも可能です。

参考になりましたでしょうか?皆さんがどのようにスライド管理(特にスライドのタイトル)をされているか分からないのですが、とりあえず文書に書き出したら生成AIサービスを利用して、その文書をアップロードして「添付書類を授業計画としてまとめて」「シラバスとしてまとめて」「各レッスンの目標と文型、トピックをまとめて」などのプロンプトでそれなりにまとまってくると思います。

こうしてGASが気軽に使えるようになったのは、すべて@8_toriさんのおかげです。感謝🙏

ラベル

こどもの日本語6 自動採点6 Gフォーム5 オンライン授業5 Google Slides4 Zoom4 eSIM4 gas4 イタリアの学校4 一時帰国4 継承語4 継承語教育4 Skype3 Viaggio in Giappone3 audible3 google apps script3 irodorigoi3 いろどり初級13 イタリアフリーランス3 一時帰国 SIM eSIM3 Appointlet2 Canva2 EduTech2 Jitsi2 Nihongo2 PearDeck2 Self Study Japanese2 Twitter2 nihongo tadoku2 tadoku2 いろどりまとめ2 イタリアの試験2 イタリアの高校2 イタリア国民投票2 イタリア語2 イタリア語学習2 スケジュール管理2 プライベートレッスン2 ポケットWiFi2 外国人2 旅行2 日伊語比較2 日本語教材2 正規表現2 絵本で日本語2 自動生成2 AIと教育1 Airalo1 BasicJapanese1 Blogger1 CanDoリスト1 ChatGPT1 ClassroomJapanese1 Easy Japanese1 Google Spreadsheet1 Google スライド1 Googleサービス1 Greeting1 Jamboard1 Japanese1 Jitsi meet1 Liveworksheet1 Mac1 Marugoto1 Microsoft Office1 MySOS1 NotebookLM1 Patente Internazionale1 PearDeck 使い方1 Permesso Internazionale di Guida1 SIM1 Sevilla1 Singer1 Transcript1 Travel Japanese1 URL作成1 WordPress1 Working Holiday Visa in Japan1 X.com1 X011 X031 X041 X051 X061 X071 X081 X091 X101 X111 X121 X131 X141 X151 Y011 Y021 Y041 Y051 Y061 Y071 Y081 Y111 Y121 Y131 Y151 Z041 Z121 Zoomキャンセル1 Zoomサブスク1 aggiustare1 amazon1 bollo elettronico1 chat lesson1 ehondenihongo1 font1 japanese number1 macchina da cucire1 manga1 marca da bollo1 numeri giapponesi1 omofoni1 omografi1 omonimi1 pedala1 portfolio1 portofolio1 rakuten1 referendum abrogativo1 referendum costituzionale1 vocabulary1 いろどりアクティビティ1 いろどりスライド1 いろどり中級1 いろどり教案1 いろどり生活の日本語1 さんふん1 さんぷん1 すうじ1 でき日1 どうおんいぎご1 まるごと1 みん日1 やさしい日本語1 よんふん1 よんぷん1 アフィリエイト1 アレルギー1 アンケート1 イタリアで子育て1 イタリアの博士課程1 イタリアの大学1 イタリアの税制1 イタリア保育園1 イタリア大学1 イタリア学校システム1 イタリア小学校1 イタリア幼稚園1 イタリア旅行1 イタリア選挙1 イタリア電車1 カメラオフ1 カンニング1 クイズ1 クラス分け1 グループチャット1 ゲーム1 コミュニケーション1 サクララウンジ1 ジャムボ1 スペイン1 スライドから書類に変換1 スライドショー1 スライド作成1 セビリア1 セビージャ1 チャット1 ツイート1 テク1 トピック1 ハーフ1 ヒースロー空港1 フォント1 フリートーク1 ブログ1 プラットフォーム1 プレゼンテーション1 プレビュー1 プレミアムエコノミー1 ペアデック1 ペダル1 ホテル1 ホワイトボード1 ポートフォリオ1 マイクオフ1 ミシン1 ミックス1 メンション1 ユーロ1 リンク作成1 レベルチェック1 レンタカー1 ワーホリ1 ワールドカレンシー1 一時帰国 ホテル Verifly1 一時帰国通信1 両替1 交流会1 人種1 位置表現1 便利な教材1 修理1 個人面談1 入国1 制限時間1 協働学習1 口頭試験1 同音異義語1 国際免許証1 家電1 差し込み印刷1 差別1 広告収入1 役割語1 役割語としてのわよ1 打ち上げ1 指示代名詞1 授業計画1 掲示板1 敬語1 文型対応表1 文法チェック1 新型コロナウイルス1 旅行会話1 日本語1 日本語アクティビティ1 日本語フォント1 日本語動詞の活用1 日本語支援1 日本語教案1 日本語教育1 書き起こし1 書く教材1 検疫措置1 検索1 水際対策1 海外WiFi1 海外スマホ1 海外旅行1 海外生活1 海外通信1 漢字1 無料教材1 生活TIP1 生活の日本語1 移住1 給食費1 絵本1 羽田空港1 自動化1 語彙1 1 道案内1 録画機能1 開発ツール1 陰性証明書1 電車1 飛行機遅延1 食べ物1 飲食店のおすすめ1 高速道路1
もっと見る

閲覧数の多い投稿

Irodori as Homework (X)

Twitterに指定の#や@を入れてもらうリンクの作り方(覚書)

いろどり教材でアクティヴィティ(スライドなど)のまとめ