振り返りフォームで学習を可視化する!これで新学習指導要領の評価も悩まない!【Google フォーム と Google スプレッドシート を GAS連携】

新学習指導要領の評価も悩まない!振り返りフォームで学習を可視化する!GAS連携!Google関連

Google フォーム と Google スプレッドシート を Google Apps Script(GAS)で連携して、授業の振り返りフォームを作成しました!これを使えば学習を可視化することができます!!

特に、「関心・意欲・態度」より変わった「学びに向かう力・人間性」の記録として非常に役立ちます。Google スプレッドシート を 振り返りフォーム として活用している学校もありますが、入力のしにくさ・ハードルを個人的に感じています

入力は Google フォーム、一覧表示は Google スプレッドシート とすることでよりスムーズに学習の記録を残していくことができます

2022年9月21日にバージョン2.0に更新し、複数授業対応、回答先のスプレッドシートと児童・生徒個別のスプレッドシートが連携されるようになりました(児童・生徒からの質問に回答・コメントしやすくなりました)。バージョン2.0では、児童・生徒がフォームに入力する前に、フォームの回答先のスプレッドシートを作成しておく必要があります。詳しくは後述の 16. 回答先のスプレッドシートの作成・選択 をご覧ください。

2022年9月24日に、児童・生徒の負担を減らすことを目的に「学んだことのアウトプット」を「振り返りの自由記述の入力」に統合した light版 を公開しました。light版 を活用したい方は、後述の 教員の使い方(セッティング) にて light版 を選択してください。

できるようになること

  • Google フォーム で生徒自身が学びを振り返ることができる
  • Google フォーム で入力した振り返りを生徒毎の個別のスプレッドシートにためていくことができる
    • 「学びに向かう力・人間性」の記録ができるようになる
    • Google フォーム で入力したものをスプレッドシートで生徒自身が振り返ることができる
  • 生徒の振り返りを Google スプレッドシート を通して教員がコメントしたりチェックしたりすることができる

これらによって、「主体的に学習に取り組む態度」、「思考・判断・表現」、「知識・技能」の3観点での観点別評価における、「主体的に学習に取り組む態度」の評価の材料とすることができます!

「主体的に学習に取り組む態度」とは、“単に継続的な行動や積極的な発言等を行うなど、性格や行動面の傾向を評価するということではなく”、下記の二点の側面から評価する必要があると、文部科学省の『児童生徒の学習評価の在り方について(報告)』に記述されています。

① 知識及び技能を獲得したり、思考力、判断力、表現力等を身に付けたりすることに向けた粘り強い取組を行おうとする側面

② ①の粘り強い取組を行う中で、自らの学習を調整しようとする側面

文部科学省(2019)『児童生徒の学習評価の在り方について(報告)』

つまり、「粘り強く学習に取り組もうとしている」ことと「自らの学習を調整しようとしている」ことを評価できる仕組みが必要であり、それがこのツールを用いることである程度可能になります

生徒の使い方

1. 振り返りフォームを開く

先生が Google Classroom 等で配布した振り返りフォームのリンクをクリックして、振り返りフォームを開きます。

なお、この振り返りフォームは繰り返し使うことで振り返りを蓄積していくことができるので、生徒はブラウザでブックマークしておくことをオススメします。

2. メールアドレス(Google アカウント)を入力

学校で使用している Google アカウント であるメールアドレスを入力します。

生徒自身のメールアドレスは、Google にログインしている状態であれば画面上部に記載されているのでそちらをコピペしたり、ブラウザの入力補助機能を使用すれば入力の手間も省けるでしょう。

メールアドレスの入力

3. 学籍番号の入力

全ての生徒で被らない、唯一無二(ユニーク)な番号を入力します。この番号がファイル名にも使用されます。

学籍番号の入力

4. 授業名の選択

授業名を選択します。なお、授業名の選択肢は教員によって変更することが可能です。

授業名の選択

5. 授業内容の入力

振り返りを行う授業の内容を入力します。

