振り返りフォームで学習を可視化する!これで新学習指導要領の評価も悩まない!【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版 を選択してください。

2022年10月26日に、バージョン2.1に更新し、複数の児童・生徒が同時に回答した際に、回答先スプレッドシートに追記する個別スプレッドシートへのリンクが行単位でずれる不具合を修正しました。また、ファイルを共有することができないメールアドレスを児童・生徒が入力した際に、振り返りフォームを設定したオーナー(教員)にメール通知が飛ぶ機能を追加しました。

2023年5月20日に、バージョン2.2に更新しました(v2.1 からの乗り換え方法はv2.1から最新バージョンへの移行方法から)。
・デフォルトで、ログインしているアカウントのメールアドレスを取得するように変更(メールアドレスの入力が不要)
・GAS がフォームからデータを取得できない場合、リトライする機能を追加
・エラーの文言を修正・更新

2024年10月8日に、バージョン2.3に更新しました。2024年8〜9月にかけて、Google フォーム の回答一覧の Google スプレッドシート への出力した際のフォーマット変更されたことに伴う対応となります(Google Workspace Updates Blog)。
・新フォーマットにおいて、回答一覧に追記される児童生徒個別の振り返りスプレッドシートのリンクが、新しいカラムに追加され続ける不具合を修正
・旧フォーマットでも使えるように後方互換性を持たせている

できるようになること

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

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

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

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

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

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

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

GAS の仕様上、1ユーザーでの同時実行数が 30 までとなるため、30人前後のクラスで使用するようにしてください。1回の実行に10秒弱かかるため、よっぽどのことがない限りは30人少々のクラスでも問題なく動作します。40人あたりを超えてくる場合には、時間をずらして実行するようにしてください。また、他の先生の授業用に自分のアカウントで振り返りフォームを作成してトリガーを設定すると、制限に引っ掛かってしまう可能性が増えるので、「自分の授業の振り返りフォームのトリガーは自分のアカウントで設定する」ようにしてください(トリガーを設定したアカウント=実行するアカウント)。その他の制限については公式の下記を参照してください。
Google サービスの割り当て  |  Apps Script  |  Google Developers

生徒の使い方

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

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

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

2. メールアドレス(Google アカウント)をチェックする

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

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

デフォルトで、ログインしているアカウントのメールアドレスを取得するようにしました(2023年5月20日)。その代わり、チェックボックスにチェックする必要があります。また、ログインしているアカウントが学校のメールアドレスと異なる場合は「アカウントを切り替える」必要があります(チェックボックスの説明文がわかりにくいかもしれませんが、こちらは 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 ドライブ にコピーします。
※ ここで「Apps Script ファイルを表示」ボタンクリックしないでください!

各校種で異なる点は、フォーム内での「授業名」の選択肢が異なるということだけです。また、「授業名」の選択肢は、各学校の実態に合わせて変更することが可能です。

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

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

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

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

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

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

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

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

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

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

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

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

6で作成したスプレッドシートの保存先のフォルダのフォルダIDを取得します。フォルダIDは、フォルダを開いたURLの “folders/” 以降となります。末尾に “?ths=true” などのクエリパラメータが追加されることがありますが、その場合は “?” 以降を省き、フォルダIDのみをメモ帳や 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 の仕様上、各シートへのリンクは生成できないために生じる手間となりますが、複数授業対応になったメリットを考慮すれば微々たるものではないかと考えています。

17. 学校アカウントでのログインを必須にする

必ず設定しなければならないものではありませんが、学校アカウントでのログインを必須にすることをオススメします。必須にしなかった場合、学校外のアカウントで本ツールを使用すると下記のどちらかが発生します(特別なエラーが発生しない限り生徒が送信した振り返り内容が消えるようなことはありません)。

  • 学校が学校外のアカウントとのドキュメント等の共有を禁止している場合
    • 学校以外のアカウントと共有できなかったというエラー通知が先生に飛ぶ
  • 学校が学校外のアカウントとのドキュメント等の共有を禁止していない場合
    • 学校外のアカウントと共有できてしまう

上記の事態を回避するためには、フォームの設定タブから 「[学校や自治体名] と信頼できる組織のユーザーに限定する」を ON にします。こうすることで、振り返りフォームに回答するためには学校アカウントでログインすることを強制できます(公開授業や研修等で、外部の方(学校外のアカウント)に利用していただく際には本設定を OFF にする必要があります)。

なお、この設定は個人アカウントでは表示されませんので、検証等で試してみたい方はご注意ください。

フォームの設定タブから、「[学校や自治体名] と信頼できる組織のユーザーに限定する」を ON にする

ログインしているアカウント以外のメールアドレスでも回答できるようにしたい場合

こちらは好みの設定となります。(v2.1以前のように)ログインしているアカウント以外のメールアドレスでも回答できるようにするためには、フォームの回答タブから「メールアドレスを収集する」を “回答者からの入力” に変更すればOKです。

フォームの設定タブから「メールアドレスを収集する」の設定を“回答者からの入力”に変更する。

制限

Google Wordspace の管理コンソールにおいて、「Drive SDK API 経由での Google ドライブへのアクセスをユーザーに許可する」の設定が OFF になっている場合には、本ツールを使用することができないことが判明しました(デフォルトでは ON)(2022年11月23日)。

手順通り実施してもうまくいかない場合には、校内や職場のシステム管理者に確認してください。

なお、本ツールに限らず、Google Drive を操作する GAS(スクリプト)やサードパーティ製の拡張機能等でも同様の制限があります。

今後の予定

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

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

〜バージョン1の動画〜

〜バージョン2の動画〜

〜Light版の動画〜

v2.1から最新バージョンへの移行方法

1. コードの差し替え

スクリプトエディタを開き下記のコードに差し替えてください。なお、FOLDER_ID は既存のコードのものを設定(コピペ)してください。なお、通常版とlight版でお間違いないようご注意ください。

2. ログインアカウントのメールアドレスを使用するように変更

手順1のみでも本ツールを利用することはできますが、お好みで、ログインアカウントのメールアドレスを使用するように変更できます。これにより、メールアドレスの入力の代わりにチェックボックスにチェックするのみとなり、メールアドレスの入力を省いて誤入力を防ぐことができます。

フォームの設定タブから、「メールアドレスを収集する」を “確認済み” に変更します。

こうすることで、児童・生徒の入力画面が若干変わり、ログインしているアカウントが学校のメールアドレスと異なる場合は「アカウントを切り替える」必要がありますので、児童・生徒にも伝えておいた方が良いでしょう(チェックボックスの説明文がわかりにくいかもしれませんが、こちらは Google フォーム の定型の文言であるため設定で変更することができません。。)。

学校のメールアドレスであることを確認できたら「メール」の項目にチェックマークを付ける。学校のメールアドレスになっていなかったら「アカウントを切り替える」必要がある。

また、上記の設定をした上で学校外のアカウントで本ツールを使用しようとした場合、下記のどちらかが発生します。

  • 学校が学校外のアカウントとのドキュメント等の共有を禁止している場合
    • 学校外のアカウントと共有できなかったというエラー通知が先生に飛ぶ
  • 学校が学校外のアカウントとのドキュメント等の共有を禁止していない場合
    • 学校外のアカウントと共有できてしまう

上記のような事態を回避するのであれば、追加で次項の設定を追加してください。

なお、学校外のアカウントで本ツールを使用しようしても、特別なエラーが発生しない限り児童・生徒がフォームから送信した振り返り内容が消えるようなことはありません。

3. 学校アカウントでのログインを必須にする

フォームの設定タブから 「[学校や自治体名] と信頼できる組織のユーザーに限定する」を ON にします。こうすることで、振り返りフォームに回答するためには学校アカウントでログインすることを強制できます(公開授業や研修等で、外部の方(学校外のアカウント)に利用していただく際には本設定を OFF にする必要があります)。

なお、この設定は個人アカウントでは表示されませんので、検証等で試してみたい方はご注意ください。

フォームの設定タブから、「[学校や自治体名] と信頼できる組織のユーザーに限定する」を ON にする

なお、これらの設定は、BYODであったり自宅のPCから本ツールを利用しようとした際に、学校のアカウントに切り替える手間が発生するかもしれないという点がデメリットとなります。しかし、これまでのお問い合わせ内容からも、メールアドレスの誤入力を防ぐ方がメリットが大きいと思われます。

コードの公開

通常版

/*
gas-reactionform2gsheet
Version 2.3.0
2023/10/08

Copyright (c) 2024 alf
Released under the MIT license
*/

// フォルダIDとテンプレートファイル名を定義(指定)
const FOLDER_ID = 'スプレッドシートを保存したいフォルダIDを入力してください';    // 振り返りのスプレッドシートを保存したいフォルダのID
const TEMPLATE_FILE_NAME = "template_classSelfFeedbackv2.0";   // テンプレートファイルは18行目のフォルダ内に格納すること

const maxRetryCount = 5;    // 最大リトライ回数
const retryInterval = 2000; // リトライ間隔(ミリ秒)

function sendSpredsheet(event) {
  // フォームからの送信データ取得
  const emailaddress = retryWithLimit(() => event.response.getRespondentEmail());
  const formResponses = retryWithLimit(() => event.response.getItemResponses());
  const timeStamp = retryWithLimit(() => event.response.getTimestamp());
  const formId = retryWithLimit(() => event.source.getId());

  // フォームの回答結果の整理
  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();          // 質問

  // MEMO: カラム数は下記で算出
  // 質問項目(レスポンス)数 + 自己評価数 + タイムスタンプ列 + メールアドレス列 - 1
  // -1 している理由は、レスポンス数に自己評価である selfchecks が含まれているため
  // files が空の場合はレスポンス数に含まれないため、その分 +1 する
  let columnCount = formResponses.length + selfchecks.length + 1

  let files = [];
  try {
    files = formResponses[7].getResponse();   // アップロードファイル
  } catch (e) {
    files = new Array("");
    columnCount += 1;
  }

  // 操作フォルダーとファイル一覧の取得等
  let folder;
  try {
    folder = DriveApp.getFolderById(FOLDER_ID);   // 操作フォルダー
  } catch (e) {
    throw new Error(`フォルダーが見つかりませんでした。本プログラムで定義されているFOLDER_IDが正しいものか確認してください。もしくは、DriveAppを使ったツールがドメイン管理者(システム管理者)によって無効化されています。\n詳細: ${e.message}`);
  }
  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;
    }
  }

  // スプレッドシートファイルの作成
  if (check === 0) {    // ファイルがなければテンプレートファイルから複製してファイルを作成する
    const templateFiles = DriveApp.getFolderById(FOLDER_ID).getFilesByName(TEMPLATE_FILE_NAME);   // テンプレートファイルをIteratorオブジェクトとして取得
    let templateFile;
    try {
      templateFile = templateFiles.next();   // .next()でIteratorオブジェクトからtemplateファイルを取得
    } catch (e) {
      throw new Error(`テンプレートファイルが見つかりませんでした。テンプレートファイルがFOLDER_IDのフォルダに保存されていることと、本プログラムで定義されているTEMPLATE_FILE_NAMEとテンプレートファイル名が一致していること、Excelファイルではなくスプレッドシートであることを確認してください。\n詳細: ${e.message}`);
    }
    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);  // アップロードファイルのリンクを入力
    });

    // アップロードファイルの閲覧権限の付与(生徒用)
    try {
      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
          }
        );
      });
    } catch (e) {
      console.error('提出されたファイルに共有設定をすることができませんでした。')
    }
  }

  // スプレッドシートの閲覧権限の付与
  let scheck = 0;   // 権限があるかのフラグ
  const sviewers = targetFile.getViewers();    // 閲覧権限のアカウントを取得
  sviewers.forEach(viewer => {   // 今回のアカウントに既にコメント権限が付与されているかチェック
    if (viewer.getEmail() === emailaddress) {
      scheck = 1;   // アカウントにコメント権限が付与されているならフラグを立てる
    }
  });
  if (scheck === 0) {    // アカウントが付与されていなければ付与
    try {
      targetFile.addCommenter(emailaddress);
    } catch (e) {
      const error_str = `${studentNumber} さんが入力したメールアドレス(${emailaddress})は、共有を許可されていないなどの問題があります。入力に誤りがあるかなどの確認をしてください。なお、${studentNumber} さん個別の振り返りスプレッドシートに振り返り内容は転送されていますが、スプレッドシートが ${studentNumber} さんと共有されていない可能性があります。また、ファイルが提出されている場合には、提出されたファイルが${studentNumber} さんと共有設定されていません。提出されたファイルの共有設定を確認して、共有されていない場合には「閲覧者(コメント可)」で手動で共有してください。

${studentNumber} さん個別の振り返りスプレッドシート: ${targetFile.getUrl()}
`
      console.error(error_str)
      const exec_emailAddress = Session.getActiveUser().getUserLoginId();
      sendMailWithOption(exec_emailAddress, studentNumber, error_str);
    }
  }

  // 個別のスプレッドシートへのリンクを回答一覧のスプレッドシートに追記
  addIndividualSsLinkToAnswerSs(targetFile, formId, timeStamp, studentNumber, columnCount);
}

