GAS 中用于在 Google 表单中创建 CheckboxgridItem 响应的二维数组的正确结构是什么
What is the correct structure of a 2D array in GAS that is used to create a CheckboxgridItem response in a Google Form
我提到的以前的“答案”并没有解决这个问题。我在发帖之前尝试过这种技术。该技术不起作用,我收到了与我现在收到的错误相同的错误。
我正在尝试创建一个 Google Apps 脚本,它允许我使用表单中以前的数据并将数据“重新提交”到表单中。用例是我将让老师在收到 class 部分的提交后更改表格问题。此更改将导致以前的数据不再包含在表单响应摘要页面或个人响应中。相反,数据是隐藏的,只能通过下载响应的 csv 或在 linked Sheet 中找到的数据访问(前提是教师 linked Sheet在编辑表格之前)。当前的解决方法是使用表单的预填充-URL 功能,然后通过使用 Sheet 中的公式为每一行数据创建一个 URL。然后教师必须手动单击每个 link 以将数据输入回表格。这不仅耗时,而且许多教师无法创建一个公式来创建个人 url links.
为了解决这个问题,我正在创建一个脚本,发生这种情况时我可以与这些老师一起使用。除了网格和时间项之外,我已经弄清楚了所有内容。这是仅适用于 checkbox_grid 问题的精简版脚本。
数据在一列 (B1:B) 中,如下所示:
1X2 Grid [R1]
C1, C2
C1
C2
C1, C2
在脚本中,我已经能够为每个单元格创建一个数组,如下所示:
array[0] = [['C1'].['C2']]
array[1] = [['C1'],['']]
array[2] = [[''],['C2']]
array[3] = [['C1'].['C2']]
返回以下错误:
Exception: Wrong number of responses: 2. Expected exactly: 1.
此外,在进一步研究时,我在开发者网站上发现了以下内容:
对于 GridItem 问题,这个 returns 一个 String[]
数组,其中索引 n 处的答案对应于表格中第 n + 1 行的问题网格。如果受访者没有回答网格中的问题,则该答案将返回为 ''
.
对于 CheckboxGridItem 问题,这个 returns 一个 String[][]
数组,其中第 n 行的答案对应于第 n + 1 行的问题复选框网格。如果受访者没有回答网格中的问题,则该答案将返回为“”。
构造数组以使 GAS 接受它的正确方法是什么?
示例文件中的代码在这里:
//Global Variables for Spreadsheet
const ss = SpreadsheetApp.getActiveSpreadsheet();
var dataSheet = ss.getSheetByName('Data');
var lastRow = dataSheet.getLastRow();
var lastCol = dataSheet.getLastColumn();
var sheetHeader = dataSheet.getRange('1:1');
var sheetTitles = sheetHeader.getValues();
var error = 'None';
var cellValue = [];
//Global Variables for Form
var form = FormApp.openByUrl(ss.getFormUrl());
var formResponses = form.getResponses();
var formCreate = form.createResponse();
var formItems = form.getItems();
//sendValues() calls the setResponses() to set the values of each form response.
// The function then submits the forms and clears the responses.
// Flush is used to make sure the order of the code is retained.
//------------------ New Variables -------------------------------
// r = row
function sendValues() {
for (r = 2; r <= lastRow; r++) {
setResponses(r);
//formCreate.submit();
console.log('submitted');
formCreate = form.createResponse();
SpreadsheetApp.flush();
}
}
//setResponses(r) sets the response for each cell of the data sheet.
//calls gridResponse(cell,i) if the question type is either a checkbox grid or multiple choice grid question.
//----------------------- New Variables ---------------------------
// c = column
// i = item response
// ssHeaderValue = Values of the Row 1 in the Data Sheet (dataSheet)
// cell = Value of each cell in dataSheet
// cellValue = Converts commas in cell variable to ;
// formItem = each item from all of the Form items
// fHeaderValue = Value of each "header" (Title) of each Form value
// itemAs = item set to correct type
// itemResponse = created response
function setResponses(r) {
for (c = 2; c <= lastCol; c++) {
for (i = 0; i < formItems.length; i++) {
var ssHeaderValue = dataSheet.getRange(1, c).getValue();
var itemType = formItems[i].getType();
var cell = dataSheet.getRange(r, c).getValue();
gridResponse(cell, i);
var formItem = formItems[i];
var fHeaderValue = formItem.getTitle();
var itemResponse = formItem
.asCheckboxGridItem()
.createResponse(cellValue);
}
//ERROR HERE: formCreate.withItemResponse(itemResponse);
}
}
//checkboxGridResponse(cell,i) makes an array of cellValue that can be used in CHECKBOX_GRID item.
//--------------------- New variables ------------------------------
// z = loop counter
// gridColumns = number of possible responses in the Form
// cellValueLength = number of responses in the cell data
// cellColumns = cell data split into separate values
// cellValue = value to be returned
// arr = temporary array for making cellValue into a 2D array
function gridResponse(cell, i) {
var gridColumns = formItems[i].asCheckboxGridItem().getColumns();
var cellValueLength = cell.split(',').length;
var cellColumns = cell.split(',');
for (z = 0; z < cellValueLength; z++) {
console.log(
'cellColumns ' +
z +
' = ' +
cellColumns[z] +
'; gridColumns ' +
z +
' = ' +
gridColumns[z]
);
var arr = [gridColumns[z] == cellColumns[z] ? gridColumns[z] : null];
cellValue.push(arr);
}
console.log(cellValue);
console.log('cellValue[0][0] = ' + cellValue[0][0]);
console.log('cellValue[0][1] = ' + cellValue[0][1]);
console.log('cellValue [1][0] = ' + cellValue[1][0]);
return cellValue;
}
CheckboxGridItem
的响应结构是一个二维数组:
- 外部数组应包含行数组
- 内部数组应包含列元素
- 元素本身应该是列标签
这个用于 1 项表单的示例脚本提交一个 2x2 CheckboxGridItem 数组,为两行选择“第 1 列”。
Column 1
Column 2
✅
⬜
✅
⬜
function myFunc16() {
const form = FormApp.getActiveForm();
const newRes = form
.getItems()[0]
.asCheckboxGridItem()
.createResponse([['Column 1'], ['Column 1']]);
form.createResponse().withItemResponse(newRes).submit();
}
要提交另一个回复选择
Column 1
Column 2
⬜
⬜
✅
⬜
数组应该是:
[
null, //Row1
['Column 1'] //Row2
]
同样,对于
Column 1
Column 2
⬜
✅
⬜
⬜
数组:
[
['Column 2'],
null
]
如果插入数组
[
['Column 2']
]
对于 2x2 CheckboxGridItem,错误,
Exception: Wrong number of responses: 1. Expected exactly: 2.
被抛出。这意味着 array.length
与网格中的行数不匹配。
数组的结构可以通过手动提交 1 个复选框网格项表单并使用编程方式检查响应来找到:
//Examine third response [2]
//First item's response [0]
console.log(form.getResponses()[2].getItemResponses()[0].getResponse())
我提到的以前的“答案”并没有解决这个问题。我在发帖之前尝试过这种技术。该技术不起作用,我收到了与我现在收到的错误相同的错误。
我正在尝试创建一个 Google Apps 脚本,它允许我使用表单中以前的数据并将数据“重新提交”到表单中。用例是我将让老师在收到 class 部分的提交后更改表格问题。此更改将导致以前的数据不再包含在表单响应摘要页面或个人响应中。相反,数据是隐藏的,只能通过下载响应的 csv 或在 linked Sheet 中找到的数据访问(前提是教师 linked Sheet在编辑表格之前)。当前的解决方法是使用表单的预填充-URL 功能,然后通过使用 Sheet 中的公式为每一行数据创建一个 URL。然后教师必须手动单击每个 link 以将数据输入回表格。这不仅耗时,而且许多教师无法创建一个公式来创建个人 url links.
为了解决这个问题,我正在创建一个脚本,发生这种情况时我可以与这些老师一起使用。除了网格和时间项之外,我已经弄清楚了所有内容。这是仅适用于 checkbox_grid 问题的精简版脚本。
数据在一列 (B1:B) 中,如下所示:
1X2 Grid [R1] |
---|
C1, C2 |
C1 |
C2 |
C1, C2 |
在脚本中,我已经能够为每个单元格创建一个数组,如下所示:
array[0] = [['C1'].['C2']]
array[1] = [['C1'],['']]
array[2] = [[''],['C2']]
array[3] = [['C1'].['C2']]
返回以下错误:
Exception: Wrong number of responses: 2. Expected exactly: 1.
此外,在进一步研究时,我在开发者网站上发现了以下内容:
对于 GridItem 问题,这个 returns 一个 String[]
数组,其中索引 n 处的答案对应于表格中第 n + 1 行的问题网格。如果受访者没有回答网格中的问题,则该答案将返回为 ''
.
对于 CheckboxGridItem 问题,这个 returns 一个 String[][]
数组,其中第 n 行的答案对应于第 n + 1 行的问题复选框网格。如果受访者没有回答网格中的问题,则该答案将返回为“”。
构造数组以使 GAS 接受它的正确方法是什么?
示例文件中的代码在这里:
//Global Variables for Spreadsheet
const ss = SpreadsheetApp.getActiveSpreadsheet();
var dataSheet = ss.getSheetByName('Data');
var lastRow = dataSheet.getLastRow();
var lastCol = dataSheet.getLastColumn();
var sheetHeader = dataSheet.getRange('1:1');
var sheetTitles = sheetHeader.getValues();
var error = 'None';
var cellValue = [];
//Global Variables for Form
var form = FormApp.openByUrl(ss.getFormUrl());
var formResponses = form.getResponses();
var formCreate = form.createResponse();
var formItems = form.getItems();
//sendValues() calls the setResponses() to set the values of each form response.
// The function then submits the forms and clears the responses.
// Flush is used to make sure the order of the code is retained.
//------------------ New Variables -------------------------------
// r = row
function sendValues() {
for (r = 2; r <= lastRow; r++) {
setResponses(r);
//formCreate.submit();
console.log('submitted');
formCreate = form.createResponse();
SpreadsheetApp.flush();
}
}
//setResponses(r) sets the response for each cell of the data sheet.
//calls gridResponse(cell,i) if the question type is either a checkbox grid or multiple choice grid question.
//----------------------- New Variables ---------------------------
// c = column
// i = item response
// ssHeaderValue = Values of the Row 1 in the Data Sheet (dataSheet)
// cell = Value of each cell in dataSheet
// cellValue = Converts commas in cell variable to ;
// formItem = each item from all of the Form items
// fHeaderValue = Value of each "header" (Title) of each Form value
// itemAs = item set to correct type
// itemResponse = created response
function setResponses(r) {
for (c = 2; c <= lastCol; c++) {
for (i = 0; i < formItems.length; i++) {
var ssHeaderValue = dataSheet.getRange(1, c).getValue();
var itemType = formItems[i].getType();
var cell = dataSheet.getRange(r, c).getValue();
gridResponse(cell, i);
var formItem = formItems[i];
var fHeaderValue = formItem.getTitle();
var itemResponse = formItem
.asCheckboxGridItem()
.createResponse(cellValue);
}
//ERROR HERE: formCreate.withItemResponse(itemResponse);
}
}
//checkboxGridResponse(cell,i) makes an array of cellValue that can be used in CHECKBOX_GRID item.
//--------------------- New variables ------------------------------
// z = loop counter
// gridColumns = number of possible responses in the Form
// cellValueLength = number of responses in the cell data
// cellColumns = cell data split into separate values
// cellValue = value to be returned
// arr = temporary array for making cellValue into a 2D array
function gridResponse(cell, i) {
var gridColumns = formItems[i].asCheckboxGridItem().getColumns();
var cellValueLength = cell.split(',').length;
var cellColumns = cell.split(',');
for (z = 0; z < cellValueLength; z++) {
console.log(
'cellColumns ' +
z +
' = ' +
cellColumns[z] +
'; gridColumns ' +
z +
' = ' +
gridColumns[z]
);
var arr = [gridColumns[z] == cellColumns[z] ? gridColumns[z] : null];
cellValue.push(arr);
}
console.log(cellValue);
console.log('cellValue[0][0] = ' + cellValue[0][0]);
console.log('cellValue[0][1] = ' + cellValue[0][1]);
console.log('cellValue [1][0] = ' + cellValue[1][0]);
return cellValue;
}
CheckboxGridItem
的响应结构是一个二维数组:
- 外部数组应包含行数组
- 内部数组应包含列元素
- 元素本身应该是列标签
这个用于 1 项表单的示例脚本提交一个 2x2 CheckboxGridItem 数组,为两行选择“第 1 列”。
Column 1 | Column 2 |
---|---|
✅ | ⬜ |
✅ | ⬜ |
function myFunc16() {
const form = FormApp.getActiveForm();
const newRes = form
.getItems()[0]
.asCheckboxGridItem()
.createResponse([['Column 1'], ['Column 1']]);
form.createResponse().withItemResponse(newRes).submit();
}
要提交另一个回复选择
Column 1 | Column 2 |
---|---|
⬜ | ⬜ |
✅ | ⬜ |
数组应该是:
[
null, //Row1
['Column 1'] //Row2
]
同样,对于
Column 1 | Column 2 |
---|---|
⬜ | ✅ |
⬜ | ⬜ |
数组:
[
['Column 2'],
null
]
如果插入数组
[
['Column 2']
]
对于 2x2 CheckboxGridItem,错误,
Exception: Wrong number of responses: 1. Expected exactly: 2.
被抛出。这意味着 array.length
与网格中的行数不匹配。
数组的结构可以通过手动提交 1 个复选框网格项表单并使用编程方式检查响应来找到:
//Examine third response [2]
//First item's response [0]
console.log(form.getResponses()[2].getItemResponses()[0].getResponse())