簡體   English   中英

在 Google Apps 腳本中為項目列表分配一個數字(最多 50 個)

[英]Assign a list of items a number (up to 50) in Google Apps Script

我在 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:

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() :這個 function 用於將值打印到所需的部分。 你有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 腳本文檔以獲得更好的理解。 干杯!

也許:

=INDEX(IF(COUNTIFS(A:A, "Apple 0")<50, SUBSTITUTE(A:A, "Apple 0", "Apple 1"), 
 IF((COUNTIFS(A:A, "Apple 0")>=50 )*(COUNTIFS(A:A, "Apple 0")<100)*(A:A="Apple 0"), "Apple "&1+INT((COUNTIFS(A:A, A:A, A:A, "Apple 0", ROW(A:A), "<="&ROW(A:A))-1)/(COUNTIFS(A:A, "Apple 0")/2)), 
 IF((COUNTIFS(A:A, "Apple 0")>=100)*(COUNTIFS(A:A, "Apple 0")<150)*(A:A="Apple 0"), "Apple "&1+INT((COUNTIFS(A:A, A:A, A:A, "Apple 0", ROW(A:A), "<="&ROW(A:A))-1)/(COUNTIFS(A:A, "Apple 0")/3)), 
 IF((COUNTIFS(A:A, "Apple 0")>=150)*(COUNTIFS(A:A, "Apple 0")<200)*(A:A="Apple 0"), "Apple "&1+INT((COUNTIFS(A:A, A:A, A:A, "Apple 0", ROW(A:A), "<="&ROW(A:A))-1)/(COUNTIFS(A:A, "Apple 0")/4)), A:A)))))

在此處輸入圖像描述

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM