# 將題庫轉為Google表單
###### tags: `Google` `Apps Script`
## 關於本文
::: danger
:book: **資料來源** [題庫批次匯入google表單](http://n.sfs.tw/content/index/14616?noframe=true)
:::
:memo: **版本紀錄**
* 2021/05/23 四個選項的單選題跟簡答題
* 2021/05/24 增加多選題、簡化程式碼
* 2022/06/27 單選題增加選項數量,找到程式碼中`let optionLength = 7;`將數字改為您需要的選項數量即可
:::info
:bulb: **提示** 在圖片上按右鍵選擇[在新分頁開啟圖片]可以看大圖
:::
一些murmur:
* 最近收到一些要求範本存取權的信件,各位老師們阿~請把範本內容複製到您自己建立的試算表,這樣建立出來的表單您才有編修權限
## 一、建立題目檔案
### 建立試算表
按[建立]選擇[Google試算表]
![](https://i.imgur.com/aMozDsb.png)
### 依照格式輸入題目
1. 幫考卷命名
2. 輸入題目及配分
範例:[範例檔案](https://docs.google.com/spreadsheets/d/1ArPLXxtxiTHO0ox1NLLGfezLCWFHu7Oky6fBqPn_vVg/edit?usp=sharing) ※題目類型(A:單選 B:簡答題 C:多選題)
:::info
:bulb: **提示** 請在您的雲端硬碟建立與範例檔案相同的試算表,這樣做出來的題庫您才有權限可以編修
:::
| 題目類型 | 配分 | 題目 | 答案 | 選項1 | 選項2 | 選項3 | 選項4 |
| -------- | -------- | -------- | -------- | -------- | -------- | -------- | -------- |
| A | 25 | MP3 是何種檔案的格式? | 2 | 圖片 | 聲音 | 文書 | |
| B | 25 | 國文老師是誰? | | | | | |
| C | 25 | 水調歌頭作者 | 1,3 | 蘇東坡 | 蘇洵 | 蘇軾 | 蘇轍 |
![](https://i.imgur.com/jHQ8Axv.png)
## 二、編輯指令
### 進入編輯器
3. 按下[工具]>[指令碼編輯器]
![](https://i.imgur.com/KxmaaQe.png)
### 重新命名專案
4. 重新命名專案
5. 儲存名稱
![](https://i.imgur.com/OhlNKGI.png)
### 在編輯器的地方貼上下列程式碼
把原本編輯器內的`function myFunction() {}`刪掉取代成下列程式碼
```javascript=
/**
* 主程式
*/
function main() {
//使用者設定區塊START
let url = 'https://docs.google.com/spreadsheets/d/1ArPLXxtxiTHO0ox1NLLGfezLCWFHu7Oky6fBqPn_vVg/edit#gid=0'; //試算表網址
let questionSize = 3; //匯入題目數
let optionLength = 7; //選項數量
//使用者設定區塊END
let exam = GetSheet(url, questionSize);
GenerateExam(exam);
}
/**
* 轉換試算表內容為測驗Object
* @param {string} url 試算表網址
* @param {int} questionSize 匯入題目數量
*/
function GetSheet(url, questionSize) {
let exam = {};
exam.url = url;
exam.size = questionSize;
Logger.log(exam.size);
let questions = [];
let SpreadSheet = SpreadsheetApp.openByUrl(exam.url);
let sheet = SpreadSheet.getSheets()[0];
let name = sheet.getSheetName();
exam.name = name;
//從試算表第二列開始取N(題目數量)列
for (let i = 2; i < exam.size + 2; i++) {
question = {};
if (!sheet.getRange(i, 1).isBlank()) {
//題目類型(第一欄)
question.type = sheet.getSheetValues(i, 1, 1, 1);
//題目配分(第二欄)
question.point = sheet.getSheetValues(i, 2, 1, 1);
//題目(第三欄)
question.description = sheet.getSheetValues(i, 3, 1, 1);
//正確答案(第四欄)
question.answer = sheet.getSheetValues(i, 4, 1, 1).toString().split(',').map(function (item) {
return parseInt(item, 10);
});
let options = [];
//選項, 第五欄位之後
for (let j = 5; j < (5 + optionLength); j++) {
if (!sheet.getRange(i, j).isBlank()) {
let option = sheet.getSheetValues(i, j, 1, 1);
options.push(option);
}
}
question.options = options;
questions.push(question);
}
}
exam.questions = questions;
return exam;
}
/**
* 產出測驗表單
* @param {object} exam 測驗內容(Sheet內容)
*/
function GenerateExam(exam) {
let form = FormApp.create(exam.name);
form.setIsQuiz(true);
AddExamineeInfo(form);
let questions = exam.questions;
for (let i = 0; i < questions.length; i++) {
if (questions[i].type == 'A') {
AddChoiceItem(form, questions[i]);
} else if (questions[i].type == 'B') {
AddTxtItem(form, questions[i]);
} else if (questions[i].type == 'C') {
AddChoiceItem(form, questions[i]);
} else {
Logger.log('請確認A欄的值並重新執行')
}
}
Logger.log("done.");
}
/**
* 增加選擇題
* @param {object} form 表單主體
* @param {object} question 選擇題題目(Sheet內容)
*/
function AddChoiceItem(form, question) {
let item = {};
if (question.type == 'A') {
item = form.addMultipleChoiceItem();
} else {
item = form.addCheckboxItem();
}
item.setPoints(question.point);
item.setTitle(question.description);
item.setRequired(true);
let options = question.options;
let choices = [];
for (let j = 0; j < options.length; j++) {
if (question.answer.indexOf(j + 1) > -1) {
choices.push(item.createChoice(options[j], true));
} else {
choices.push(item.createChoice(options[j], false));
}
}
item.setChoices(choices);
}
/**
* 增加簡答題 - 無法設定解答,需手動調整表單
* @param {object} form 表單主體
* @param {object} question 簡答題題目(Sheet內容)
*/
function AddTxtItem(form, question) {
let item = form.addTextItem();
item.setPoints(question.point);
item.setTitle(question.description);
item.setRequired(true);
}
/**
* 增加考生基本資料簡答區
* @param {object} form 表單主體
*/
function AddExamineeInfo(form) {
let item1 = form.addTextItem();
item1.setTitle('請輸入您的班級,例如:資三3');
item1.setRequired(true);
let item2 = form.addTextItem();
item2.setTitle('請輸入您的座號,例如:15');
item2.setRequired(true);
let item3 = form.addTextItem();
item3.setTitle('請輸入您的姓名,例如:王大明');
item3.setRequired(true);
}
```
### 輸入指令並儲存
6. 將程式碼貼上後,修改`url`跟`questionSize`
7. 儲存
![](https://i.imgur.com/W9HSMF9.png)
## 三、執行程式碼
### 執行
8. 確認執行程式選項有變成[main]
9. 執行
![](https://i.imgur.com/Rb3N8Rg.png)
10. 等到這個畫面出現後,按下[審查權限]
![](https://i.imgur.com/eIQozLz.png)
### 授權給這支程式
11. 選擇目前登入的Google帳號
![](https://i.imgur.com/GTd38GI.png)
12. 選擇[進階]
這邊會出現不安全警告是因為這支程式為自行開發,沒有向Google申請憑證登錄發表程式,所以直接按[進階]來由使用者自行授權程式
![](https://i.imgur.com/9UKrLng.png)
13. 選擇[前往「出題程式」(不安全)]
![](https://i.imgur.com/mJuUXEZ.png)
14. 允許程式執行
![](https://i.imgur.com/uzJ42if.png)
### 執行完成後回到專案
確認專案底下執行區塊有出現done表示成功
![](https://i.imgur.com/hwqdRNu.png)
## 四、產出表單
### 查看產出的表單
回到雲端硬碟就會看到表單被建立了
![](https://i.imgur.com/zf7ys6c.png)
### 簡答題設定
簡答題目前不支援用程式設定正確答案,所以需要手動設定
![](https://i.imgur.com/5sHm96B.png)
### 選擇是否公布成績
立即公佈成績:學生可馬上看到成績
稍後公佈:學生不會馬上知道成績
學生作答成績還沒找到匯出方式😭
![](https://i.imgur.com/O6pz1KU.png)
### 把表單傳給學生作答
15. 確認題目後按下[傳送]
16. 選擇[🔗]來複製表單網址
17. 按下[複製]就可以將連結複製到剪貼簿
![](https://i.imgur.com/gH0O1rI.png)