如何从 Google 表格中获取数据并将其显示在 Google 表单上?

How to fetch data from Google Sheets and show it on Google Forms?

我正在制作一个Google表格,我想向其中添加一些问题,但这些问题应该随机选择 来自 Google Sheet 中的问题库。为此需要做什么? 例如:我想从 Google Sheets

的 20 个问题池中随机显示 5 个问题

P.s:我确实在 Whosebug 上尝试过已经提到的解决方案,但它对我的目的没有帮助。

为了创建一个脚本来回答您的问题,我创建了一个示例 sheet,如下所示:

其中 A 是问题,后面的列是选项。 注意:如果您只需要生成没有任何选项的问题,您可以选择从 sheet 中删除它。我包含了选项,因为那将是您问题中最糟糕的情况。

因此,首先,我们需要具有表单和传播的 IDsheet:

var formID = <FORM_ID>;
var ssID = <SPREADSHEET_ID>;
var fData = FormApp.openById(formID);
var wsData = SpreadsheetApp.openById(ssID).getSheetByName("Sheet1");

下一步是尝试从传播中生成问题sheet:

function populateForm() {
  // get all values from spreadsheet
  var ssValues = wsData.getDataRange().getValues();

  // traverse all values
  for(var row = 0; row < ssValues.length; row++){
    var newItem;
    var options = [];
    for(var col = 0; col < ssValues[row].length; col++){
      var cellValue = ssValues[row][col];
      switch(col) {
        case 0:
          // if question, add as item
          newItem = fData.addListItem().setTitle(cellValue).getId(); 
          break;
        default:
          // if not question, add as choice
          options.push(cellValue);
      }
    }
    // add accumulated options as choices for the recently added item
    fData.getItemById(newItem).asListItem().setChoiceValues(options);
  }
}

完成此步骤后,您应该能够将所有问题添加到表单中。现在,因为我们只需要生成 5 randomized 个问题,所以我添加了下面的函数供我们使用。

function getFiveRandomQuestions(array){
  // randomly remove questions until 5 remains
  for(var i = array.length - 1; i >= 5; i--){
    array.splice(Math.floor(Math.random() * array.length), 1);
  }
  return array;
}

上面的函数接受一个数组(getValues() 的结果),然后从中随机删除项目,直到只剩下 5 个项目。

下面是整合以上所有功能后的代码。 注意:我添加了 clearForm() 以删除现有项目,因此每当我 运行 populateForm() 时表格都会重置。这是为了测试以防万一您需要它。感觉代码改多少就改多少。

// Randomize Form from Sheets
var formID = <FORM_ID>;
var ssID = <SPREADSHEET_ID>;
var fData = FormApp.openById(formID);
var wsData = SpreadsheetApp.openById(ssID).getSheetByName("Sheet1");

function clearForm(){
  // clears all items
  var items = fData.getItems();
  while(items.length > 0){
    fData.deleteItem(items.pop());
  }
}

function getFiveRandomQuestions(array){
  // randomly remove questions until 5 remains
  for(var i = array.length - 1; i >= 5; i--){
    array.splice(Math.floor(Math.random() * array.length), 1);
  }
  return array;
}

function populateForm() {
  // call clearForm to prevent appending newly randomized questions
  clearForm();

  var ssValues = wsData.getDataRange().getValues();

  // remove random questions until 5 are remaining
  var formItems = getFiveRandomQuestions(ssValues);

  for(var row = 0; row < formItems.length; row++){
    var newItem;
    var options = [];
    for(var col = 0; col < formItems[row].length; col++){
      var cellValue = formItems[row][col];
      switch(col) {
        case 0:
          // if question, add as item
          newItem = fData.addListItem().setTitle(cellValue).getId(); 
          break;
        default:
          // if not question, add as choice
          options.push(cellValue);
      }
    }
    // add accumulated options as choices for the recently added item
    fData.getItemById(newItem).asListItem().setChoiceValues(options);
  }
}

这是示例输出:

请注意,这个答案很简单,仍然可以根据您的测试用例进行优化。如果您有任何不清楚的地方,请随时提问。

编辑:

如果要添加硬编码问题,需要在循环之前添加。

// remove random questions until 5 are remaining
var formItems = getFiveRandomQuestions(ssValues);
    
// start of hardcoded questions
fData.addListItem().setTitle('Name').getId(); 
fData.addListItem().setTitle('Email').getId(); 
// end of hardcoded questions    

for(var row = 0; row < formItems.length; row++){

此外,如果您希望只有 5 个问题并且已经通过硬编码有 2 个问题,我们需要将随机化器函数减少到 3 个而不是 5 个。

// note that I renamed the function to getRandomQuestions so bear in mind to update the function call too
function getRandomQuestions(array){
  for(var i = array.length - 1; i >= 3; i--){
    array.splice(Math.floor(Math.random() * array.length), 1);
  }
  return array;
}

示例输出:

如果有多个部分,您也可以使用分页符。 在你的情况下它将是

fData.addPageBreakItem();

这将在表单的新页面上创建一个部分