/* 個別のスプレッドシートへのリンクを回答一覧のスプレッドシートに追記 */
function addIndividualSsLinkToAnswerSs(targetFile, formId, timeStamp, studentNumber, columnCount) {
  const downloadUrl = targetFile.getUrl();  // 個別のスプレッドシートのリンクを取得
  const answerSheet = retryWithLimit(() => getSheet(formId));

  let retryCount = 0;
  let timeStamps, studentNumbers, targetRow;
  while (!targetRow && retryCount < maxRetryCount) {
    retryCount++;
    Utilities.sleep(retryInterval);
    timeStamps = answerSheet.getRange("A:A").getValues();     // A列(タイムスタンプ)の値を配列で取得
    studentNumbers = answerSheet.getRange("C:C").getValues(); // C列(学籍番号)の値を配列で取得
    targetRow = getTargetRow(timeStamps, studentNumbers, timeStamp, studentNumber) // 回答を記録した行を取得
  }
  if (!targetRow) {
    throw new Error(`回答一覧のスプレッドシートに ${studentNumber} さんの回答が見つからなかったため、個別のスプレッドシートへのリンクを回答一覧のスプレッドシートに追記できませんでした。`)
  } else {
    answerSheet.getRange(1, columnCount + 1).setValue("個別の振り返りスプレッドシート");  // ヘッダーを入力
    answerSheet.getRange(targetRow, columnCount + 1).setValue(downloadUrl);  // 個別のスプレッドシートのリンクを入力
  }
}

/* スプレッドシートのIDを取得する */
function getSheet(formId) {
  const form = FormApp.openById(formId);    // フォームを取得(スクリプトエディタでDrive APIを追加しておく必要がある)
  let answerSs;
  try {
    answerSs = SpreadsheetApp.openById(form.getDestinationId());    // フォームとリンクしている回答スプレッドシートを取得
  } catch (e) {
    throw new Error(`フォームとリンクしている回答先スプレッドシートが見つかりませんでした。フォームの回答タブから回答先スプレッドシートを作成・もしくは既存のものを選択してください。\n詳細: ${e.message}`);
  }
  const formUrl = form.getEditUrl().replace('/edit', '');   // フォームのURL兼IDを取得
  const destinationSheet = answerSs.getSheets().find(sheet =>   // 回答スプレッドシートの各シートにおいて、リンクしているフォームがformUrlと一致するシートを探す
    sheet.getFormUrl()?.replace('/viewform', '') === formUrl
  );
  return destinationSheet;
}

/* 回答した行を取得 */
function getTargetRow(timeStamps, studentNumbers, timeStamp, studentNumber) {
  for(var i = 1; i < timeStamps.length; i++){
    if(timeStamps[i] + studentNumbers[i] === timeStamp + studentNumber){
      return i + 1;
    }
  }
}

