【问题标题】:Google Sheets Search and Sum in two lists谷歌表格搜索和两个列表中的总和
【发布时间】:2019-10-31 11:50:57
【问题描述】:

我有一个 Google 表格问题,希望有人能提供帮助。

我有一个大约 200 个关键字的列表,如下所示:

**List 1** 
Italy City trip
Italy Roundtrip
Italy Holiday
Hungary City trip
Czechia City trip
Croatia Montenegro Roundtrip
....
....

然后我有另一个列表,其中包含大约 100 万行的混乱关键字。此列表中的关键字与第一个列表不完全匹配。我需要做的是在列表 2(下)中搜索列表 1(上)中的关键字,并对所有相应的成本值求和。正如您在下面的列表中看到的,列表 1 中的关键字位于第二个列表中,但周围还有其他关键字。例如,我需要一个公式来从列表 1 中的列表 2 中搜索“意大利城市之旅”,并在该关键字出现时求和成本。在这种情况下,总共将是 6 个。将“意大利城市之旅 4 月”和“意大利城市之旅 6 月”的费用相加。

**List 2**                   Cost
Italy City trip April         1
Italy City trip June          5 
Next week Italy Roundtrip     4
Italy Holiday next week       1
Hungary City holiday trip     9
....
....

我希望这是有道理的。

任何帮助将不胜感激

【问题讨论】:

  • “一百万行”o_O
  • 哈哈,我可以剪掉它
  • “砍掉它”!打消念头。

标签: regex google-sheets google-sheets-formula array-formulas google-sheets-query


【解决方案1】:

尝试:

=ARRAYFORMULA(QUERY({IFNA(REGEXEXTRACT(PROPER(C1:C), 
 TEXTJOIN("|", 1, SORT(PROPER(A1:A), 1, 0)))), D1:D}, 
 "select Col1,sum(Col2) 
  where Col1 is not null 
  group by Col1 
  label sum(Col2)''", 0))

【讨论】:

  • "try" - 年度轻描淡写。
【解决方案2】:

您想确定一个列表 (List#1) 中的关键字是否可以在另一个列表 (List#2) 中找到。

List#2 有 1,000,000 行长,因此我建议对列表进行分段,以免超过执行时间。您可以通过反复试验来确定这一点。

解决方法是使用javascript方法indexOf

w3schools 释义:indexOf() 返回指定值在字符串中第一次出现的位置。如果未找到该值,则返回 -1。所以测试if (idx !=-1){ 只会返回在List#2 中找到的List#1 值。注意:indexOf() 方法区分大小写。


 function so5864274503() {

  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var srcname = "source";
  var tgtname = "target";
  var sourceSheet = ss.getSheetByName(srcname);
  var targetSheet = ss.getSheetByName(tgtname);

  // get the source list 
  var sourceLR = sourceSheet.getLastRow();
  var srcData = sourceSheet.getRange(1,1,sourceLR).getValues();

  //get the target list
  var targetLR = targetSheet.getLastRow();
  var tgtlist = targetSheet.getRange(1,1,targetLR,2).getValues();
  var totalcostvalues = [];

  //  start looping through the keywords (list 1)
  for (var s = 0;s<srcData.length;s++){
    var totalcost = 0;
    var value = srcData[s][0]

    // start looping through the strings (List 2)
    for (var i=0;i<tgtlist.length;i++){
      // set cost to zero
      var cumcost = 0;
      // use indexOf to test if keyword is in the string
      var idx = tgtlist[i][0].indexOf(value);

      // value of -1 = no match, value >-1 indicates posuton in the string where the key word was found      
      if (idx !=-1){
        var cost = tgtlist[i][1]
        cumcost = cumcost + cost;
        totalcost = totalcost+cost
      }

    }//end of loop - list2


    //Logger.log("DEBUG: Summary: "+value+", totalcost = "+totalcost)
    totalcostvalues.push([totalcost])

  }// end of loop - list1

  //Logger.log(totalcostvalues);  //DEBUG
  sourceSheet.getRange(1,2,sourceLR).setValues(totalcostvalues);
}

【讨论】:

    【解决方案3】:

    我也有这个,但是有点区分大小写

    function myFunction() {
      var ss = SpreadsheetApp.getActive();
      var sheet1 = ss.getSheets()[0];
      var sheet2 = ss.getSheets()[1];
    
      var valuesSheet1 = sheet1.getRange(2,1, (sheet1.getLastRow()-1), sheet1.getLastColumn()).getValues();
      var valuesCol1Sheet1 = valuesSheet1.map(function(r){return r[0]});
      var valuesCol2Sheet1 = valuesSheet1.map(function(r){return r[1]});
      Logger.log(valuesCol2Sheet1);
    
      var valuesSheet2 = sheet2.getRange(2,1, (sheet2.getLastRow()-1)).getValues();
      var valuesCol1Sheet2 = valuesSheet2.map(function(r){return r[0]});
    
      for (var i = 0; i<= valuesCol1Sheet2.length-1; i++){
     var price = 0;
     valuesCol1Sheet1.forEach(function(elt,index){
      var position = elt.toLowerCase().indexOf(valuesCol1Sheet2[i].toLowerCase());
         if(position >-1){
      price = price + valuesCol2Sheet1[index];
      }
      });
      sheet2.getRange((i+2),2).setValue(price);
      };
      }
    

    【讨论】:

    • var valuesSheet2 = sheet2.getRange(2,1, (sheet1.getLastRow()-1))。这不应该是var valuesSheet2 = sheet2.getRange(2,1, (sheet2.getLastRow()-1))
    • 是的,我的错
    • 我收到了TypeError: Cannot call method "toLowerCase" of undefined. var position = elt.toLowerCase().indexOf(valuesCol1Sheet2[i].toLowerCase());
    • 你的 SS1 的价值是什么?
    • for (var i = 0; i&lt;= valuesCol1Sheet2.length-1; i++){ 时工作正常。注意长度减1;这就是导致打嗝的原因。我真的很喜欢这个答案;你有一个循环,而我的有两个循环;
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-28
    • 1970-01-01
    • 1970-01-01
    • 2021-06-04
    • 2021-09-14
    • 2021-10-27
    相关资源
    最近更新 更多