Google表格:自动合并相同的单元格

时间:2019-06-30 14:44:19

标签: google-apps-script google-sheets google-sheets-api

我正在尝试合并垂直相邻且具有相同值的单元格。

|"X"|         |"X"|
|"X"|   --->  |   |
|"X"|         |   | (merged)

我正在制作一个时间跟踪表,并且合并类似的活动将非常棒 example image from my sheet (因此,“睡眠”将合并为一个大块,“跟踪此工作表”也将合并)

我只想垂直合并单元格

(而且,我仅在B26:H121范围内操作)

为此,我尝试在stackoverflow上使用一些现有代码-Google Sheets - Horizontal merge identical cells in single rowMerge cells with same words-但我什么都做不了。也许是因为我不懂javascript哈哈。

———

还有最后一件事,如果可能的话,我想以某种方式存储合并单元的大小。 (在上图中,用于睡眠和跟踪此工作表的时间分别为16和4。)这将使我能够跟踪合并单元格时执行任何特定任务的时间。 (也许将此数字存储在单元格附带的注释中?)

请帮助, 保罗

2 个答案:

答案 0 :(得分:0)

您可以使用merge()方法合并给定范围内的所有垂直单元格,该方法可用于Range对象。您可以查看here merge()方法的工作方式文档。

以下代码将垂直合并单元格,只要它们具有相同的非空值并且彼此相邻即可。

function numberToLetter(number){
  var temp = "" 
  var letter = "";
  while (number > 0){
    temp = (number - 1) % 26;
    letter = String.fromCharCode(temp + 65) + letter;
    number = (number - temp - 1) / 26;
  }
  return letter;
}

function myFunction() {
  var ss = SpreadsheetApp.getActiveSheet();

  for (col = 2; col <=8; col++){ //Do from Columns B to H (B = 2, H = 8)
    var start = 26; // Start row range
    var end = 121;  // End of Row range
    var mergeArr = [];
    var colData = ss.getRange(start, col, end, 1).getValues().toString().split(","); 
    var last = false;
    var count = -1;

    colData.forEach(function(e) {
      if (e == last){
        count++;
      }
      else if (e != last){
        mergeArr.push(count + 1);
        count = 0;
      }
      last = e;
    });

    var mergeStart = start;   
    for (each = 0; each < mergeArr.length; each++){

      var mergeEnd = mergeStart + mergeArr[each] - 1;      

      if (ss.getRange(numberToLetter(col) + mergeStart).getValue() == "" ){        
      }
      else{
        if (mergeEnd - mergeStart >= 1){
          ss.getRange(numberToLetter(col) + mergeStart + ':' + numberToLetter(col) + mergeEnd).merge(); 
        }
      }
      mergeStart = mergeEnd + 1;      
    }     
  }
}

您可以在start循环中通过更改endcol的值和for的范围来修改此范围。

答案 1 :(得分:0)

Rafa Guillermo 的解决方案几乎正是我想要的,但我做了两个小改动:1) 我想将列指定为数组(基于 1 的索引)和 2) 我的一些数据在单元格中包含逗号,这不不适用于 toString().split(",") 方法。

function numberToLetter(number){
  var temp = "" 
  var letter = "";
  while (number > 0){
    temp = (number - 1) % 26;
    letter = String.fromCharCode(temp + 65) + letter;
    number = (number - temp - 1) / 26;
  }
  return letter;
}

function mergeColumns() {
  var ss = SpreadsheetApp.getActiveSheet();
  cols = [1, 2, 4, 5, 6, 7, 11]   
  var start = 1; // Start row range
  var end = 500;  // End of Row range

  cols.forEach( function (col) { // For each relevant column
    var mergeArr = [];
    var colData = ss.getRange(start, col, end, 1).getValues() 
    var last = null;
    var count = -1;

    colData.forEach(function(e) {
      eStr = e.toString()
      if (eStr === last){
        count++;
      } else {
        mergeArr.push(count + 1);
        count = 0;
      }
      last = eStr;
    });

    var mergeStart = start;   
    for (each = 0; each < mergeArr.length; each++){

      var mergeEnd = mergeStart + mergeArr[each] - 1;      

      if (ss.getRange(numberToLetter(col) + mergeStart).getValue() == "" ){        
      }
      else{
        if (mergeEnd - mergeStart >= 1){
          ss.getRange(numberToLetter(col) + mergeStart + ':' + numberToLetter(col) + mergeEnd).merge(); 
        }
      }
      mergeStart = mergeEnd + 1;      
    }     
  })
}

function onOpen() {
  var ui = SpreadsheetApp.getUi();
  // Or DocumentApp or FormApp.
  ui.createMenu('Custom Menu')
      .addItem('First item', 'mergeColumns')
      .addToUi();
}