彰化一整天的論壇

 找回密碼
 立即註冊
查看: 1462|回復: 14

【Google表單教學】自動選擇題題庫產生器 (可選範圍+答案...

[複製鏈接]
發表於 2021-4-2 16:31:52 | 顯示全部樓層 |閱讀模式
本帖最後由 imingho 於 2021-5-22 19:03 編輯

自動選擇題題庫產生器 (可選範圍+答案類型+讀入工作表+固定網址)
google_from_exam_fix_url.jpg

請建立複本再使用.

  1. function onOpen() {
  2.   //update
  3.   /*
  4.   彰化一整天的blog: http://blog.bestdaylong.com
  5.   彰化一整天的論壇: http://discuz.bestdaylong.com
  6.   
  7.   影音教學: https://youtu.be/dNQvhb_T34c

  8.   作者:蔡明和
  9.   電子郵件:imingho@gmail.com
  10.   
  11.     v4.0 2021.04.04  第四版
  12.   
  13.   */
  14.   
  15.   var ss = SpreadsheetApp.getActiveSpreadsheet();

  16.   // These are the 2 menu entries
  17.   var menuEntries = [
  18.     {name: "自動產生選擇題題庫", functionName: "bestdaylong_auto_google_form_quiz"},

  19.     ];

  20.   // After defining the menu entries, then you define the menu itself
  21.   ss.addMenu("彰化一整天Blog工具", menuEntries);
  22.   
  23. }
  24. function bestdaylong_auto_google_form_quiz() {
  25.   //自動產生Google表單試題 by 彰化一整天blog
  26.   
  27.   //程式碼及討論 http://discuz.bestdaylong.com/thread-39245-1-1.html
  28.   
  29.   //影音教學: https://youtu.be/dNQvhb_T34c
  30.   
  31.   //儲存格格式 編號        題目        答案        選項1        選項2        選項3        選項4

  32.   
  33.   
  34.   var sheet=SpreadsheetApp.getActiveSheet();  //取得目前工作表

  35.   var exam = sheet.getRange("B1").getValue().toString(); //題庫工作表

  36.   var formUrl=sheet.getRange("B10").getValue().toString();

  37.   var startNum=sheet.getRange("B11").getValue();

  38.   var examSheet=SpreadsheetApp.getActiveSpreadsheet().getSheetByName(exam);
  39.   
  40.   var examname = sheet.getRange("B2").getValue().toString(); //考卷名稱

  41.   var form = FormApp.openByUrl(formUrl);

  42.   var examRequired=sheet.getRange("B12").getValue(); //是否必填



  43.   

  44.   //清除之前記錄
  45.   var items = form.getItems();
  46.   
  47.   Logger.log("I="+items.length);

  48.   for (var i=items.length-1; i>=startNum-1; i--) {
  49.     form.deleteItem(i);
  50.   }
  51.   
  52.   
  53.   form.setIsQuiz(true);  //設定表單為考試

  54.   var m=examSheet.getLastColumn();//取得欄數
  55.   var n=sheet.getRange("B6").getValue();//取得筆數
  56.   var i,j;//迴圈變數   

  57.   var min,max;
  58.   var min=sheet.getRange("B4").getValue();
  59.   var max=sheet.getRange("B5").getValue();

  60.   var examType=sheet.getRange("B3").getValue();

  61.   var showExamNo=sheet.getRange("B7").getValue();  //是否顯示原題號

  62.   var showNo=sheet.getRange("B8").getValue();  //是否顯示題號

  63.   var QuestionType=sheet.getRange("B9").getValue();  //答案類型
  64.   
  65.   var score=100/n;  //計算每題分數
  66.   
  67.   var answer;//正確答案

  68.   var question_no=[];

  69.   question_no=get_rand(min,max,n);

  70.   var data;

  71.   
  72.   
  73.   var exam_no;//取得題號
  74.   
  75.   Logger.log(question_no);

  76.   for(i=0;i<n;i++){   //從第0筆開始讀取  
  77.     //var item = form.addListItem();//下拉選單
  78.     exam_no=question_no[i]+1;//轉換成第幾列
  79.     if(examType=="選擇題")
  80.       item = form.addMultipleChoiceItem();//選擇題
  81.     else
  82.       item = form.addListItem();//下拉式選單

  83.     var data="";
  84.     if(showNo=="是")
  85.     {
  86.         data=(i+1)+'.';

  87.     }
  88.     Logger.log(exam_no);
  89.     data+=examSheet.getRange(exam_no,2).getValue();
  90.     if(showExamNo=="是")
  91.       data+=',原題號('+examSheet.getRange(exam_no,1).getValue()+')';
  92.       
  93.     answer=examSheet.getRange(exam_no,3).getValue();
  94.     item.setTitle(data);
  95.     var answers=[];//設定答案選項
  96.     for(j=4;j<=m;j++){  //從第4欄往右讀取
  97.       switch(QuestionType)
  98.       {
  99.       case "數字1.2.3.4.":
  100.         data=(j-3)+'.';
  101.         break;
  102.       case "數字(1)(2)(3)(4)":
  103.         data="("+(j-3)+')';
  104.         break;
  105.       case "英文(A)(B)(C)(D)":
  106.         data="("+String.fromCharCode(j-3+64)+')';
  107.         break;   
  108.       case "英文A.B.C.D.":   
  109.         data=String.fromCharCode(j-3+64)+'.';
  110.         break;
  111.       case "無任何提示":           
  112.         data="";
  113.         break;
  114.       }
  115.        data+=examSheet.getRange(exam_no,j).getValue(); //取得題目選項

  116.        answers[j-4]=item.createChoice(data, answer==(j-3)); //陣列從0開始,儲存格是從1開始
  117.     }
  118.     item.setChoices(answers);//填入選項
  119.     if(examRequired=="是")
  120.        item.setRequired(true); //設為必填
  121.     item.setPoints(score);//設定每題分數
  122.   }
  123.   sheet.getRange("B15").setValue(form.getPublishedUrl());
  124.   sheet.getRange("B16").setValue(form.getEditUrl());
  125.   //Logger.log('公開網址: ' + form.getPublishedUrl());
  126.   //Logger.log('修改網址: ' + form.getEditUrl());  
  127.   Browser.msgBox('執行結果','公開網址: ' + form.getPublishedUrl()+'\\n修改網址: ' + form.getEditUrl(), Browser.Buttons.OK);
  128. }

  129. function get_rand(min,max,n)
  130. {
  131.   var question_no=[];
  132.   var m,temp;

  133.   for(i=min;i<=max;i++)
  134.   {
  135.     question_no[i-min]=i;
  136.   }
  137.   for(i=0;i<n;i++)
  138.   {
  139.     m=parseInt((max-min+1)* Math.random());
  140.     temp=question_no[i];
  141.     question_no[i]=question_no[m];
  142.     question_no[m]=temp;
  143.   }

  144.   return question_no;
  145. }

  146. function test_rand()
  147. {
  148.   var min,max;
  149.   var question_no=[];
  150.   var n,m,temp;
  151.   min=1;
  152.   max=20;
  153.   n=10;
  154.   for(i=min;i<=max;i++)
  155.   {
  156.     question_no[i-min]=i;
  157.   }
  158.   for(i=0;i<n;i++)
  159.   {
  160.     m=parseInt((max-min+1)* Math.random());
  161.     temp=question_no[i];
  162.     question_no[i]=question_no[m];
  163.     question_no[m]=temp;
  164.   }

  165.   Logger.log(question_no);
  166. }
  167. function test1()
  168. {
  169.    var sheet=SpreadsheetApp.getActiveSheet();  //取得目前工作表

  170.   var examSheet=SpreadsheetApp.getActiveSpreadsheet().getSheetByName("題庫");
  171.   
  172.   var examname = examSheet.getRange("A2").getValue().toString(); //考卷名稱
  173.   


  174.   var m=examSheet.getLastColumn();//取得欄數
  175.   var n=sheet.getRange("B5").getValue();//取得筆數
  176.   var i,j;//迴圈變數   

  177.   var min,max;
  178.   var min=sheet.getRange("B3").getValue();
  179.   var max=sheet.getRange("B4").getValue();
  180.   
  181.   var score=100/(n-1);  //計算每題分數

  182. }
  183. function GetSheetNames() {
  184.   //取得所有工作表到陣列
  185.   var out = new Array()
  186.   var sheets = SpreadsheetApp.getActiveSpreadsheet().getSheets();
  187.   for (var i=0 ; i<sheets.length ; i++)
  188.   {
  189.     if(sheets[i].getName()!="參數設定")
  190.       out.push( [ sheets[i].getName() ] )
  191.   }
  192.   
  193.   return out
  194. }
  195. function GetExamSheet()
  196. {
  197.   //設定下拉選項
  198.    var data;
  199.    data=GetSheetNames();


  200.   var spreadsheet = SpreadsheetApp.getActive();
  201.   spreadsheet.getRange('B1').activate();
  202.   spreadsheet.getRange('B1').setDataValidation(SpreadsheetApp.newDataValidation()
  203.   .setAllowInvalid(true)
  204.   .requireValueInList(data, true)
  205.   .build());
  206. }



複製代碼


回復

使用道具 舉報

 樓主| 發表於 2021-5-22 18:56:19 | 顯示全部樓層
本帖最後由 imingho 於 2021-5-22 19:03 編輯
arthurchen 發表於 2021-5-22 17:14
謝謝版主回答, 這兩天認真在研究您這個作品, 看看能否實際應用, 有點小問題請教。
這個最後產生的表單全是" ...

您好,
    只要將程式中的
  1. item.setRequired(true); //設為必填
複製代碼

改成
  1. //item.setRequired(true); //設為必填
複製代碼

就可以了.我已經加上選項來讓網友可以在前台就選擇。
回復 支持 1 反對 0

使用道具 舉報

發表於 2021-5-20 16:25:24 | 顯示全部樓層
很棒的範例!
請教建立副本之後, 想要試試建立題庫, 先按下"載入題庫工作表"沒問題, 接下來按下"產生題庫"按鈕後, 出現錯誤訊息:
Exception: 找不到指定 ID 的項目。可能是你尚未編輯過這個項目,或者沒有編輯這個項目的權限。詳細資料
是哪裡有問題?
謝謝!!
回復 支持 反對

使用道具 舉報

 樓主| 發表於 2021-5-20 19:42:03 | 顯示全部樓層
arthurchen 發表於 2021-5-20 16:25
很棒的範例!
請教建立副本之後, 想要試試建立題庫, 先按下"載入題庫工作表"沒問題, 接下來按下"產生題庫" ...

儲存格B10是存放您自己產生的表單。
回復 支持 反對

使用道具 舉報

發表於 2021-5-22 17:14:13 | 顯示全部樓層
謝謝版主回答, 這兩天認真在研究您這個作品, 看看能否實際應用, 有點小問題請教。
這個最後產生的表單全是"必答", 一般來說大概只有開頭的學號、姓名之類的問題才會設定必答, 題目的部分一般都設定成可答可不答, 是程式的哪個地方需要修改?
回復 支持 反對

使用道具 舉報

發表於 2021-5-29 14:39:44 | 顯示全部樓層
一般選擇題是四個欄位選項,可以在第五個選項改成,錯誤答案的解析位置嗎,一般題庫會有匯出解析的內容,可以在作答後,自己看一下解析。
google form 本來就有提供 setFeedbackForIncorrect(feedback) ,這個函數
回復 支持 反對

使用道具 舉報

 樓主| 發表於 2021-5-29 16:02:44 | 顯示全部樓層
1ping 發表於 2021-5-29 14:39
一般選擇題是四個欄位選項,可以在第五個選項改成,錯誤答案的解析位置嗎,一般題庫會有匯出解析的內容,可 ...

我有查過,但是我試不出來,您也可以試看看.
  1. // Open a form by ID and add a new list item.
  2. var form = FormApp.openById('1234567890abcdefghijklmnopqrstuvwxyz');
  3. var item = form.addListItem();
  4. item.setTitle('Do you prefer cats or dogs?');
  5. // Set "Dogs" as the correct answer to this question.
  6. item.setChoices([
  7.   item.createChoice('Dogs', true),
  8.   item.createChoice('Cats', false)]);
  9. // Add feedback which will be shown for correct responses; ie "Dogs".
  10. item.setFeedbackForCorrect(
  11.     FormApp.createFeedback().setDisplayText("Dogs rule, cats drool.").build());
複製代碼


官網的說明: https://developers.google.com/ap ... tFeedbackForCorrect(QuizFeedback)
回復 支持 反對

使用道具 舉報

發表於 2021-5-29 17:18:04 | 顯示全部樓層
本帖最後由 1ping 於 2021-5-29 17:24 編輯

網路上有人是放在目題的下一欄應該是第5欄,x 應該是列數:
        if (d[x][5] !== ""){
          var incorrectFeedback = FormApp.createFeedback().setText(d[x][5]).build();
          q.setFeedbackForIncorrect(incorrectFeedback);
        }
回復 支持 反對

使用道具 舉報

 樓主| 發表於 2021-5-29 19:41:12 | 顯示全部樓層
1ping 發表於 2021-5-29 17:18
網路上有人是放在目題的下一欄應該是第5欄,x 應該是列數:
        if (d[x][5] !== ""){
          var i ...

好的.感謝提供,我再來研究看要如何修改.
回復 支持 反對

使用道具 舉報

 樓主| 發表於 2021-5-29 22:46:21 | 顯示全部樓層
1ping 發表於 2021-5-29 14:39
一般選擇題是四個欄位選項,可以在第五個選項改成,錯誤答案的解析位置嗎,一般題庫會有匯出解析的內容,可 ...

我已加上您說的詳解.格式請看試算表.
回復 支持 反對

使用道具 舉報

您需要登錄後才可以回帖 登錄 | 立即註冊

本版積分規則

Archiver|手機版|小黑屋|彰化一整天的論壇(Excel,Office)

GMT+8, 2021-7-25 19:32 , Processed in 0.126399 second(s), 20 queries .

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回復 返回頂部 返回列表