授業内容の入力

6. 3観点での振り返り

「主体的に学習に取り組む態度」、「思考・判断・表現」、「知識・技能」の3観点で選択して自己評価を行います。すべての授業で3観点すべてを扱っているわけではないのが現実だと思いますので、扱っていない場合は「ー:評価対象外」を選択します。

なお、各項目の文言は先生によって変更することが可能です。観点を増やしたり減らしたりすることは、スクリプト(プログラム)を変更する必要があるので、プログラミングができる方や挑戦したい方は後述する Google Apps Script(GAS)をいじってみてください。

3観点での自己評価

7. 振り返りの自由記述の入力

振り返りの自由記述を入力します。なお、文言(デフォルトでは「本日の授業における自分の取り組みで良かった点や今後の学習への改善点を挙げてみよう。」)は教員によって変更することが可能です。

本日の授業における自分の取り組みで良かった点や今後の学習への改善点を挙げてみよう。

8. 学んだことのアウトプット

学んだことをアウトプットします。アウトプットすることで、学んだことの定着が図れると思い、このような項目を用意しました。なお、文言や説明文は教員によって変更することが可能です。

2022年9月24日に、児童・生徒の負担を減らすことを目的に、本入力項目を削除して 7 の「振り返りの自由記述の入力」に統合した light版 を公開しました。light版 を活用したい方は後述の 教員の使い方(セッティング) にて light版 を選択してください。

本日の授業で得た学びや感じたことを表現しよう。本日学んだキーワードを2つ以上使用すること

9. 質問の入力(任意)

質問がある児童・生徒は、質問することができます。こちらの設問の入力は任意となっています。

質問の入力(任意)

10. ファイルのアップロード(任意)

授業で作成したファイルをアップロードすることが可能です。これで授業の振り返りが成果物でも行うことができるようになります。1ファイル100MB、5ファイルまでアップロードすることが可能です。こちらの設問の入力は任意となっています。

ファイルのアップロード(任意)

11. 送信

「次へ」をクリックすると、確認画面が表示されます。間違いがない場合は「送信」ボタンをクリックします。

12. スプレッドシートで振り返り内容の確認

振り返りフォームのオーナーである教員と共有されたスプレッドシートが、生徒一人につき1ファイル作成されます(生徒のアカウントでは Google ドライブ 上の「共有アイテム」で開くことができます)。このファイルは一度作成されれば、次回以降は追記されていきますので、振り返りを蓄積していくことが可能となります。

振り返りスプレッドシート

また、2022年9月21日に更新したバージョン2.0より、授業名毎にシートが分かれるようになったため、授業毎に振り返りが蓄積されます。

授業名毎にシートが分かれる

なお、生徒はこのスプレッドシートを編集することが出来ないようにしています。コメントを付けたり、コメントを返信したりすることは可能です。

スプレッドシートには、振り返りフォームで提出したファイルのリンクが入力されているので、成果物を見て振り返ることも可能です。一点注意が必要なのが、提出したファイル(スプレッドシートのリンクからアクセスできるファイル)は、生徒側からは編集することができないようにしています。もちろん、生徒自身のマイドライブにあるオリジナルのファイルは、生徒自身で編集することできます。

振り返りスプレッドシートに記載されているファイルのリンク

教員の使い方(セッティング)

1. 先生用のGoogleアカウントでログイン

先生用の Google アカウントで Google にログインします。

2. Google フォーム を Google ドライブ に コピー

次のURLにアクセスして Google フォーム を 自分(先生)の Google ドライブ にコピーします。各校種で異なる点は、フォーム内での「授業名」の選択肢が異なるということだけです。また、「授業名」の選択肢は、各学校の実態に合わせて変更することが可能です。

なお、コピーした Google フォーム の名前、場所も任意のものに変更することが可能です。

3. ファイルのアップロード先のフォルダの復元(作成)