/* メールアドレスを間違えていたりして共有設定できなかった際のメール通知 */
function sendMailWithOption(address, studentNumber, message) {
  const subject = `【振り返りフォームエラー】${studentNumber}さんが入力したメールアドレスに問題がある`; // メールの件名
  // const options = { /*オプションの内容*/ };
  const body = `${message}`;
  MailApp.sendEmail(address, subject, body);
}

/* リトライ処理用関数 */
function retryWithLimit(func) {
  let retryCount = 0;
  let result;

  while (retryCount < maxRetryCount) {
    try {
      result = func();
      if (!result) {
        throw new Error("データ取得に失敗しました。");
      }
      break;
    } catch (e) {
      retryCount++;
      console.error(`リトライします: ${retryCount}回目(データ取得に失敗しました: ${e.message})`);
      Utilities.sleep(retryInterval);
    }
  }

  if (!result) {
    throw new Error("データ取得の最大リトライ回数を超えました。処理を終了します。");
  }

  return result;
}

light版(自由記述を統合したバージョン)

/*
gas-reactionform2gsheet_light
Version 2.3.0
2024/10/08

Copyright (c) 2024 alf
Released under the MIT license
*/

// フォルダIDとテンプレートファイル名を定義(指定)
const FOLDER_ID = 'スプレッドシートを保存したいフォルダIDを入力してください';    // 振り返りのスプレッドシートを保存したいフォルダのID
const TEMPLATE_FILE_NAME = "template_classSelfFeedbackv2.0_light";   // テンプレートファイルは18行目のフォルダ内に格納すること

const maxRetryCount = 5;    // 最大リトライ回数
const retryInterval = 2000; // リトライ間隔(ミリ秒)

function sendSpredsheet(event) {
  // フォームからの送信データ取得
  const emailaddress = retryWithLimit(() => event.response.getRespondentEmail());
  const formResponses = retryWithLimit(() => event.response.getItemResponses());
  const timeStamp = retryWithLimit(() => event.response.getTimestamp());
  const formId = retryWithLimit(() => event.source.getId());

  // フォームの回答結果の整理
  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();          // 質問

  // MEMO: カラム数は下記で算出
  // 質問項目(レスポンス)数 + 自己評価数 + タイムスタンプ列 + メールアドレス列 - 1
  // -1 している理由は、レスポンス数に自己評価である selfchecks が含まれているため
  // files が空の場合はレスポンス数に含まれないため、その分 +1 する
  let columnCount = formResponses.length + selfchecks.length + 1

  let files = [];
  try {
    files = formResponses[6].getResponse();   // アップロードファイル
  } catch (e) {
    files = new Array("");
    columnCount += 1;
  }

  // 操作フォルダーとファイル一覧の取得等
  let folder;
  try {
    folder = DriveApp.getFolderById(FOLDER_ID);   // 操作フォルダー
  } catch (e) {
    throw new Error(`フォルダーが見つかりませんでした。本プログラムで定義されているFOLDER_IDが正しいものか確認してください。もしくは、DriveAppを使ったツールがドメイン管理者(システム管理者)によって無効化されています。\n詳細: ${e.message}`);
  }
  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;
    }
  }

  // スプレッドシートファイルの作成
  if (check === 0) {    // ファイルがなければテンプレートファイルから複製してファイルを作成する
    const templateFiles = DriveApp.getFolderById(FOLDER_ID).getFilesByName(TEMPLATE_FILE_NAME);   // テンプレートファイルをIteratorオブジェクトとして取得
    let templateFile;
    try {
      templateFile = templateFiles.next();   // .next()でIteratorオブジェクトからtemplateファイルを取得
    } catch (e) {
      throw new Error(`テンプレートファイルが見つかりませんでした。テンプレートファイルがFOLDER_IDのフォルダに保存されていることと、本プログラムで定義されているTEMPLATE_FILE_NAMEとテンプレートファイル名が一致していること、Excelファイルではなくスプレッドシートであることを確認してください。\n詳細: ${e.message}`);
    }
    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);  // アップロードファイルのリンクを入力
    });

    // アップロードファイルの閲覧権限の付与(生徒用)
    try {
      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
          }
        );
      });
    } catch (e) {
      console.error('提出されたファイルに共有設定をすることができませんでした。')
    }
  }

  // スプレッドシートの閲覧権限の付与
  let scheck = 0;   // 権限があるかのフラグ
  const sviewers = targetFile.getViewers();    // 閲覧権限のアカウントを取得
  sviewers.forEach(viewer => {   // 今回のアカウントに既にコメント権限が付与されているかチェック
    if (viewer.getEmail() === emailaddress) {
      scheck = 1;   // アカウントにコメント権限が付与されているならフラグを立てる
    }
  });
  if (scheck === 0) {    // アカウントが付与されていなければ付与
    try {
      targetFile.addCommenter(emailaddress);
    } catch (e) {
      const error_str = `${studentNumber} さんが入力したメールアドレス(${emailaddress})は、共有を許可されていないなどの問題があります。入力に誤りがあるかなどの確認をしてください。なお、${studentNumber} さん個別の振り返りスプレッドシートに振り返り内容は転送されていますが、スプレッドシートが ${studentNumber} さんと共有されていない可能性があります。また、ファイルが提出されている場合には、提出されたファイルが${studentNumber} さんと共有設定されていません。提出されたファイルの共有設定を確認して、共有されていない場合には「閲覧者(コメント可)」で手動で共有してください。

${studentNumber} さん個別の振り返りスプレッドシート: ${targetFile.getUrl()}
`
      console.error(error_str)
      const exec_emailAddress = Session.getActiveUser().getUserLoginId();
      sendMailWithOption(exec_emailAddress, studentNumber, error_str);
    }
  }

  // 個別のスプレッドシートへのリンクを回答一覧のスプレッドシートに追記
  addIndividualSsLinkToAnswerSs(targetFile, formId, timeStamp, studentNumber, columnCount);
}

/* 個別のスプレッドシートへのリンクを回答一覧のスプレッドシートに追記 */
function addIndividualSsLinkToAnswerSs(targetFile, formId, timeStamp, studentNumber, columnCount) {
  const downloadUrl = targetFile.getUrl();  // 個別のスプレッドシートのリンクを取得
  const answerSheet = retryWithLimit(() => getSheet(formId));

  let retryCount = 0;
  let timeStamps, studentNumbers, targetRow;
  while (!targetRow && retryCount < maxRetryCount) {
    retryCount++;
    Utilities.sleep(retryInterval);
    timeStamps = answerSheet.getRange("A:A").getValues();     // A列(タイムスタンプ)の値を配列で取得
    studentNumbers = answerSheet.getRange("C:C").getValues(); // C列(学籍番号)の値を配列で取得
    targetRow = getTargetRow(timeStamps, studentNumbers, timeStamp, studentNumber) // 回答を記録した行を取得
  }
  if (!targetRow) {
    throw new Error(`回答一覧のスプレッドシートに ${studentNumber} さんの回答が見つからなかったため、個別のスプレッドシートへのリンクを回答一覧のスプレッドシートに追記できませんでした。`)
  } else {
    answerSheet.getRange(1, columnCount + 1).setValue("個別の振り返りスプレッドシート");  // ヘッダーを入力
    answerSheet.getRange(targetRow, columnCount + 1).setValue(downloadUrl);  // 個別のスプレッドシートのリンクを入力
  }
}

