如何处理谷歌表格脚本中的重复项?

Posted

技术标签:

【中文标题】如何处理谷歌表格脚本中的重复项?【英文标题】:How to deal with duplicates in google sheets script? 【发布时间】:2020-05-20 03:04:43 【问题描述】:

所以在我想做的项目中,我有一个谷歌表,其中包含时间戳和电子表格中这些时间戳旁边的名称。我在计算重复项并在另一个 Google 表格中为名称提供多个时间戳时遇到了麻烦。

for(var i = 0; i < length; i++)//for loop 1

if(currentCell.isBlank())//current cell is blank
  daySheet.getRange(i+10, 2).setValue(fullName);//set name to first cell
  daySheet.getRange(i+10,3).setValue(pI);
  daySheet.getRange(i+10,day+3).setValue(1);    

else if(counter > 1 )//the index of the duplicate in the sheet month
      //if counter is > 1 then write duplicates
      for(var t = 1; t <= sheetLength ; t++)//loop through sign in sheet
          //current index i
          if(signInLN == signInSheet.getRange(t+1,3).getValue())
          //if there is a match
            daySheet.getRange(t+10,day+3).setValue(1);
            //day is equal to the day I spliced from the timestamp

            //at this point I am confused on how to get the second date that has the same
            //name and add to the row with the original name.
            //when i splice the timestamp based on the row of index i, with duplicates I get 
            //the day number from the first instance where the name is read


          
      
//for loop 1

我怎样才能让它与重复项一起使用,以便我可以考虑日期,但要确保如果有 任何重复的它们都将被添加到原始名称的行中

Google Sheet EX:
12/10/2020   test1
12/11/202    test2
12/15/2020   test1 

应该是这样的:

name       10   11   12   13   14   15   16
test1       1                        1
test2            1

//一个是标识日期是用户在工作表上登录的日期。

【问题讨论】:

【参考方案1】:

示例电子表格:


使用 Apps 脚本 完成代码 sn-p,根据您的需要进行调整。

使用Logger.log(),以防您不理解部分代码

主要是用函数式JavaScript

function main()
  var inputRange = "A2:B";
  var sheet = SpreadsheetApp.getActive().getSheets()[0]

  var input = sheet.getRange(inputRange).getValues(); //Read data into array

  var minDate, maxDate;
  var presentDates = input.map(function(row) return row[0];); //Turns input into an array of only the element 0 (the date)
  minDate = presentDates.reduce(function(a,b)  return a<b?a:b); //For each value, if its the smallest: keep; otherwise: skip;
  maxDate = presentDates.reduce(function(a,b)  return a>b?a:b); //Same as above, but largest.

  var dates = [];
  for (var currentDate = minDate; currentDate <= maxDate; currentDate.setDate(currentDate.getDate()+1)) 
    dates.push(getFormattedDate(currentDate)); //Insert each unique date from minDate to maxDate (to leave no gaps)
  

  var uniqueNames = input.map(function(row) return row[1];) //Turns input into an array of only the element at 1 (the names)
                         .filter(function (value, index, self) return self.indexOf(value) === index;); //Removes duplicates from the array (Remove the element if the first appearence of it on the array is not the current element's index)

  var output = ; //Temporary dictionary for easier counting later on.
  for (var i=0; i< dates.length; i++) 
    var dateKey = dates[i];
    for (var userIndex = 0; userIndex <= uniqueNames.length; userIndex++) 
      var mapKey = uniqueNames[userIndex]+dateKey; //Match each name with each date
      input.map(function(row) return row[1]+getFormattedDate(row[0])) //Translate input into name + date (for easier filtering)
      .filter(function (row) return row === mapKey) //Grab all instances where the same date as dateKey is present for the current name
      .forEach(function(row)output[mapKey] = (output[mapKey]||0) + 1;); //Count them.
    
  

  var toInsert = []; //Array that will be outputted into sheets
  var firstLine  = ['names X Dates'].concat(dates); //Initialize with header (first element is hard-coded)
  toInsert.push(firstLine); //Insert header line into output.


  uniqueNames.forEach(function(name) 
    var newLine = [name];
    for (var i=0; i< dates.length; i++)  //For each name + date combination, insert the value from the output dictionary.
      var currentDate = dates[i];
      newLine.push(output[name+currentDate]||0);
    
    toInsert.push(newLine); //Insert into the output.
  );

  sheet.getRange(1, 5, toInsert.length, toInsert[0].length).setValues(toInsert); //Write the output to the sheet


// Returns a date in the format MM/dd/YYYY
function getFormattedDate(date) 
  var year = date.getFullYear();

  var month = (1 + date.getMonth()).toString();
  month = month.length > 1 ? month : '0' + month;

  var day = date.getDate().toString();
  day = day.length > 1 ? day : '0' + day;

  return month + '/' + day + '/' + year;


运行脚本结果:

【讨论】:

变量 currentDate 在哪里实例化为 new Date()?这会产生在 object 中找不到函数 getFullYear 和 getMonth 的错误。 @Gabriel, currentDate 已声明并在循环中使用,但您始终可以使用快捷键 Ctrl+F 来搜索内容。如果您想获得与我提供的相同的结果,只需在列 A 中填写日期(MM/dd/YYYY)并在 B 中填写名称,然后将源代码复制粘贴到脚本中,然后运行它。你会得到同样的结果。当您看到它可以工作时,开始将代码调整到您的项目中。

以上是关于如何处理谷歌表格脚本中的重复项?的主要内容,如果未能解决你的问题,请参考以下文章

在使用具有剪切和粘贴功能的Apps脚本时,如何处理Google表单中的新数据?

如果谷歌电子表格的同一列中的值重复,如何突出显示单元格?

如何处理DataFrame中缺失项

SSAS - 如何处理具有有效重复项的维度?

iOS - 如何处理自定义表格单元格中的方向变化

Linux 中的 SEH 等效项或如何处理操作系统信号(如 SIGSERV)并继续