2でコピーした Google フォーム を開き、「ファイルのアップロード先のフォルダが見つかりません」で「復元」をクリックします。この操作で、振り返りフォームでアップロードできるファイルのアップロード先のフォルダ(デフォルトでのファイル名「授業振り返りフォーム(File responses)」)を作成することになります。

なお、作成されたフォルダの名前、場所は任意のものに変更することが可能です。

4. Google スプレッドシート のテンプレートを Google ドライブ に コピー

次のURLにアクセスして Google スプレッドシート のテンプレートを 自分(先生)の Google ドライブ にコピーします。

light(アウトプットの入力項目がないバージョン)

5. コピーした Google スプレッドシート の名前の変更

4でコピーしたファイルを右クリックして、「名前の変更」を選択し、冒頭の文字列である「コピー 〜 」を削除してファイル名を「template_classSelfFeedbackv2.0」にします。もしくは、4でコピーしたファイルを開いて、画面左上のファイル名の冒頭の文字列である「コピー 〜 」を削除してファイル名を「template_classSelfFeedbackv2.0」にします。なお、light版の場合は末尾に「_light」が付加されます。

6. スプレッドシート の保存先のフォルダを Google ドライブ 上に作成

生徒一人につき作成されるスプレッドシートの保存先のフォルダを 自分(先生)の Google ドライブ 上に作成します。作成する場所とフォルダ名は任意です。自分が整理しやすい場所、フォルダ名にすると良いでしょう。

Google ドライブ 上でのフォルダの作成

7. 保存先フォルダのフォルダIDの取得

6で作成したスプレッドシートの保存先のフォルダのフォルダIDを取得します。フォルダIDは、フォルダを開いたURLの “folders/” 以降となります。メモ帳や Google Keep など、任意の場所にコピペして退避させておきます。なお、下記の画像内でのフォルダ名は「情報Iの振り返り」となっていますが、現在は複数科目・授業にも対応できるようになっているため、ご自身や先生方がわかりやすいフォルダ名にしていただいて構いません。

Google ドライブ 上でのフォルダのIDの取得

8. テンプレートファイルを保存先フォルダに移動

4でコピーした(つまり、5で名前を変更した)スプレッドシートのテンプレートファイルを6で作成した(つまり、7でファイルIDを取得した)フォルダに移動します。

テンプレートファイルを保存先フォルダに移動

9. スクリプトを開く

2でコピーした Google フォーム(振り返りフォーム)を開いて、右上の縦三点リーダーからスクリプトエディタを開きます。なお、“スクリプト エディタ” という選択肢は、ある程度画面(ウィンドウ)が大きくないと表示されないので、表示されない方は、画面(ウィンドウ)幅を広げてみてください。

スクリプトエディタを開く

10. スクリプトにフォルダIDをセッティング

7で取得したフォルダIDをスクリプトに貼り付け、「プロジェクタを保存」のボタンをクリックします。

スクリプトエディタでフォルダIDをセットしてプロジェクトを保存

11. スクリプトのトリガー画面を開く

スクリプト画面の左メニューから「トリガー」をクリックします。

スクリプト画面の左メニューから「トリガー」をクリック

12. 「トリガーを追加」画面を開く

画面右下の「トリガーを追加」ボタンをクリックします。

画面右下の「トリガーを追加」ボタンをクリック

13. トリガーの設定

「イベントの種類を選択」にて “フォーム送信時” 、「エラー通知設定」にて “1週間おきに通知を受け取る” を選択し、保存ボタンをクリックします。

「イベントの種類を選択」にて “フォーム送信時” 、「エラー通知設定」にて “1週間おきに通知を受け取る” を選択し、保存ボタンをクリック

14. Google アカウントの選択

スクリプトを実行する Google アカウント を選択します。つまり、自分(先生)のアカウントを選択します。

スクリプトを実行する Google アカウント を選択

15. スクリプトの追加の許可

今回のようなお手製のスクリプトを使用する場合、スクリプトの追加の許可が必要となります。ドメイン(職場の環境)によっては本手順は不要な場合があります。その場合は、本手順をスキップしてください。

