javascript - 在 Google Apps 脚本中为项目列表分配一个数字(最多 50 个)
问题描述
我在 C 列中有一个项目列表,我想分配一个不同的数值。示例列表如下所示:
C 列(之前) | C 列(之后) |
---|---|
苹果 0 | |
苹果 0 | |
苹果 0 | |
苹果 0 | |
橙子 | |
苹果 0 | |
苹果 0 | |
苹果 0 | |
橙子 | |
苹果 0 | |
苹果 0 | |
苹果 0 | |
苹果 0 | |
苹果 0 | |
苹果 0 | |
苹果 0 | |
苹果 0 | |
橙子 | |
橙子 |
它将分配“1”直到列表中的最大值为 50。
例如,如果“Apple 0”少于 50 个,它只会执行“Apple 1”。但如果超过 50 个,就会平分“Apple 1”和“Apple 2”。
换句话说:
如果找到少于 50 个零,它会自动分配值“1”(Apple 0 --> Apple 1)。
如果发现大于 50 但小于 100 个零,它会自动平均分配值“1”和“2”(Apple 0 --> Apple 1 x 50,Apple 2 x 50)。
如果发现大于 100 但小于 150 个零,它会自动平均分配值“1”“2”和“3”。
如果发现大于 150 但小于 200 个零,它会自动平均分配值“1”“2”“3”和“4”,依此类推。
我正在尝试从菜单中触发此功能:
function onInstall(e) {
onOpen(e);
}
function onOpen() {
var ui = SpreadsheetApp.getUi();
ui.createMenu('Assign Values')
.addItem('Assign Numbers to Zeroes (Max. 50)', 'assignNumbers')
.addToUi();
}
function assignNumbers() {
const sheet = SpreadsheetApp.getActiveSheet();
var colC = sheet.getRange("C:C");
var colCValues = colC.getValues();
var appleCount = 0; // to store the apple count
var appleLineAddress = []; // to store the row-no of Apple 0's
// get the total count and and its row-no
for (let i = 0; i < colCValues.length; i++) {
if (colCValues[i][0] == "") continue;
if (colCValues[i][0].toString().includes('Apple 0')) {
appleCount++;
appleLineAddress.push(i);
}
}
// Check apple count and divide
if (appleCount < 50) {
for (let i = 0; i < appleLineAddress.length; i++) {
sheet.getRange(i + 5, 3).setValue('Apple 1');
}
} else if (appleCount > 50 && appleCount <= 100) {
printAppleCount(2, appleCount, appleLineAddress);
} else if (appleCount > 100 && appleCount <= 150) {
printAppleCount(3, appleCount, appleLineAddress);
} else if (appleCount > 150 && appleCount <= 200) {
printAppleCount(4, appleCount, appleLineAddress);
} else if (appleCount > 200 && appleCount <= 250) {
printAppleCount(5, appleCount, appleLineAddress);
} else if (appleCount > 250 && appleCount <= 300) {
printAppleCount(6, appleCount, appleLineAddress);
}
}
function printAppleCount(caseNo, appleCount, appleLineAddress) {
const sheet = SpreadsheetApp.getActiveSheet();
var splitInteger = function numParts(num, parts) {
var val;
var mod = num % parts;
if (mod == 0) {
val = num / parts;
retData = Array(parts).fill(val);
} else {
val = (num - mod) / parts;
retData = Array(parts).fill(val);
for (i = 0; i < mod; i++) {
retData[i] = retData[i] + 1;
}
retData.reverse()
//Comment the above line to unreverse the result.
}
return retData;
}
console.log("Case No: " + caseNo);
console.log("AppleCount : " + appleCount);
var equalSplits = splitInteger(appleCount, caseNo);
console.log(equalSplits);
// for the applecount: 113(suppose), the var equalSplits will log [37,38,38].
// You can print the data now with the equalSplits and appleLineAddress
var k = 0;
for (var i = 0; i < equalSplits.length; i++) {
for (var j = 0; j < equalSplits[i]; j++) {
console.log('Print Apple ' + (i + 1) + ' at ' + appleLineAddress[k++]);
sheet.getRange(appleLineAddress[k++], 3).setValue('Apple ' + (i + 1));
}
}
}
错误:异常:参数 (null,number) 与 SpreadsheetApp.Sheet.getRange 的方法签名不匹配。
结果是跳过数字而不是正确分配。查看控制台日志结果:
2021 年 5 月 13 日下午 5:21:59 | 调试 | 案例编号:2 |
2021 年 5 月 13 日下午 5:21:59 调试 | 苹果数:52 | |
2021 年 5 月 13 日下午 5:21:59 调试 | [ 26, 26 ] | |
2021 年 5 月 13 日下午 5:21:59 调试 | 在 6 点打印 Apple 1 | |
2021 年 5 月 13 日下午 5:21:59 调试 | 8 点打印 Apple 1 | |
2021 年 5 月 13 日下午 5:21:59 调试 | 10 点打印 Apple 1 | |
2021 年 5 月 13 日下午 5:21:59 调试 | 12 点打印 Apple 1 | |
2021 年 5 月 13 日下午 5:21:59 调试 | 在 14 点打印 Apple 1 | |
ETC... | ... |
我们快到了,它只是跳跃 6、8、10 等等——但它正在平均分配批次,这是一个好兆头。
谢谢!
解决方案
请注意,正如@doubleunary 所说,这是一项非常简单的任务,而电子表格公式可以做到这一点。但是,如果您的情况超出了您所描述的范围,那么可以从以下内容开始:
var colA = sheet.getRange("A:A");
var colAValues = colA.getValues();
var appleCount = 0; // to store the apple count
var appleLineAddress = []; // to store the row-no of 'Apple 0's.
// get the total count and and its row-no
for(let i=0; i<colAValues.length; i++){
if(colAValues[i][0] == "") continue;
if(colAValues[i][0].toString().includes('Apple'))
{
appleCount++;
appleLineAddress.push(i);
}
}
// Check apple Count and Divide
if(appleCount < 50)
{
for(let i = 0; i<appleLineAddress.length; i++)
{
sheet.getRange(i+2,2).setValue('Apple 1');
}
}
else if(appleCount >= 50 && appleCount <100)
{
printAppleCount(2,appleCount,appleLineAddress);
}
else if(appleCount >= 100 && appleCount <150)
{
printAppleCount(3,appleCount,appleLineAddress)
}
else if(appleCount >= 150 && appleCount <200)
{
printAppleCount(4,appleCount,appleLineAddress);
}
else ...
我已使用此答案的方法在您所说的案例(1,2,3,4,...)之间平均分配否
var splitInteger = function(num, parts) {
var val;
var mod = num % parts;
if(mod == 0){
val = num/parts;
retData = Array(parts).fill(val);
} else {
val = (num-mod)/parts;
retData = Array(parts).fill(val);
for(i=0;i<mod;i++){
retData[i] = retData[i] + 1;
}
retData.reverse()
//Comment the above line to unreverse the result.
}
return retData;
}
然后你只需要打印:
function printAppleCount(caseNo, appleCount, appleLineAddress){
console.log("Case No: "+caseNo);
console.log("AppleCount : "+appleCount);
var equalSplits = splitInteger(appleCount, caseNo);
console.log(equalSplits);
// for the applecount : 113(suppose), the var equalSplits will log [37,38,38].
// You can print the data now with the equalSplits and appleLineAddress
.
.
.
}
显然,对于上面提到的大多数代码,您可以使用很多单行函数。上面的代码只是为了保持可读性。
如果我误解了你的问题或者这不是你想要的,我很抱歉。
评论后编辑
- 相邻列中的 Apple 1:我正在使用
sheet.getRange(i+2,2).setValue('Apple 1');
以供您理解,以便相邻列获得值。
您可以简单地更改col address in getRange()
为(i+2,3) //or whatever your column index is.
- printAppleCount():此函数用于将值打印到所需部分。您拥有
equalSplits (an array of [37,38,38] )
并且也拥有lineAddresses(the row no. which had 'Apple 0')
. 您可以遍历这些值以打印具有精确计数的 Apple 1/2/3。并且,appleLineAddress
将处理混合数据,即 Apple、Orange、Strawberry,然后是 Apple,...
代码:
var k = 0;
for(var i=0; i<equalSplits.length; i++){
for(var j=0; j<equalSplits[i]; j++)
{
console.log('Print Apple '+(i+1)+' at'+appleLineAddress[k++]);
sheet.getRange(appleLineAddress[k++],3).setValue('Apple '+(i+1));
}
}
此外,请参阅Google Apps 脚本文档以获得更好的理解。干杯!
推荐阅读
- python - pycharm 刽子手游戏中的问题。这里是初学者(显然)。TypeError: 'builtin_function_or_method' 类型的对象没有 len()
- c++ - 创建 GL_TEXTURE_2D_ARRAY 后访问冲突
- python - 为什么加密中的AES加密会产生汉字
- django - Django OnetoOne 字段未填充
- java - 哪种数据结构更适合使用顺序搜索来搜索元素 - 数组列表或链接列表?
- python - 通过代码调用函数和参数
- python - Python中的最小一对多
- outlook - 从 getUserIdentityTokenAsync 验证令牌时引发 JWT::ExpiredSignature
- r - 多个邮政编码的 zipRadius 函数
- python - 为什么我会收到“NameError: name 'B'/'C'/'V' is not defined”?