彰化一整天的論壇

 找回密碼
 立即註冊
查看: 785|回復: 0

V7.0自動選擇題題庫產生器

[複製鏈接]
發表於 2021-7-1 17:21:19 | 顯示全部樓層 |閱讀模式
本帖最後由 imingho 於 2021-7-7 09:15 編輯

exam_v7.jpg
    v7.0 2021.07.01  第七版
    新增
    1.可設定題目是否亂數
    2.可設定每題分數
    3.可學生自動產生連結
    4.自動判斷多選題
    5.可新增區段名稱



請建立複本再使用.https://docs.google.com/spreadsh ... _pPGK196bbrAWE/copy

  1. function doGet(e) {
  2.   //自動產生題庫
  3.   return bestdaylong_auto_google_form_quiz(1);
  4. }
  5. function run_exam_by_form()
  6. {
  7.   bestdaylong_auto_google_form_quiz(0);
  8. }

  9. function onOpen() {
  10.   //update
  11.   /*
  12.   彰化一整天的blog: http://blog.bestdaylong.com
  13.   彰化一整天的論壇: http://discuz.bestdaylong.com
  14.   
  15.   影音教學: https://youtu.be/3cCkcUXo-lc

  16.   作者:蔡明和
  17.   電子郵件:imingho@gmail.com
  18.   
  19.     v7.0 2021.07.01  第七版
  20.     新增
  21.     1.可設定題目是否亂數
  22.     2.可設定每題分數
  23.     3.可學生自動產生連結
  24.     4.自動判斷多選題
  25.     5.可新增區段名稱

  26.     修改
  27.     1.選項改成有5個選項
  28.     2.修正題數0表示所選範圍之全部資料
  29.   
  30.   */
  31.   
  32.   var ss = SpreadsheetApp.getActiveSpreadsheet();

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

  36.     ];

  37.   // After defining the menu entries, then you define the menu itself
  38.   ss.addMenu("彰化一整天Blog工具", menuEntries);
  39.   
  40. }
  41. function bestdaylong_auto_google_form_quiz(UserExam) {
  42.   //自動產生Google表單試題 by 彰化一整天blog
  43.   
  44.   //程式碼及討論 hhttp://discuz.bestdaylong.com/thread-39285-1-1.html
  45.   
  46.   //影音教學: https://youtu.be/3cCkcUXo-lc
  47.   
  48.   //儲存格格式 編號        題目        答案        選項1        選項2        選項3        選項4    空格   詳解

  49.   
  50.   
  51.   var sheet=SpreadsheetApp.getActiveSheet();  //取得目前工作表

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

  53.   

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

  55.   var examSheet=SpreadsheetApp.getActiveSpreadsheet().getSheetByName(exam);
  56.   
  57.   var examname = sheet.getRange("B2").getValue().toString(); //考卷名稱


  58.   


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

  60.   var formID;

  61.   var form;

  62.   if(UserExam==1)
  63.   {
  64.     formID=copyFile(UserExam);//建立複本
  65.     Logger.log("GetFromID="+formID);
  66.     form=FormApp.openById(formID);
  67.   }
  68.   else
  69.     form = FormApp.openByUrl(formUrl);


  70.   form.setTitle(examname); //設定試卷名稱

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


  72.   var AnswerRand=sheet.getRange("B13").getValue(); //答案是否亂數

  73.   var QuestionRand=sheet.getRange("B15").getValue(); //出題是否亂數
  74.   

  75.   //清除之前記錄
  76.   var items = form.getItems();
  77.   
  78.   Logger.log("I="+items.length);

  79.   for (var i=items.length-1; i>=startNum-1; i--) {
  80.     form.deleteItem(i);
  81.   }
  82.   
  83.   
  84.   form.setIsQuiz(true);  //設定表單為考試

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

  88.   var min,max;
  89.   var min=sheet.getRange("B4").getValue();
  90.   var max=sheet.getRange("B5").getValue();

  91.   if(n==0)
  92.   {
  93.     n=max-min+1;
  94.   }

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

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

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

  98.   var QuestionType=sheet.getRange("B9").getValue();  //答案類型
  99.   
  100.   var score=sheet.getRange("B16").getValue();  //計算每題分數



  101.   if(score==0)
  102.     score=100/n;

  103.   
  104.   var answer;//正確答案

  105.   var question_no=[];

  106.   if(QuestionRand=="是")
  107.     question_no=get_rand(min,max,n);
  108.   else
  109.     question_no=get_no(min,max,n);

  110.   var data;

  111.   
  112.   var OptionOffset=0;


  113.   
  114.   var exam_no;//取得題號
  115.   
  116. var reason;//詳解

  117.   var isComment;//是否有詳解
  118.   
  119.   //Logger.log(question_no);

  120.   //檢查是否有詳解
  121.   if(examSheet.getRange(1,m-1).getValue()=="" ||  examSheet.getRange(1,m).getValue()=="")
  122.     {  //有詳解
  123.         m=m-2;
  124.         isComment=true;
  125.     }

  126.   var t;
  127.   var t1;

  128.   for(i=0;i<n;i++){   //從第0筆開始讀取  
  129.     //var item = form.addListItem();//下拉選單
  130.     exam_no=question_no[i]+1;//轉換成第幾列

  131.     var data="";
  132.     if(showNo=="是")
  133.     {
  134.         data=(i+1)+'.';

  135.     }
  136.     Logger.log(exam_no);
  137.     data+=examSheet.getRange(exam_no,2).getValue();
  138.     if(showExamNo=="是")
  139.       data+=',原題號('+examSheet.getRange(exam_no,1).getValue()+')';

  140.     Logger.log(data);

  141.     answer=parseInt(examSheet.getRange(exam_no,3).getValue(),10);

  142.     answer=answer.toString();

  143.     if(answer.length>1) //答案2個以上
  144.       item=form.addCheckboxItem();
  145.     else if(examType=="選擇題")
  146.       item = form.addMultipleChoiceItem();//選擇題      
  147.     else
  148.       item = form.addListItem();//下拉式選單


  149.     item.setTitle(data);





  150.     var answers=[];//設定答案選項

  151.       if(AnswerRand=="是")
  152.       {
  153.         //產一位移數數字1到3
  154.         OptionOffset=parseInt(3* Math.random())+1;
  155.       }

  156.     answer=answer.toString();

  157.     for(j=4;j<=m;j++){  //從第4欄往右讀取


  158.    
  159.       switch(QuestionType)
  160.       {
  161.       case "數字1.2.3.4.5.":
  162.         data=(j-3)+'.';
  163.         break;
  164.       case "數字(1)(2)(3)(4)(5)":
  165.         data="("+(j-3)+')';
  166.         break;
  167.       case "英文(A)(B)(C)(D)(E)":
  168.         data="("+String.fromCharCode(j-3+64)+')';
  169.         break;   
  170.       case "英文A.B.C.D.E.":   
  171.         data=String.fromCharCode(j-3+64)+'.';
  172.         break;
  173.       case "無任何提示":           
  174.         data="";
  175.         break;
  176.       }
  177.        t=(j-4+OptionOffset)%(m-4+1)+4;
  178.        data+=examSheet.getRange(exam_no,t).getValue(); //取得題目選項

  179.        //t1=(j+OptionOffset)%(m-4+1);
  180.        t1=(m-4+1+answer-OptionOffset-1)%(m-4+1);//計算位移後的答案
  181.        Logger.log('t='+t+"-Answer="+answer+"-Offset="+OptionOffset+"-t1="+t1+"-data="+data+',t-3='+(t-3)+'j-4='+(j-4));
  182.        answers[j-4]=item.createChoice(data, answer.indexOf(t-3)!=-1); //陣列從0開始,儲存格是從1開始
  183.     }

  184.     if(isComment==true)
  185.     {
  186.        reason=examSheet.getRange(exam_no,m+2).getValue();
  187.         if(reason!='')
  188.         {
  189.           item.setFeedbackForIncorrect(
  190.           FormApp.createFeedback().setText(reason).build());
  191.           item.setFeedbackForCorrect(
  192.           FormApp.createFeedback().setText(reason).build());
  193.         }
  194.     }


  195.     item.setChoices(answers);//填入選項
  196.     if(examRequired=="是")
  197.        item.setRequired(true); //設為必填
  198.     item.setPoints(score);//設定每題分數
  199.   

  200.   }

  201.   //Logger.log('公開網址: ' + form.getPublishedUrl());
  202.   //Logger.log('修改網址: ' + form.getEditUrl());  

  203.     if(UserExam==1)
  204.       return HtmlService.createHtmlOutput("<center><p><font size='7'><a href=" + form.getPublishedUrl()+ ">點我開始進行【"+examname+"】測驗</a></font></p></center>");
  205.     else
  206.     {
  207.         sheet.getRange("B20").setValue(form.getPublishedUrl());
  208.         sheet.getRange("B21").setValue(form.getEditUrl());
  209.             Browser.msgBox('執行結果','公開網址: ' + form.getPublishedUrl()+'\\n修改網址: ' + form.getEditUrl(), Browser.Buttons.OK);
  210.     }


  211.    
  212. }
  213. function add_PageBreak()
  214. {
  215.    
  216.   var sheet=SpreadsheetApp.getActiveSheet();  //取得目前工作表

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



  218.   var form;


  219.   form = FormApp.openByUrl(formUrl);

  220.   var examname = Browser.inputBox('彰化一整天Google表單題庫產生器', '請輸入區段名稱', Browser.Buttons.OK_CANCEL); //區段名稱


  221.   form.addPageBreakItem().setTitle(examname); //設定區段

  222.   

  223.   sheet.getRange("B10").setValue(form.getEditUrl());
  224.   sheet.getRange("B20").setValue(form.getPublishedUrl());
  225.   sheet.getRange("B21").setValue(form.getEditUrl());
  226.   Browser.msgBox('執行結果','公開網址: ' + form.getPublishedUrl()+'\\n修改網址: ' + form.getEditUrl(), Browser.Buttons.OK);
  227. }


  228. function add_form()
  229. {
  230.    
  231.   var sheet=SpreadsheetApp.getActiveSheet();  //取得目前工作表

  232.   var examname = sheet.getRange("B2").getValue().toString(); //題庫工作表

  233.   var field = sheet.getRange("B14").getValue().toString(); //欄位名稱


  234.   var form = FormApp.create(examname);  //建立表單

  235.   form.setIsQuiz(true);  //設定為考試


  236.   var fields=field.split(",");

  237.   for(var i=0;i<fields.length;i++)
  238.   {
  239.     var item=form.addTextItem();
  240.     item.setTitle(fields[i]);
  241.     item.setRequired(true); //設為必填
  242.   }

  243.   form.addPageBreakItem().setTitle(examname); //設定區段

  244.   

  245.   sheet.getRange("B10").setValue(form.getEditUrl());
  246.   sheet.getRange("B20").setValue(form.getPublishedUrl());
  247.   sheet.getRange("B21").setValue(form.getEditUrl());
  248.   Browser.msgBox('執行結果','公開網址: ' + form.getPublishedUrl()+'\\n修改網址: ' + form.getEditUrl(), Browser.Buttons.OK);
  249. }

  250. function get_no(min,max,n)
  251. {
  252.   var question_no=[];
  253.   var i,m=0;

  254.   for(var i=min;i<=max;i++)
  255.   {
  256.     m=m+1;
  257.     question_no[i-min]=i;
  258.     if(m==n)
  259.       break;
  260.   }
  261.   return question_no;

  262. }

  263. function get_rand(min,max,n)
  264. {
  265.   var question_no=[];
  266.   var m,temp;

  267.   for(i=min;i<=max;i++)
  268.   {
  269.     question_no[i-min]=i;
  270.   }
  271.   for(i=0;i<n;i++)
  272.   {
  273.     m=parseInt((max-min+1)* Math.random());
  274.     temp=question_no[i];
  275.     question_no[i]=question_no[m];
  276.     question_no[m]=temp;
  277.   }

  278.   return question_no;
  279. }

  280. function test_rand()
  281. {
  282.   var min,max;
  283.   var question_no=[];
  284.   var n,m,temp;
  285.   min=1;
  286.   max=20;
  287.   n=10;
  288.   for(i=min;i<=max;i++)
  289.   {
  290.     question_no[i-min]=i;
  291.   }
  292.   for(i=0;i<n;i++)
  293.   {
  294.     m=parseInt((max-min+1)* Math.random());
  295.     temp=question_no[i];
  296.     question_no[i]=question_no[m];
  297.     question_no[m]=temp;
  298.   }

  299.   Logger.log(question_no);
  300. }
  301. function test1()
  302. {
  303.    var sheet=SpreadsheetApp.getActiveSheet();  //取得目前工作表

  304.   var examSheet=SpreadsheetApp.getActiveSpreadsheet().getSheetByName("題庫");
  305.   
  306.   var examname = examSheet.getRange("A2").getValue().toString(); //考卷名稱
  307.   


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

  311.   var min,max;
  312.   var min=sheet.getRange("B3").getValue();
  313.   var max=sheet.getRange("B4").getValue();
  314.   
  315.   var score=100/(n-1);  //計算每題分數

  316. }
  317. function GetSheetNames() {
  318.   //取得所有工作表到陣列
  319.   var out = new Array()
  320.   var sheets = SpreadsheetApp.getActiveSpreadsheet().getSheets();
  321.   for (var i=0 ; i<sheets.length ; i++)
  322.   {
  323.     if(sheets[i].getName()!="參數設定")
  324.       out.push( [ sheets[i].getName() ] )
  325.   }
  326.   
  327.   return out
  328. }
  329. function GetExamSheet()
  330. {
  331.   //設定下拉選項
  332.    var data;
  333.    data=GetSheetNames();


  334.   var spreadsheet = SpreadsheetApp.getActive();
  335.   spreadsheet.getRange('B1').activate();
  336.   spreadsheet.getRange('B1').setDataValidation(SpreadsheetApp.newDataValidation()
  337.   .setAllowInvalid(true)
  338.   .requireValueInList(data, true)
  339.   .build());
  340. }

  341. function copyFile(UserExam)
  342. {
  343.   //複製檔案

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

  345.   var examname = sheet.getRange("B2").getValue().toString(); //題庫工作表


  346.   //var UserExam=sheet.getRange("B17").getValue();  //學生登入自動產生表單

  347.   if(UserExam==1)
  348.   {
  349.     examname=examname+"-"+Utilities.formatDate(new Date(),"GMT+8","yyyyMMdd HH:mm:ss");
  350.   }  

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

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

  353.   var form_id=form.getId() ;

  354.   

  355.   //var fid=DriveApp.getFileById();

  356.   //取得目前檔案所在資料夾
  357.   //var folderId = DriveApp.getFileById(form_id).getParents().next().getId();

  358.   Logger.log(form_id);

  359.   var form1_id=DriveApp.getFileById(form_id).makeCopy(examname).getId();
  360.   Logger.log("form1_id="+form1_id);
  361.   return form1_id;
  362.   
  363. }

複製代碼



回復

使用道具 舉報

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

本版積分規則

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

GMT+8, 2021-9-21 00:55 , Processed in 0.104658 second(s), 19 queries .

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

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