14のあと、「このアプリは Google で確認されていません」という警告ウィンドウが表示されるので、左下の「詳細」をクリックします。

「このアプリは Google で確認されていません」という警告ウィンドウが表示されるので、左下の「詳細」をクリックする

次に「FormToSpreadsheet(安全ではないページ)に移動」をクリックします。

「FormToSpreadsheet(安全ではないページ)に移動」をクリックする

最後に、「FormToSpreadsheet が Google アカウントへのアクセスをリクエストしています」というウィンドウにて一番下の「許可」ボタンをクリックします。

「FormToSpreadsheet が Google アカウントへのアクセスをリクエストしています」というウィンドウにて一番下の「許可」ボタンをクリックする

16. 回答先のスプレッドシートの作成・選択

2022年9月21日に本ツールがバージョン2.0に更新されたことによって、この作業が必要となりました。やることは至って簡単です。児童・生徒が回答する前に、振り返りフォームの編集画面の「回答」タブから緑色のスプレッドシートのアイコンをクリックし、回答先のスプレッドシートを作成・選択(リンク)するだけとなります。

振り返りフォームの編集画面の「回答」タブから緑色のスプレッドシートのアイコンをクリックし、回答先のスプレッドシートを作成・選択(リンク)する

この作業をしておくと、回答先のスプレッドシートの一番右の列に児童・生徒個別のスプレッドシートのリンクが追加されることになり、児童・生徒から質問があった際にコメント・回答しやすくなります。

回答先のスプレッドシートの一番右の列に児童・生徒個別のスプレッドシートのリンクが追加される

回答先のスプレッドシートの「授業名」の列でフィルタをかければ授業ごとに質問の有無を確認したり、自己評価を確認したりすることもできます。成績を算出する時期には ピボットテーブル を活用するのも良いかもしれません。

少々イケていない点は、児童・生徒個別のスプレッドシートへのリンクは、スプレッドシートファイルの各シートのリンクではなく、あくまで「スプレッドシートファイル」へのリンクとなるため、シートタブで該当の授業をクリックする必要があります。これは、Google の仕様上、各シートへのリンクは生成できないために生じる手間となりますが、複数授業対応になったメリットを考慮すれば微々たるものではないかと考えています。

今後の予定

YouTube にて多くのコメントをいただいているのでバージョンアップしようと考えています。まずは質問してくれた児童・生徒のスプレッドシートにすぐアクセスできるような仕組みの実装を予定しています。2022年9月21日にバージョン2.0を公開し、回答先のスプレッドシートから簡単に児童・生徒のスプレッドシートにアクセスできるようになりました。また、複数授業にも対応できるようにしました。

ぜひ、使ってみた感想や追加での要望等があればお気軽にコメント・問い合わせ等でご連絡いただけると嬉しいです。

〜バージョン1の動画〜

〜バージョン2の動画〜

コードの公開

通常版

