我正在尝试构建一个简单的脚本来使用Google电子表格。电子表格从Google表单中获取输入,因此电子表格中有一系列值,如下所示:
我的目标是编写一个脚本,用于从用户指定范围内的每个表单输入中删除数字,然后添加所有数字以提供单个分数。因此,例如,用户可以在单元格中键入=sumColumns(H2:K2)
,它将返回分数的总和(对于我发布的示例屏幕截图,它将返回3+3+0+3
的结果,{{1 }})。
以下是我为此编写的代码:
9
问题是它似乎只是将两个值一起添加。因此,当我将function sumColumns(values) {
var sum = 0;
for(var i = 0; i <= values.length; i++){
var input = values[0][i];
var x = input.toString();
var y = x.charAt(0);
var num = parseInt(y);
sum += num;
}
return sum;
}
放入电子表格的单元格中时,它只返回=sumColumns(H2:K2)
。此外,在第3行,如果我将其从6
更改为i <= values.length
,则只会添加一个数字,因此我会得到i < values.length
。我的猜测是我误解了Google Spreadsheet值传递给函数的方式,但我完全无法使它工作。我真的很感激任何帮助!
答案 0 :(得分:3)
哎呀 - 编辑&amp;保存了问题,写了一个答案 - 忘了保存它。我让塞尔德打败了我!而且,像往常一样,塞尔的答案效果很好(整数值)。但你确实问过事情是如何运作的,所以你走了。
当您为自定义函数指定一个范围作为参数时,H2:K2
在这种情况下,该函数会接收一个二维数组,相当于Range.getValues()
的返回值。您可以通过(临时)更改函数来返回参数的JSON表示来轻松测试:
function sumColumns(values) {
return JSON.stringify(values); // For debugging, just return string showing values
...
以下是您在包含=sumColumns(H2:K2)
的单元格中看到的内容:
[["3 (Rarely)","3 (Frequently)","0 (Never)","3 (Frequently)"]]
显示由[ .. ]
括起来的数组,其中包含另一个数组,也用方括号括起来,该数组有四个元素。如果我们将范围更改为H2:K3
,我们会得到此信息(为清晰起见添加了空格):
[
["3 (Rarely)","3 (Frequently)","0 (Never)","3 (Frequently)"],
["","","",""]
]
现在您知道了,很容易理解为什么您的功能会给出结果。
首先,for(var i = 0; i <= values.length; i++)
使用错误的数组边界进行循环,因为values.length
会告诉我们values
中有多少行。在H2:K2
中,该长度为1
。相反,我们需要使用其values[0]
单元格遍历第一行(4
)中的列。
您想知道此循环的<
vs <=
- 我们确实需要使用<
,因为它是基于0的索引,.length
返回的是元素。所以我们最终得到:
for (var i=0; i < values[0].length; i++){ ... }
使用parseInt()
是一个不错的选择,适用于电子表格中的值。但是,可以通过确保任何String值首先删除前导非数字值来进行改进 - parseInt()
然后可以在字符串中找到一个Integer。
function sumColumns(values) {
return JSON.stringify(values); // For debugging, just return string showing values
var sum = 0;
for(var i = 0; i < values[0].length; i++){
var input = new String(values[0][i])
.replace( /^\D+/g, ''); // Strip any leading non-digits
sum += parseInt(input);
}
return sum;
}
答案 1 :(得分:0)
我不熟悉自定义函数,因为我从不使用它们,但似乎values
不是真正的数组......
斜体评论:
嗯尴尬...我的第一个虽然是它必须是一个2D数组但是我在测试中记录了val [0]并且它返回了一个'undefined'错误...我一定输错了那一刻......无论如何,这就是为什么我寻找一种方法来处理数据作为字符串并使用split和regex。 和Mogsdad的答案一样,你有一个答案以及随之而来的所有解释;-)而且,和他一样,你得到的答案比我的好。 (虽然有一个限制(@Mogsdad)你的关于非整数值的注释也可以应用到你的代码中......你只需用parseInt()去掉任何十进制值...... :-) 也就是说,你的用例得到了很好的描述,在这个例子的范围内,两个代码都应该按预期运行,Mogsdad的一个更“学术化”,编程更正。
评论结束。
使用下面的这个技巧,它可以按预期工作于任何输入范围(1个或更多行和列):
function sumCol(val) { // returns the sum of all numeric values in range
var values = val.toString().split(',');
var sum = 0;
for(var n=0;n<values.length;++n){
sum+=Number(values[n].replace(/[^0-9+.]/ig,''));
}
return sum;
}
我还改变了数字提取模式,使其更具普遍性。