2014年12月7日 星期日

以Google Sheet題庫產生Google Forms隨機測驗卷

凌晨3:52 Posted by Envisioning U-Commerce Lab

利用Google Spreadsheet可撰寫App Scripts的特性,搞懂Google Forms相關的method就可以撰寫程式來將Spreadsheet的資料自動轉為Forms的問題。

這個想法的落實,是參考了下列資訊:

在前述第一個參考影片裏面所提供的Script 1,對於中文版的Spreadsheet來說需要改寫一小部分字串為中文,而且為了結合第二個參考資訊的題庫概念再進一步增寫有加註的程式碼,在直接將改寫好的Script並已建立題庫內容的Spreadsheet公開給大家參考,不必客氣將該檔案建立副本存到自己的雲端硬碟,開啟該Spreadsheet就能從主選單的[工具]>[指令碼編輯器]進入看到完整的Script了。




接下來,請自己在雲端硬碟新建一個表單(但無需建立問題),然後在網址列找出如下部分的該表單ID,將其取代前述圖片標示處,並按下存檔,再按下執行(第一次會出現需要授權的視窗)。



程式執行完成,就可以看到新表單自動建立了幾道問題。若再按下執行一次就會清除原有問題並再隨機建立新問題。







接下來,解釋整個Spreadsheet與Script的設計細節吧...




首先,這個例子是引用政府開放資料平台的智慧財產權小題庫,其下載後的ODT檔案就是個Word檔,內容如下所示。若要將這個文件裡的題目轉入Spreadsheet成為一列一個題目,是有個小技巧來加快處理效率的,就是先用Word的[文字轉換為表格]功能將這些一個個段落的題目轉換成表格內的一列列內容。





於是,在Word將整個表個選取複製起來,再到Spreadsheet貼上就能成為一個題目存放在一格裡面,這樣比起做數十次的複製貼上要快多了。然後,再手動刪除每一題的題號及答案。重複這些動作,將題庫分門別類存放在幾個工作表裡面。




一開始提到參考第一個影片後改寫的Script會對工作表1進行一些處理,所以在工作表1的第一列先定義了題號、類型、題目、說明、圖片URL、選項...等欄位名稱,然後在第二列開始就會以 vlookup() 來設計從後面題庫工作表隨機複製題目過來到工作表1,就如下列畫面所示,加了紅底的是來自於智產權是非題庫,加了橘底的是來自於商標權是非題庫,加了黃底的是來自於專利權是非題庫。




在A2那格的設定是這樣的 : 


=vlookup(randbetween(1,max('智產權是非題'!$A:$A)),'智產權是非題'!$A$1:$A,1,false)

解釋 max(範圍首, 尾) 的作用,是指定'智產權是非題'工作表中的整個A欄為範圍找出最大值,因為A欄就是題號,於是這樣就能取得總共有多少題的數值。再來解釋 randbetween(最小值, 最大值) 的作用,就是從指定數值範圍內產生一個隨機值。用這兩個函數把題庫工作表的所有題目都納入可能選擇,並隨機挑出一個題號。至於 vlookup(搜尋值, 範圍, 索引, 布林值) 請自行爬文搞懂,就可以了解是如何從'智產權是非題'工作表中的A欄挑出一格資料複製到A2這格(如果你懂資料庫就會發現這過程很像是對資料表下達查詢指令找出符合條件記錄並取得該記錄的指定欄位內容)。


在B2那格的設定是這樣的 : 


=vlookup(A2,'智產權是非題'!$A$1:$B,2,false)

在C2那格的設定是這樣的 : 


=vlookup(A2,'智產權是非題'!$A$1:$C,3,false)

在F2那格的設定是這樣的 : 


=vlookup(A2,'智產權是非題'!$A$1:$G,4,false)

在G2那格的設定是這樣的 : 


=vlookup(A2,'智產權是非題'!$A$1:$G,5,false)


這幾格就把'智產權是非題'工作表中與A2那格題號相同的類型、題目、選項...等內容分別複製過來,這部分應該無需多做解釋了吧。

完成第二列所有格子的設計後,再標示成紅底,並將整列複製起來,貼到第二、三、四列等等,也就是要出幾題就複製多少列。

依此類推,也分別設計如何隨機複製'商標權是非題'工作表中的題目,以及如何隨機複製專利權是非題'工作表中的題目,如此就完成工作表1的整個設計了。在操作過程發現工作表1只要有編輯動作(增刪改)就會讓每一格以 vlookup() 套用的資料都會再更新過,所以才在Script中的第5行程式碼進行清除本來就無資料的G1這格:

              // 下列是工作表1只要有編輯動作(增刪改)就會觸發亂數更新達成重新選題之動作
              ss.getRange("G1").clearContent();




最後,如果不希望使用者那麼麻煩到指令碼編輯器按下執行按鈕,那就乾脆在工作表1上面放個顯眼的圖案當作按鈕吧,並在圖案上設定[指派指令碼]輸入Script的函數名稱。










如此一來,就能讓使用者按下該圖案按鈕就再執行一次myFunction的動作,這樣要重新隨機出題的只要按一下即可,這樣的Spreadsheet檔案交給使用者之後,就什麼操作都不必教了。