/*
Copyright (c) 2022 alf
Released under the MIT license
*/
// フォルダIDとテンプレートファイル名を定義(指定)
const FOLDER_ID = 'スプレッドシートを保存したいフォルダIDを入力してください';    // 振り返りのスプレッドシートを保存したいフォルダのID
const TEMPLATE_FILE_NAME = "template_classSelfFeedbackv2.0";   // テンプレートファイルは8行目のフォルダ内に格納すること
function sendSpredsheet(event) {
  // フォームの回答結果の整理
  const formResponses = event.response.getItemResponses();  // 回答結果を取得
  const emailaddress = event.response.getRespondentEmail(); // Emailアドレスを取得
  const studentNumber = formResponses[0].getResponse();     // 学籍番号
  const classname = formResponses[1].getResponse();         // 授業名
  const content = formResponses[2].getResponse();           // 授業内容
  const selfchecks = formResponses[3].getResponse();        // 自己評価
  const actfeedback = formResponses[4].getResponse();       // 取り組みに対する振り返り
  const contentfeedback = formResponses[5].getResponse();   // 授業内容に対する振り返り
  const question = formResponses[6].getResponse();          // 質問
  let files = [];
  try {
    files = formResponses[7].getResponse();           // アップロードファイル
  } catch (e) {
    files = new Array("");
  }
  // 操作フォルダーとファイル一覧の取得等
  const folder = DriveApp.getFolderById(FOLDER_ID);   // 操作フォルダー
  const filelist = folder.getFiles();   // 操作フォルダーに格納されているファイル一覧をIteratorオブジェクトとして取得
  const fileName = `【振り返りシート】${studentNumber}`   // 振り返りシートの名前
  let check = 0;    //  既にファイルが存在しているかのチェックフラグ
  // 既にファイルが存在しているかの確認
  while (filelist.hasNext()) {          // .hasNext()でファイルがまだ残っているかどうかチェック
    const file = filelist.next();     // .next()で順番にファイルを取り出す
    if (file.getName() === fileName) {  // 既にファイルがあったならばチェックフラグを立てる
      check = 1;
      Logger.log("exist!");
    }
  }
  // ファイルの作成
  if (check === 0) {    // ファイルがなければテンプレートファイルから複製してファイルを作成する
    const templateFiles = DriveApp.getFolderById(FOLDER_ID).getFilesByName(TEMPLATE_FILE_NAME);   // テンプレートファイルをIteratorオブジェクトとして取得
    const templateFile = templateFiles.next();   // .next()でIteratorオブジェクトからtemplateファイルを取得
    templateFile.makeCopy(fileName, folder);    // templateファイルをコピー
  }
  // スプレッドシート情報の取得
  const targetFiles = DriveApp.getFolderById(FOLDER_ID).getFilesByName(fileName);   // 操作するスプレッドシートをIteratorオブジェクトとして取得
  const targetFile = targetFiles.next();  // .next()でIteratorオブジェクトからファイルを取得
  const targetss = SpreadsheetApp.openById(targetFile.getId()); // .getIdでID名を指定してスプレッドシートとしてファイルを取得し直す
  const targetsheets = targetss.getSheets();    // すべてのシートを取得
  // 既に同じ授業名のシートが存在しているかの確認
  const sheet_names = [];
  targetsheets.forEach(sheet => {
    sheet_names.push(sheet.getName());
  });
  if (sheet_names.includes(classname)) {  // 既に同じ授業名のシートが存在している場合
    var targetsheet = targetss.getSheetByName(classname);  // 授業名のシートを取得    
  } else {
    const templatesheet = targetss.getSheetByName("template");  // テンプレートシートを取得
    var targetsheet = templatesheet.copyTo(targetss);   // テンプレートシートをコピー
    targetsheet.setName(classname);   // シート名を授業名に変更
    targetsheet.activate();   // 新しいシートをアクティブにする
    targetss.moveActiveSheet(1);   // 新しいシートを一番左に移動
  }
  // スプレッドシートへの入力
  const dataRange = targetsheet.getRange("B:B").getValues();  // B列の値を配列で取得
  const lastRow = dataRange.filter(String).length;  // 空白の要素を除いた配列の長さを取得
  const d = new Date();   // 現在時刻を取得
  targetsheet.getRange(lastRow + 1, 2).setValue(`${d.getMonth() + 1}月${d.getDate()}日`);   // 日付を入力
  targetsheet.getRange(lastRow + 1, 3).setValue(content);         // 授業内容を入力
  targetsheet.getRange(lastRow + 1, 4).setValue(selfchecks[0]);   //  主体的な態度の評価を入力
  targetsheet.getRange(lastRow + 1, 5).setValue(selfchecks[1]);   //  思考・判断・表現の評価を入力
  targetsheet.getRange(lastRow + 1, 6).setValue(selfchecks[2]);   //  知識・技能の評価を入力
  targetsheet.getRange(lastRow + 1, 7).setValue(actfeedback);     //  取り組みに対する振り返りを入力  
  targetsheet.getRange(lastRow + 1, 8).setValue(contentfeedback); //  授業内容に対する振り返りを入力
  targetsheet.getRange(lastRow + 1, 9).setValue(question);        //  質問内容を入力
  if (files[0] != "") {
    let fileLink = '';
    let counter = 0;
    files.forEach(fileId => {
      counter++;
      fileLink = `https://drive.google.com/file/d/${fileId}`;
      targetsheet.getRange(lastRow + 1, 9 + counter).setValue(fileLink);  //  アップロードファイルのリンクを入力
    });
    // アップロードファイルの閲覧権限の付与(生徒用)
    files.forEach(fileId => {
      Drive.Permissions.insert(
        {
          'role': 'reader', //権限タイプを選ぶ (owner, organizer, fileOrganizer, writer, reader)
          'type': 'user', //アカウントタイプを選ぶ (user, group, domain, anyone)
          'value': emailaddress
        },
        fileId,
        {
          'sendNotificationEmails': 'false' //true=通知ON, false=通知OFF
        }
      );
    });
  }
  // 個別のスプレッドシートへのリンクを回答結果のスプレッドシートに追記
  addIndividualSsLinkToAnswerSs(targetFile, event);
  // スプレッドシートの閲覧権限の付与
  let scheck = 0;   // 権限があるかのフラグ
  const sviewers = targetFile.getViewers();    // 閲覧権限のアカウントを取得
  sviewers.forEach(viewer => {   // 今回のアカウントに既にコメント権限が付与されているかチェック
    if (viewer.getEmail() === emailaddress) {
      scheck = 1;   // アカウントにコメント権限が付与されているならフラグを立てる
    }
  });
  if (scheck === 0) {    // アカウントが付与されていなければ付与
    targetFile.addCommenter(emailaddress);
  }
}
/* 個別のスプレッドシートへのリンクを回答結果のスプレッドシートに追記 */
function addIndividualSsLinkToAnswerSs(targetFile, event) {
  const downloadUrl = targetFile.getUrl();  // 個別のスプレッドシートのリンクを取得
  const answerSheet = getSheet(event.source.getId());    // 回答シートを取得
  const dataRange = answerSheet.getRange("C:C").getValues();  // C列の値を配列で取得
  const lastRow = dataRange.filter(String).length;  // 空白の要素を除いた配列の長さを取得
  const lastColumn = answerSheet.getRange(1, 1).getNextDataCell(SpreadsheetApp.Direction.NEXT).getColumn() + 1;
  answerSheet.getRange(lastRow, lastColumn).setValue(downloadUrl);  // 個別のスプレッドシートのリンクを入力
}
/* スプレッドシートのIDを取得する */
function getSheet(formId) {
  const form = FormApp.openById(formId);    // フォームを取得(スクリプトエディタでDrive APIを追加しておく必要がある)
  const answerSs = SpreadsheetApp.openById(form.getDestinationId());    // フォームとリンクしている回答スプレッドシートを取得
  const formUrl = form.getEditUrl().replace('/edit', '');   // フォームのURL兼IDを取得
  const destinationSheet = answerSs.getSheets().find(sheet =>   // 回答スプレッドシートの各シートにおいて、リンクしているフォームがformUrlと一致するシートを探す
    sheet.getFormUrl()?.replace('/viewform', '') === formUrl);
  return destinationSheet;
}