/* スプレッドシートのIDを取得する */
function getSheet(formId) {
  const form = FormApp.openById(formId);    // フォームを取得(スクリプトエディタでDrive APIを追加しておく必要がある)
  let answerSs;
  try {
    answerSs = SpreadsheetApp.openById(form.getDestinationId());    // フォームとリンクしている回答スプレッドシートを取得
  } catch (e) {
    throw new Error(`フォームとリンクしている回答先スプレッドシートが見つかりませんでした。フォームの回答タブから回答先スプレッドシートを作成・もしくは既存のものを選択してください。\n詳細: ${e.message}`);
  }
  const formUrl = form.getEditUrl().replace('/edit', '');   // フォームのURL兼IDを取得
  const destinationSheet = answerSs.getSheets().find(sheet =>   // 回答スプレッドシートの各シートにおいて、リンクしているフォームがformUrlと一致するシートを探す
    sheet.getFormUrl()?.replace('/viewform', '') === formUrl
  );
  return destinationSheet;
}

/* 回答した行を取得 */
function getTargetRow(timeStamps, studentNumbers, timeStamp, studentNumber) {
  for(var i = 1; i < timeStamps.length; i++){
    if(timeStamps[i] + studentNumbers[i] === timeStamp + studentNumber){
      return i + 1;
    }
  }
}

/* メールアドレスを間違えていたりして共有設定できなかった際のメール通知 */
function sendMailWithOption(address, studentNumber, message) {
  const subject = `【振り返りフォームエラー】${studentNumber}さんが入力したメールアドレスに問題がある`; // メールの件名
  // const options = { /*オプションの内容*/ };
  const body = `${message}`;
  MailApp.sendEmail(address, subject, body);
}

/* リトライ処理用関数 */
function retryWithLimit(func) {
  let retryCount = 0;
  let result;

  while (retryCount < maxRetryCount) {
    try {
      result = func();
      if (!result) {
        throw new Error("データ取得に失敗しました。");
      }
      break;
    } catch (e) {
      retryCount++;
      console.error(`リトライします: ${retryCount}回目(データ取得に失敗しました: ${e.message})`);
      Utilities.sleep(retryInterval);
    }
  }

  if (!result) {
    throw new Error("データ取得の最大リトライ回数を超えました。処理を終了します。");
  }

  return result;
}

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

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