light版(アウトプットの入力項目がないバージョン)

/*
Copyright (c) 2022 alf
Released under the MIT license
*/
// フォルダIDとテンプレートファイル名を定義(指定)
const FOLDER_ID = '1K7v2lKe4Xtb6GAXuycrXZGsCbG8nRW--';    // 振り返りのスプレッドシートを保存したいフォルダのID
const TEMPLATE_FILE_NAME = "template_classSelfFeedbackv2.0_light";   // テンプレートファイルは8行目のフォルダ内に格納すること
function sendSpredsheet(event) {
  // フォームの回答結果の整理
  const formResponses = event.response.getItemResponses();  // 回答結果を取得
  const emailaddress = event.response.getRespondentEmail(); // Emailアドレスを取得
  const studentNumber = formResponses[0].getResponse();     // 学籍番号
  const classname = formResponses[1].getResponse();         // 授業名
  const content = formResponses[2].getResponse();           // 授業内容
  const selfchecks = formResponses[3].getResponse();        // 自己評価
  const actfeedback = formResponses[4].getResponse();       // 振り返り(自由記述)
  const question = formResponses[5].getResponse();          // 質問
  let files = [];
  try {
    files = formResponses[6].getResponse();           // アップロードファイル
  } catch (e) {
    files = new Array("");
  }
  // 操作フォルダーとファイル一覧の取得等
  const folder = DriveApp.getFolderById(FOLDER_ID);   // 操作フォルダー
  const filelist = folder.getFiles();   // 操作フォルダーに格納されているファイル一覧をIteratorオブジェクトとして取得
  const fileName = `【振り返りシート】${studentNumber}`   // 振り返りシートの名前
  let check = 0;    //  既にファイルが存在しているかのチェックフラグ
  // 既にファイルが存在しているかの確認
  while (filelist.hasNext()) {          // .hasNext()でファイルがまだ残っているかどうかチェック
    const file = filelist.next();     // .next()で順番にファイルを取り出す
    if (file.getName() === fileName) {  // 既にファイルがあったならばチェックフラグを立てる
      check = 1;
      Logger.log("exist!");
    }
  }
  // ファイルの作成
  if (check === 0) {    // ファイルがなければテンプレートファイルから複製してファイルを作成する
    const templateFiles = DriveApp.getFolderById(FOLDER_ID).getFilesByName(TEMPLATE_FILE_NAME);   // テンプレートファイルをIteratorオブジェクトとして取得
    const templateFile = templateFiles.next();   // .next()でIteratorオブジェクトからtemplateファイルを取得
    templateFile.makeCopy(fileName, folder);    // templateファイルをコピー
  }
  // スプレッドシート情報の取得
  const targetFiles = DriveApp.getFolderById(FOLDER_ID).getFilesByName(fileName);   // 操作するスプレッドシートをIteratorオブジェクトとして取得
  const targetFile = targetFiles.next();  // .next()でIteratorオブジェクトからファイルを取得
  const targetss = SpreadsheetApp.openById(targetFile.getId()); // .getIdでID名を指定してスプレッドシートとしてファイルを取得し直す
  const targetsheets = targetss.getSheets();    // すべてのシートを取得
  // 既に同じ授業名のシートが存在しているかの確認
  const sheet_names = [];
  targetsheets.forEach(sheet => {
    sheet_names.push(sheet.getName());
  });
  if (sheet_names.includes(classname)) {  // 既に同じ授業名のシートが存在している場合
    var targetsheet = targetss.getSheetByName(classname);  // 授業名のシートを取得    
  } else {
    const templatesheet = targetss.getSheetByName("template");  // テンプレートシートを取得
    var targetsheet = templatesheet.copyTo(targetss);   // テンプレートシートをコピー
    targetsheet.setName(classname);   // シート名を授業名に変更
    targetsheet.activate();   // 新しいシートをアクティブにする
    targetss.moveActiveSheet(1);   // 新しいシートを一番左に移動
  }
  // スプレッドシートへの入力
  const dataRange = targetsheet.getRange("B:B").getValues();  // B列の値を配列で取得
  const lastRow = dataRange.filter(String).length;  // 空白の要素を除いた配列の長さを取得
  const d = new Date();   // 現在時刻を取得
  targetsheet.getRange(lastRow + 1, 2).setValue(`${d.getMonth() + 1}月${d.getDate()}日`);   // 日付を入力
  targetsheet.getRange(lastRow + 1, 3).setValue(content);         // 授業内容を入力
  targetsheet.getRange(lastRow + 1, 4).setValue(selfchecks[0]);   //  主体的な態度の評価を入力
  targetsheet.getRange(lastRow + 1, 5).setValue(selfchecks[1]);   //  思考・判断・表現の評価を入力
  targetsheet.getRange(lastRow + 1, 6).setValue(selfchecks[2]);   //  知識・技能の評価を入力
  targetsheet.getRange(lastRow + 1, 7).setValue(actfeedback);     //  振り返り(自由記述)を入力  
  targetsheet.getRange(lastRow + 1, 8).setValue(question);        //  質問内容を入力
  if (files[0] != "") {
    let fileLink = '';
    let counter = 0;
    files.forEach(fileId => {
      counter++;
      fileLink = `https://drive.google.com/file/d/${fileId}`;
      targetsheet.getRange(lastRow + 1, 8 + counter).setValue(fileLink);  //  アップロードファイルのリンクを入力
    });
    // アップロードファイルの閲覧権限の付与(生徒用)
    files.forEach(fileId => {
      Drive.Permissions.insert(
        {
          'role': 'reader', //権限タイプを選ぶ (owner, organizer, fileOrganizer, writer, reader)
          'type': 'user', //アカウントタイプを選ぶ (user, group, domain, anyone)
          'value': emailaddress
        },
        fileId,
        {
          'sendNotificationEmails': 'false' //true=通知ON, false=通知OFF
        }
      );
    });
  }
  // 個別のスプレッドシートへのリンクを回答結果のスプレッドシートに追記
  addIndividualSsLinkToAnswerSs(targetFile, event);
  // スプレッドシートの閲覧権限の付与
  let scheck = 0;   // 権限があるかのフラグ
  const sviewers = targetFile.getViewers();    // 閲覧権限のアカウントを取得
  sviewers.forEach(viewer => {   // 今回のアカウントに既にコメント権限が付与されているかチェック
    if (viewer.getEmail() === emailaddress) {
      scheck = 1;   // アカウントにコメント権限が付与されているならフラグを立てる
    }
  });
  if (scheck === 0) {    // アカウントが付与されていなければ付与
    targetFile.addCommenter(emailaddress);
  }
}
/* 個別のスプレッドシートへのリンクを回答結果のスプレッドシートに追記 */
function addIndividualSsLinkToAnswerSs(targetFile, event) {
  const downloadUrl = targetFile.getUrl();  // 個別のスプレッドシートのリンクを取得
  const answerSheet = getSheet(event.source.getId());    // 回答シートを取得
  const dataRange = answerSheet.getRange("C:C").getValues();  // C列の値を配列で取得
  const lastRow = dataRange.filter(String).length;  // 空白の要素を除いた配列の長さを取得
  const lastColumn = answerSheet.getRange(1, 1).getNextDataCell(SpreadsheetApp.Direction.NEXT).getColumn() + 1;
  answerSheet.getRange(lastRow, lastColumn).setValue(downloadUrl);  // 個別のスプレッドシートのリンクを入力
}
/* スプレッドシートのIDを取得する */
function getSheet(formId) {
  const form = FormApp.openById(formId);    // フォームを取得(スクリプトエディタでDrive APIを追加しておく必要がある)
  const answerSs = SpreadsheetApp.openById(form.getDestinationId());    // フォームとリンクしている回答スプレッドシートを取得
  const formUrl = form.getEditUrl().replace('/edit', '');   // フォームのURL兼IDを取得
  const destinationSheet = answerSs.getSheets().find(sheet =>   // 回答スプレッドシートの各シートにおいて、リンクしているフォームがformUrlと一致するシートを探す
    sheet.getFormUrl()?.replace('/viewform', '') === formUrl);
  return destinationSheet;
}

GitHubでもコードを公開しています。ライセンスはMITとなりますのでご自由にお使いください。

情報教育を中心に教育関連のことを発信していますので 他の記事TwitterYouTube もご覧いただけると嬉しいです。また、情報教育教材のまとめサイト も作成しています。教材だけでなく、入試情報や便利ツールの一覧集などのページもありますのでぜひご覧ください。

コメント

タイトルとURLをコピーしました