コメント

  1. ミヤタケ より:

    こんにちは。とても興味深く拝見させていただきました。
    いくつか要望があり、コメントさせていただきます。
    私は大阪府立高校の家庭科教諭をしております。
    生徒が学習を振り返られるスプレッドシートをフォームの入力で簡単にできるのは素晴らしいと思いました。
    できれば、単元ごとにポートフォリオが完成するものをつくりたいと思っており、単元を貫く問いに対して学習する前の考えを記入する欄。
    また、単元の学習が終わってから、改めて同じ単元を貫く問いに対する考えや、その考えに至った経
    緯や今後の行動や意識についてを記入する欄があると嬉しいと思いました。
    セクションを変えて学習前、学習中、学習後などに分けることで、集まるデータをポートフォリオのようなものにすることは可能でしょうか?
    また、可能でしたらぜひともそのようなシステムを教えていただきたいです。

    • あるふ より:

      コメントありがとうございます!
      毎授業ではなく、単元毎に使うのもとても有効な方法ですね。また、学習の前後での変遷を残していくことは私もとても良いことだと思っています。

      ミヤタケさんがやりたいことを本ツールで行うのであれば、各回答項目の文言は変更しても問題ありませんので、そちらで十分であればそのようにお使いください。回答項目を増やしたり減らしたりする場合は、GAS(プログラム)をいじらないといけないので、少々プログラミングスキルが必要となります。

      「セクションを変えて学習前、学習中、学習後などに分ける」というのは、どうやってデータとして残していくかによります(単元ごとにシートをわけるのかどうするのかなど)。たとえば、一行に一単元の振り返りを並べた場合、その単元での前後の変化は見にくいでしょうし、「学習前、学習中、学習後」で3行にすると、他の単元がその前後に並んだ際にみづらくなるでしょう。そうであれば単元ごとにシートをわけるのが良さそうですが、項目も含めて4行のシートが単元ごとに増えていくのも微妙な気がしています。

      つまり、スプレッドシートのような表計算ソフトだと少々厳しいのではないかというのが個人的な考えです。
      似たようなことをスライドを用いてやっている先生もいらっしゃいますので、単元ごとにスライドを作成するのも良いと思います(単元での振り返りシート・プリントのイメージ)。

      システム化しようとするのであればWebシステムで作成するのも良さそうですが、今は仕事の片手間で行っている活動ですので、私一人では時間的にもスキル的にも厳しいというのが現状です。
      回答になっていますでしょうか。ミヤタケさんのお力に少しでもなれば幸いです。

  2. かじさん より:

    こんにちは。
    振り返りフォームを活用させていただいております。

    一つ質問があります。

    以前、学籍番号の所を全角4ケタの数で入力していました。そうすると、日ごとに別々のスプレッドシートが生徒と教員に共有される状態が生じました。
    (※11/20に送った振り返りのスプレッドシートに11/21に送った文が蓄積されず、11/21用のスプレッドシートが新たに作成される。といった感じです。)

    そこで、半角4ケタの数で入力するルールにしたところ、上の状態になる生徒と、上手く蓄積されていく生徒とで分かれてしまいました。

    上で書かれていた中に、人数についてのことが書かれていましたが、もしかしたらこの状態も人数が関係しているのでしょうか?クラスの人数は35名ほどです。

    また、学籍番号の入力時に気をつけること等がありましたら、教えていただけたらと思います。

    お時間ありましたら、よろしくお願いいたします。

    • あるふ より:

      コメントありがとうございます。
      まず、振り返りフォームの学籍番号は半角入力する想定で作っています。そのため、振り返りフォームの初期設定においても半角数字での入力のみになるよう制限しています。おそらくかじさんで設定を変更されたのだと推測しています。

      以下、設定を変更されたことを前提として説明させていただきます。

      > 学籍番号の所を全角4ケタの数で入力していました。そうすると、日ごとに別々のスプレッドシートが生徒と教員に共有される状態が生じました。

      同じスプレッドシートファイル名(【振り返りシート】[学籍番号])のものがあればそこに追記し、なければ新しいものが作成されるようにプログラムしています。半角全角もそれぞれ違うものとして認識するように作っているので、
      ・【振り返りシート】[全角学籍番号]
      ・【振り返りシート】[半角学籍番号]
      の2つのファイルが出来ており、全角で入力するか半角で入力するかによって追記される先が違う状態になっていると思われます。

      もし、全角入力をOKにする設定を継続するのであれば、全角で入力するよう児童生徒に徹底するようにしてください。
      なお、全角数字での入力をOKにする設定だと半角数字での入力もできますが、初期設定の半角数字での入力のみをOKにする設定だと全角数字での入力はできません。
      初期設定が半角数字での入力のみになるよう制限しているのもこのような理由ですので、設定を元に戻すことをおすすめします。

      > 上で書かれていた中に、人数についてのことが書かれていましたが、もしかしたらこの状態も人数が関係しているのでしょうか?クラスの人数は35名ほどです。

      今回のケースでは人数が原因ではないように思われます。
      この人数の制限は、同時実行数の制限ですので、児童生徒が「せーのっ!」で送信しない限りは35人程度であれば滅多に制限に達することはないと思われます。

      よろしくお願いします。

  3. 吉武 謙二 より:

    はじめまして!
    いくつかの小学校でICT支援担当の仕事をしています。吉武と申します。
    小学校で外国語を教えておられる先生から、サイトを見るように言われ、
    導入の検討しましたが、・・・
    外国語の先生も4校で4年生5年生6年生の授業を行っておられ、
    授業毎にフォームを作成し、生徒毎に授業で理解したこと、理解できなかったことの
    質問形式になっているようです。
    今はスプレットシートの一覧表を見ながら、生徒ひとりひとりに上がってきた質問に
    返答しておられます。
    この場合、振替リフォームで、スプレットシートを結合しても、毎回質問内容が異なる為
    毎回のスプレットシートが別に作成されてしまい。生徒との対応がかえって
    面倒なものにならないでしょうか?

    外国語の先生は。あるふ信者であり、これを導入したら、生徒毎にスプレットシートが毎回
    出来上がり、各時間に上がってきた質問事項にも、対応出来やすくなる!とお考えのようです。
    毎回、フォームの質問内容が異なる場合、振替リフォーム作成したほうが、良いでしょうか?
    何かいい方法がありましたら、お願いいたします。
    ICT支援担当と言っても、ど新人で、あるふ先生が何を言われているのか?
    理解出来ていないところが、多々あります。
    よろしくお願いいたします。

    • あるふ より:

      吉武さん

      コメントありがとうございます。

      現在は授業毎にフォームを作成されているのですね。

      振り返りフォームは吉武さんのご認識の通り、同じフォームを使い続けることによって振り返りが児童・生徒毎に蓄積されるものとなっています。
      そのため、授業毎に異なるフォームを作るような用途は想定していません。

      やるとしたら「同じフォーム使って毎授業質問を変更する」と良いかもしれません。
      各項目の文言を変更すること事態は問題ありません。
      ただ、一点制限がありまして、項目数の増減はGAS(コード・プログラム)の編集が必要になります。
      こちらはプログラミングに不慣れな方の場合はハードルが高いと思われます。
      また、毎授業編集して別の質問を設定すると「どのような質問をしたか」が
      スプレッドシートから追えなくなると思われます。
      どのような質問をしたか先生や吉武さんで管理できるのならこの方法もアリではあると思います。

      もしくは、バージョン2の下記の動画のように毎授業別の教科として扱い、別シートにする方法(1授業1シート)もあります。
      https://www.youtube.com/watch?v=KNCF0ltFr2Q

      ただ、スプレッドシート上の1行だけ入力されて、次の授業では別シートになるというのは
      児童・生徒からしたら一覧性を大きく損なうもので、あまりスマートな方法ではないかもしれません。

      今は別々のフォームを授業毎に作成して進めていますが、
      察するに、先生は前者の方法をイメージされているのではないでしょうか。
      まずは先生とイメージを共有すると良いかもしれません。

      よろしくお願いします。

    • あるふ より:

      吉武さん

      もう少し状況を想像してみたのですが、今の先生のやり方を効率化するのなら、
      Google フォーム ではなく、Google Classroom を使うと良いのではないでしょうか。
      毎授業、質問を生徒に課題として配布することができますし、それに対するコメント・返信も可能です。
      振り返りフォームはあくまで「毎授業の蓄積」を想定していますので 今のやり方であれば Google Classroom の方がマッチすると思います。

      各学校・自治体での制約もあるとは思いますが、Google Classroom もぜひご検討ください。

  4. 山田 より:

    自動でふり返りシートを集約していただける機能が搭載されていて、とても便利に使っています。ありがとうございます。
    定時制高校の体育のみで使用していて、授業名のところを種目(4つ)にしています。番号でシートが判断されてしまうので、朝と夜で授業名が一緒なので、朝の生徒と夜の生徒で同じフォルダに入ってしまいます。その場合はフォーム自体を複数作成しなければならないのでしょうか。
    希望としては、同じフォームで朝と夜の生徒を分けられないかなと思っています。あわよくば男女でフォルダも分かれるようにしたいです。
    いい方法があればご教授願います。

    • あるふ より:

      山田さん

      ご活用いただきありがとうございます!

      まず、ご質問を整理させてください。

      > 番号でシートが判断されてしまうので、朝と夜で授業名が一緒なので、朝の生徒と夜の生徒で同じフォルダに入ってしまいます。

      児童生徒の個別ファイルを午前の部と午後の部でフォルダ分けしたいということでしょうか。また、授業名が異なっていても児童生徒の個別ファイルは同じフォルダに入ります。

      > その場合はフォーム自体を複数作成しなければならないのでしょうか。

      フォルダごとに分けたいのであれば、おっしゃるとおりフォーム自体を複数作成するのが良いと思います。

      あるいは、午前の部と午後の部でそれぞれ別の授業名で選択できるようにするのはいかがでしょうか。
      そうすれば、(フォルダごとに分けることはできませんが)回答一覧スプレッドシートをコピー ⇒ フィルタすることである程度は分けて評価したりすることができると思われます(回答一覧スプレッドシートから各児童生徒の個別ファイルへリンクでアクセスできるので)。

      ぜひご検討ください!

  5. 山田 より:

    ご回答ありがとうございます。質問が分かりにくく申し訳ございません。具体的には体育①という教科があり、その中で、αとβでの習熟度別で授業を展開しています。そして朝・昼・夜に登校する生徒たちがいますので、朝の体育①α・β、昼の体育①α・β、体育①α・βの計6つの体育①が存在している事になっています。どの授業も別々の先生が行っていて、評価もそれぞれの先生がしています。

    1.体育①の振り返りフォームは1つのみを使用
    2.朝の体育①α・β、昼の体育①α・β、体育①α・βの計6つをそれぞれのフォルダに自動で割り振れるようにしたい ということでした。

    ドライブのフォルダに朝昼夜αβのフォルダをそれぞれ作り、GASのコードにフォルダIDのところを追加すればいいのでしょうか。

    コードの修正はチャットGPTに質問しながらいろいろ試そうかと思っているところでした。

    教科名が独特なので、適宜カットして回答していただけると助かります。

    • あるふ より:

      山田さん

      三部制で習熟度別の授業を実施されているということですね。
      詳細な情報ありがとうございます。

      > ドライブのフォルダに朝昼夜αβのフォルダをそれぞれ作り、GASのコードにフォルダIDのところを追加すればいいのでしょうか。

      はい、その通りです。

      > コードの修正はチャットGPTに質問しながらいろいろ試そうかと思っているところでした

      コードを修正すれば、山田さんが達成したい1、2は実現できると思います。
      ライセンスは MIT ライセンスですので、自由に改変していただいて構いません。
      https://opensource.org/licenses/mit-license.php

      自分がもしやるのであれば、下記のような手順を踏むと思います。
      1. 授業名を種目名に変更(コード上でも変更)
      2. 授業名を下記の選択肢で追加
        ・午前部体育①α
        ・午前部体育①β
        ・午後部体育①α
        ・午後部体育①β
        ・夜間部体育①α
        ・夜間部体育①β
      3. 授業名に応じて保存するフォルダを変更するようコードを修正

      一方で、私はこの方法を取らないかもしれません。
      というのも、生徒が授業名を間違って選択する可能性があるからです。
      間違って選択してしまった場合、評価材料が別のフォルダ・ファイルに
      バラけてしまい、採点が面倒になるかもしれません。

      それであれば、各授業(先生ごと)で振り返りフォームを作成・設定し、
      別々で管理した方がリスクが少ないかもしれません。

      最後の部分は私の個人的な意見ですので、山田さんの状況によって
      適切な方法を選択していただければと思います。

      よろしくお願いします。

  6. 田中 より:

    振り返りフォームを使わせていただいております。ありがとうございます。
    1人1人振り返りがスプレッドシートに蓄積されていくのが,とても良いです。
    1つしつもんなのですが,1人1人のスプレッドシートに,「フォームの回答1」というシートもコピーされ,何番の生徒がどのように入力しているのか見られる状態になっているのですが,これを回避する方法はあるのでしょうか?

    • あるふ より:

      田中さん

      返信が遅くなってしまい申し訳ありません。
      なぜかスパム判定になっており、気づくのが遅れてしまいました。

      > 1つしつもんなのですが,1人1人のスプレッドシートに,「フォームの回答1」というシートもコピーされ,何番の生徒がどのように入力しているのか見られる状態になっているのですが,これを回避する方法はあるのでしょうか?

      公開しているGASのプログラムと本記事の手順を実施してそのような動きをするのは考えにくいのですが、どのような手順・設定をされたのでしょうか。

      本手順やプログラムで編集した箇所があれば教えていただけないでしょうか。

      よろしくお願いします。

  7. スズカ より:

    はじめまして。今年度から活用させていただこうと考えております。さっそく授業にて使用したのですが、2回目のフォームを送信させた際、

    Exception: シート名「(授業名)」はすでに存在しています。別の名前を入力してください。
    at sendSpredsheet(FormToSpreadsheet:86:17)

    というエラーが出ました。一度目のフォームで個別振り返りシートは作成できています。
    色々と試してみたのですが原因が特定できませんでした。考えられる原因と対策をお教えいただけると幸いです。

    • あるふ より:

      スズカさん

      活用のご検討ありがとうございます。こちらのエラーですが、発生するとしたらGASの
      targetsheet.setName(classname); // シート名を授業名に変更
      で起きますが、通常であればこのエラーにはならないと思われます。

      また、上記のコードは通常版では93行目、light版では92行目のコードなのですが、
      スズカさんが送ってくださったエラーによると86行目で発生しているようです。

      元のコードから手順以外の変更を加えていませんか?
      今一度オリジナルと比較するか作り直して試してみていただけますでしょうか。

      よろしくお願いします。

  8. はら より:

    初めまして。中学校で理科を担当している教員のはらと申します。
    授業毎に書いた振り返りを継続的にデータに残していきたいなと思っていたところ、このサイトを見つけ、大変感銘を受けました。ぜひ活用させていただきたいと思います。

    フォームやスプレッドシートの設定段階での質問です。
    設定の6〜13でフォームの結果を入れるファイルをドライブに作成し、ファイルのリンクをフォームのスクリプトエディタに入力しました。
    ですが、生徒にフォームを送信してもらっても個別のスプレッドシートは作成されず、ドライブのファイルに入っている蓄積のスプレッドシートは元のままです。何か設定をミスしているのかもしれないのですが、どうしたら連携して個別のスプレッドシートができるのか教えていただきたいです。
    お手数おかけしますが、よろしくお願いします。

  9. はら より:

    先程コメントさせていただいたはらです。度々すみません。

    何回かやり直したところ、フォルダのリンクの最初に半角スペースが入ってしまっており、そのためにフォームとスプレッドシートが連結しなくなっていたようです。お騒がせいたしました。

    これからたくさん活用させていただきます。ありがとうございます!

    • あるふ より:

      はら さん

      解決できて良かったです!ぜひご活用ください!
      今後ともよろしくお願いします。

  10. スズカ より:

    ご返信ありがとうございます。
    エラーが発生した原因が判明したので共有させていただきます。
    原因はフォームの入力形式を変更したことにありました。
    授業が1つだったので、プルダウン方式ではなく、チェックボックスでの選択に変更したために起こったようです。
    コードの行数が違ったのは、フォームをコピーして編集ではなく、サイトに記載の項目をコピーしたためでした。上記のコードでは86番目に「targetsheet.setName(classname)」がありました。
    変更しようと思った理由は、1つしか授業名がないのに毎回プルダウンは手間だと思ったためでした。
    もし、なぜプルダウンからチェックボックス変えた場合にclassnameを上手く取得できないかについて、理由と対策をご存知であれば、お教えいただけないでしょうか。
    現在のところでは、初回のシート名は正しく作れているのですが、2回目以降に上手くシート名を特定できておらず、新規シートで作成する段階で初めて同じシート名が存在すると判断しているようです。

    • あるふ より:

      スズカ さん

      > もし、なぜプルダウンからチェックボックス変えた場合にclassnameを上手く取得できないかについて、理由と対策をご存知であれば、お教えいただけないでしょうか。

      [理由]
      チェックボックスに変更すると、GASに送られる授業名のデータは配列というデータ型になります。
      これは、チェックボックスだと複数選択で回答できるため、単純な文字列ではなくなるためです。
      配列だと、既存のシートの有無をチェックする分岐がうまく動きません。

      [対策(というよりは解決策となります)]
      解決策は以下の2つあります。

      1. 選択肢を一つだけにしてプルダウンを使う
      チェックボックスと比較してもそこまで手間ではないと思われるので最も簡単な解決策となります。
      (以前の似たような問い合わせでもこちらを案内しています)

      2. コード(GAS)を書き換えて保存する
      const classname = formResponses[1].getResponse();
      上記のコードを下記のように書き換えて、配列の最初の文字列を取得するようにします。
      const classname = formResponses[1].getResponse()[0];

      個人的には「授業名」は複数選択を想定していないため、解決策1をお勧めします。
      よろしくお願いします。

  11. あつろう より:

    はじめまして。小学校教諭をしております「あつろう」と申します。
    今年度、家庭学習の裁量を児童に委ね、児童の自主性を高めようと考えています。そこで、あるふ先生の授業振り返りフォームを活用させていただこうと思っています。
    そこで、2点ご助言いただきたいのですが、

    ①問1の授業選択(私の場合は家庭学習の内容)をスプレッドシートに反映できないか
    ②問1の授業選択をチェックボックスで複数選択にできないか

    ということです。こちらのほうでも調べたり勉強したりしながら試行錯誤しているのですが、ぜひご助言いただけると幸いです。

    https://docs.google.com/forms/d/1Kp1C3PqL-NN4k0nDBUcN6qifKEIf4j04Y34K8wMpMZs/edit

    • あるふ より:

      あつろう さん

      返信が遅くなってしまい申し訳ありません。
      なぜかスパム判定になっており、気づくのが遅れてしまいました。

      > ①問1の授業選択(私の場合は家庭学習の内容)をスプレッドシートに反映できないか

      いただいたURL(Google フォーム)の回答の受付が終了していたため内容を確認することができなかったのですが、質問項目を増やしたりするためにはGASを編集しなければなりません。プログラミングに知見がある方ならそこまで難易度は高くないものではありますが、あまり慣れていない方だと少々ハードルが高いかもしれません。

      > ②問1の授業選択をチェックボックスで複数選択にできないか

      GASを変更すれば可能だとは思いますが、振り返りフォームでは一回の回答で1授業・1シートに回答を反映させて管理することを目的としているため授業選択をチェックボックスで複数選択することは想定していません。おそらく、あつろうさんがやりたいことは「家庭学習」ということから察するに、

      1. 一回の回答で複数授業を選択してその回答をそれぞれのシートに複数反映させること?
      2. 今日はどの教科の家庭学習を実施したか回答したいということ?

      のどちらかだと推測しています。

      1の推測が正しいのであれば、それなりにGASを変更する必要があり、そこそこの変更量になると思われるので具体的にどこをどうすれば良いのかお伝えするのは難しいです。
      2の場合、チェックボックスでの複数選択は「配列」というデータ型で Google フォーム から GAS に送られてくるので、それを文字列に変換して児童生徒個々のスプレッドシートのセルに入力することは可能かと思われます。1よりは難易度は低いですが、こちらもGASの変更が必要かと思われます。

      よろしくお願い致します。

  12. はら より:

    先日コメントさせていただいたはらです。
    早速授業で活用しています。ありがとうございます!
    度々の質問失礼します。

    フォームの回答一覧のスプレッドシートで質問にコメントしたところ、個々のスプレッドシートに反映されていませんでした。
    コメントする場合は、個々の(学籍番号ごとの)スプレッドシートを開いて記入しないといけないのでしょうか。

    よろしくお願いします!

    • あるふ より:

      はら さん

      > コメントする場合は、個々の(学籍番号ごとの)スプレッドシートを開いて記入しないといけないのでしょうか。

      おっしゃる通りです。
      回答一覧のスプレッドシートは児童生徒と共有されていないので、個々のスプレッドシートを開いてコメントする必要があります。
      個々のスプレッドシートへのアクセスは回答一覧にリンクが追記されるようにしているので、児童生徒から質問がある場合はそちらからアクセスしてコメントする運用を想定しています。

      よろしくお願いします。

      • はら より:

        返信ありがとうございます!
        リンクから飛んで回答するという形なのですね。かしこまりました。

        ありがとうございます!

  13. とも より:

    はじめまして小学校教員のともと申します。

    子どもたちの振り返りを表形式で返す方法を探していて、こちらにたどり着きました。
    とても素晴らしいシートですね。
    light版を是非使わせていただきたいと思っています。

    学籍番号について質問があります。
    振り返りの際、学籍番号を毎回入力するような仕様になっていますが、対象が小学生のため誤入力があると予想します。
    学籍番号ではなく、収集した学校アカウントのメールアドレスまたはアカウントのみ(@の左部)をIDとしてそのまま使うことができれば、振り返りだけを入力することができると思ったのですが、そのようなことは可能でしょうか。

    よろしくお願いします。

    ※以前コメントしたのですが、反映されていなかったのでもう一度コメントします。もし、重複していましたらすみません。

    • あるふ より:

      とも さん

      返信遅くなりすみません。コメントありがとうございます。

      > 学籍番号ではなく、収集した学校アカウントのメールアドレスまたはアカウントのみ(@の左部)をIDとしてそのまま使うことができれば、振り返りだけを入力することができると思ったのですが、そのようなことは可能でしょうか。

      可能ですが、以下の理由より現在の形にしています。
      ・メールアドレスのユーザー名(@の左部)は児童生徒にとっては無意味は文字列の自治体が多い
      ・メールアドレスのユーザー名は自治体によっては児童生徒の個別のスプレッドシートをソートした際に名前の順にならないこともある
      ・↑と関連で、無意味な文字列だと、先生が児童生徒の個別のファイルを成績の参考等にするために Google ドライブ から開こうとした際に、誰のスプレッドシートかファイル名からわからない

      上記を踏まえ、児童生徒にとって意味のある番号でソートができる入力項目(例えば学年 + クラス + 出席番号)を設けています。

      > 振り返りの際、学籍番号を毎回入力するような仕様になっていますが、対象が小学生のため誤入力があると予想します。

      紙で実施する場合でも学籍番号等は記入するものなので間違わないように入力する癖をつけることも大事かとも思っています。

      とはいえ、私自身もここに関しては悩んでいて(以前は確か入力履歴が残せた気がしていたのですが)、今は Google フォーム の仕様上、基本的に入力履歴は残らないようになっていそうなので、「メールアドレスのユーザー名」でも良いのかもしれないと何度も思ったことはありますが、上記の理由から今の形になっています。

      学籍番号の入力を不要にするためにはGASの変更が必要です。プログラミングの知見がある方であればハードルはそこまで高くない変更ではありますが、知見がない場合、複数箇所の変更が必要となるため難しいかもしれません。
      ライセンスは MIT というもので改変は可能ですので、もしご興味があるのであればチャレンジしてみてください。

      回答になっていますでしょうか。よろしくお願いします。

      • とも より:

        あるふ様

        丁寧なご回答ありがとうございます。
        こちらのお返事が遅くなり申し訳ありません。

        多様な子どもがいるので、できるだけ簡単に入力できるようにしたいと思っていました。

        私の知識で改変できるかやってみようと思います。
        ありがとうございました。

  14. より:

    初めまして、Googleフォームを利用した振り返りの方法を探してここに行きつきました。

    早速利用させてもらっています。そこで問題が起きてしまったのですが、10人前後が回答した結果、トリガーが実行されてエラーが発生し、生徒個人のスプレットシートが作成されませんでした。
    その後時間をおいて回答した生徒数人分はトリガーが実行後エラーが発生することなく、スプレットシートが作成されました。
    さらに時間をおいて回答した1名分はまたエラーが発生して作成されませんでした。

    何か原因はあるのでしょうか。また、すでにエラーが発生して作られなかった分は手動で作れたりするのでしょうか。

    よろしくお願いいたします。

    • あるふ より:

      和 さん

      返信が遅くなってしまい申し訳ありません。
      なぜかスパム判定になっており、気づくのが遅れてしまいました。

      > そこで問題が起きてしまったのですが、10人前後が回答した結果、トリガーが実行されてエラーが発生し、生徒個人のスプレットシートが作成されませんでした。

      お手数ですがどのようなエラーが発生したかログをご送付いただけないでしょうか。
      ログはスクリプトエディタ(Apps Script)の左のメニューの「実行数」を
      クリックすると確認できます。
      お手数お掛けしますが、エラーが出力されている箇所の文言を
      数字も含めて送っていただけますでしょうか。

      よろしくお願いします。

      • より:

        ご回答ありがとうございます。以下がエラーです。よろしくお願いいたします。

        2024/04/23 13:34:34 エラー リトライします: 1回目(データ取得に失敗しました: Failed to retrieve form data. Please wait and try again.)
        2024/04/23 13:34:36 エラー リトライします: 2回目(データ取得に失敗しました: Failed to retrieve form data. Please wait and try again.)
        2024/04/23 13:34:38 エラー リトライします: 3回目(データ取得に失敗しました: Failed to retrieve form data. Please wait and try again.)
        2024/04/23 13:34:40 エラー リトライします: 4回目(データ取得に失敗しました: Failed to retrieve form data. Please wait and try again.)
        2024/04/23 13:34:42 エラー リトライします: 5回目(データ取得に失敗しました: Failed to retrieve form data. Please wait and try again.)
        2024/04/23 13:34:44 エラー Error: データ取得の最大リトライ回数を超えました。処理を終了します。
        at retryWithLimit(FormToSpreadsheet:241:11)
        at sendSpredsheet(FormToSpreadsheet:26:24)

        • あるふ より:

          和 さん

          エラーログのご送付ありがとうございます。
          エラー内容としては、Google フォーム からデータを取得できなかったようです。
          できる時間帯とできない時間帯があったことから、Google 側の障害に関わっているように思えます。
          GAS等の実行は、Google Cloud 上のどこかのサーバーで行われており、ユーザーには公開されていないようなのですが、該当の時間だと下記の障害に当てはまる可能性が少なからずあるかもしれません。
          https://status.cloud.google.com/incidents/P43dHoyBajdZ82B1kubv

          上記はあくまで推測となりますが、現在は解消されているようですので再度実施していただくとうまくいくかもしれません。

          また、一点前回のコメントで回答できていなかったものがあるので回答させていただきます。

          > また、すでにエラーが発生して作られなかった分は手動で作れたりするのでしょうか。

          手動で作成することは可能ですが、もう一度回答してもらった方が手間としては少ないです。
          もう一度児童生徒に回答してもらうのが難しいようでしたら下記の手順で手動で作成できるものと思われます。

          [手動で作成する手順]
          0. 回答一覧のスプレッドシートから該当の回答を見つけておく
          1. テンプレートのスプレッドシートをコピー
          2. コピーした2のファイル名を「【振り返りシート】学籍番号」に変更
           ・ 学籍番号は、0から取得
          3. 2を開き、スプレッドシート内のシート「template」をコピーして別シートを作成
          4. 3のシート名を、0の授業名に変更
          5. 4のシートを選択し、0の回答をコピペ等で入力
          6. 5のスプレッドシートファイルを該当の児童生徒と「閲覧者(コメント可)」で共有

          以上となります。うまくいくことを願っております。
          よろしくお願いします。

  15. 山田 より:

    初めまして、公立学校で教諭をしています。
    本校では、全校で行なっている取り組みがあり、その振り返り(年6回ほど)にこのプログラムを活用できればと考えています。
    注意事項にも書かれていましたが、一人の教員にアンケートの回答が集中して集まるようにしていた場合、GASを実行することができないほどの負担になる感じでしょうか・・・。
    ※全校生徒は、500名ほどいます。

    対応策として、①回答する時間を分散させる②フォームをコピーして、学年ごとに異なるフォームに集約されるようにする。などするとで、解決することは可能でしょうか。

    アドバイスをくだされば、大変助かります。よろしくお願いします。

    • あるふ より:

      山田 さん

      コメントありがとうございます。

      > 注意事項にも書かれていましたが、一人の教員にアンケートの回答が集中して集まるようにしていた場合、GASを実行することができないほどの負担になる感じでしょうか・・・。

      一回の実行は数秒で終わるため、よほどのことがない限り、制限(特に「同時実行数30」)に達することはないと思われますが、こちらは Google の仕様と児童生徒の回答次第になるので「これだと大丈夫」とお約束することは難しいです(このような回答で恐縮です…)。

      > 対応策として、①回答する時間を分散させる②フォームをコピーして、学年ごとに異なるフォームに集約されるようにする。などするとで、解決することは可能でしょうか。

      ①も②も有効な手段だと思われます。②の場合は、学年ごとに作成する異なるフォームを作るユーザー(正確にはトリガーを設定するユーザー)を別のユーザーにしないと「同時実行数30」に引っかかる可能性が出てきます(この制限はユーザー単位の制限のようです)。

      うまく行くことを願っています。
      よろしくお願いします。

      • 山田 より:

        早速のお返事ありがとうございます。
        チャレンジしてみます。

        追加での質問となり、申し訳ないのですが…。
        現在、質問内容を変更するため、プログラミング部分を書き換えたり、生徒用のシートのレイアウトを変更したりしています。
        その際、質問内容を変えたことにより?生徒用のスプレッドシートが自動的に生成されなくなってしまいました。色々と試行錯誤を重ねているのですが、どうも原因が分からずに手詰まりになってしまっています。考えられる原因がありましたらご教授いただけますと幸いです。

        • 山田 より:

          無事、先程の質問部分も解決することができました。

          ありがとうございました。

  16. ran より:

    高校の教員をしています。

    フォーム(2.2)と振り返りシートを入れ、集計もできていると思います。
    しかし、共有アイテムにスプレッドシートがなく、生徒が見ることができません。
    どうしたらいいですか?教えてください。

    • あるふ より:

      ran さん

      お試しいただきありがとうございます。

      生徒の共有アイテムに表示がないとのことですが、個別のスプレッドシートは生成されていますでしょうか。また、お手数お掛けしますがログをご送付いただけると助かります。ログはスクリプトエディタ(Apps Script)の左のメニューの「実行数」をクリックすると確認できます。エラーが出力されている箇所の文言を数字も含めて送っていただけますでしょうか。

      よろしくお願いします。

  17. 丸山 将 より:

    はじめまして
    中学校社会科の教員をしております。まーと申します。
    9月よりこちらのシステムを使わせていただいております。とても素晴らしいシステムを公開していただき誠にありがとうございます。
    1点質問です。

    Googleフォームの回答を収集するスプレットシートの列が気づいたら増えておりました。現在「Column 68」まで増えております。本来「列1」に表示される生徒のスプレットシートURLが様々な列に表示されてしまっております。こちらの問題をどのように解決したら良いでしょうか?
    よろしくお願いいたします。

    • あるふ より:

      まーさん

      ご報告ありがとうございます。
      8〜9月にかけて、Google フォーム から連携されるスプレッドシートのデフォルトのフォーマットが変更されたようです。
      https://workspaceupdates.googleblog.com/2024/08/view-and-structure-google-form-data-as-table-google-sheets.html
      日本語のアップデートブログは英語のものから数ヶ月遅れて公表されるのでキャッチできていませんでした。。)

      新しいフォーマットに対応したものにスクリプト(GAS)を変更します💦
      対応が完了しましたら再度連絡させていただきます。

    • あるふ より:

      まーさん

      新しいフォーマットに対応したものにスクリプト(GAS)を変更しました。
      本ページから再度 Google フォーム をコピーするか、本ページの コードの公開 から最新のスクリプトを今お使いのフォームのスクリプトと差し替えていただけますでしょうか。
      なお、差し替える際、FOLDER_ID のみ、今お使いのスクリプトに設定されているもののままにしておくようご注意ください。

      よろしくお願いします。

      • まー より:

        ご対応ありがとうございました。
        コードをから最新のスクリプトと入れ替えたのですがエラーの表示が出てしまします。
        それでよろしいのでしょうか?
        ご確認よろしくお願いいたします。

        エラー内容

        10:56:27 エラー リトライします: 1回目(データ取得に失敗しました: Cannot read properties of undefined (reading ‘response’))
        10:56:29 エラー リトライします: 2回目(データ取得に失敗しました: Cannot read properties of undefined (reading ‘response’))
        10:56:31 エラー リトライします: 3回目(データ取得に失敗しました: Cannot read properties of undefined (reading ‘response’))
        10:56:33 エラー リトライします: 4回目(データ取得に失敗しました: Cannot read properties of undefined (reading ‘response’))
        10:56:35 エラー リトライします: 5回目(データ取得に失敗しました: Cannot read properties of undefined (reading ‘response’))
        10:56:36 エラー
        Error: データ取得の最大リトライ回数を超えました。処理を終了します。
        retryWithLimit @ code.gs:240
        sendSpredsheet @ code.gs:19

        • あるふ より:

          まーさん

          コードの差し替えとエラーの件、報告ありがとうございます。
          エラーを拝見する限り、Google フォームからのデータをGASが受信できていないようです。

          手順12. 「トリガーを追加」画面を開くに置いて、一度設定されているトリガーを削除したのち、再設定してみてはいただけないでしょうか。

          よろしくお願いします。

  18. まー より:

    ご対応ありがとうございます。
    トリガーの再設定を行ったのですが、同じエラーとなってしまいます。
    新たにフォームをダウンロードして設定しても同じエラーとなってしまします。
    どのようにしたら良いでしょうか?

    • あるふ より:

      まーさん

      状況のご共有ありがとうございます。何か根本的なところでうまくいっていない気がします。
      使用しているアカウントは学校のものだと思いますが、個人のアカウントではどうでしょうか。
      また、フォームとGASはlight版でしょうか?それとも通常版でしょうか。

      なお、元のコードは下記に公開しているので、原因の切り分けとして一度元に戻すのも一つの手だと思います。

      お試しいただけますでしょうか。
      よろしくお願いします。

      • あるふ より:

        個別でメールでやり取りさせていただいたところ、新しいコード(v2.3)で使用できたとの報告をいただけたので、安心しました。今後ともよろしくお願いします。

  19. ハチ より:

    ハチと申します。貴重な情報提供、ありがとうございます。活用させていただきたいと思います。

    1
    添付ファイルをアップロードした際は、先生アカウントに保存されるのでしょうか? データ保存容量が小さいと対応できないでしょうか?
    2
    また、バージョン2.2で準備を完了させスタートしようと考えておりましたところ、バージョン2.3があるということですね。「v2.1から最新バージョンへの移行方法」 の記載にある手順で進めるのが一番簡易でしょうか?

    • あるふ より:

      ハチさん

      活用のご検討ありがとうございます。


      1
      > 添付ファイルをアップロードした際は、先生アカウントに保存されるのでしょうか? データ保存容量が小さいと対応できないでしょうか?

      先生アカウントに保存されます。データ保存容量の制限に達していなければ使用できます。


      2
      > また、バージョン2.2で準備を完了させスタートしようと考えておりましたところ、バージョン2.3があるということですね。「v2.1から最新バージョンへの移行方法」 の記載にある手順で進めるのが一番簡易でしょうか?

      現在公開しているバージョンは 2.3 となりますので 2.3 で進めていただけると幸いです。
      v2.2 で導入したい理由などがございましたら教えていただけると助かります。

      よろしくお願いします。

  20. ハチ より:

    あるふさん
    ご回答ありがとうございます

    1
    容量が少ないと保存容量を気にしながら利用しないといけないのかなと思いまして。それなら、容量を最大にしておいた方が良いのかななどと考えています。容量に達してしまいそうになってから、事後に対応する方法としてどのようなことが考えられますでしょうか?

    1ー2
    添付ファイルが5つ可能になっていると思いますが、これを3つまで可能にするなどの制限数を変更することはできますでしょうか?

    2
    いえ。準備しはじめていた期間が少し前だったものですから、その時の最新の2.2で準備を完了させました。この度、最終チェックを兼ねて、このページを再度閲覧させてもらったら2.3のバージョンがあるということだったので、どのように対応したらよいかなと思い質問しました。

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