Google表格-水平合并单行中的相同单元格

时间:2018-12-14 13:41:43

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

我正在努力更新以下示例的代码示例: Merge cells with same words 由@Tanaike提供

我本质上是在尝试与上面的示例代码做相同的事情,但是有一个不同之处,就是我希望将其旋转为在类似的列上水平工作,而不是在类似的行上垂直工作。

我尽了最大的努力来翻转功能,但是我非常初级,陷入僵局。下面是我编辑的代码段,我标记了我的理解范围的那一行,所以我认为那里有些问题。

function mergeMonths() {
  var start = 6; // Start row number for values.
  var c = {};
  var k = "";
  var offset = 0;
  var ss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("BlockingChart1");

  // Retrieve values of column B.
  var data = ss
    .getRange(4, start, 1, ss.getLastColumn())
    .getValues()
    .filter(String);

  // Retrieve the number of duplicate values. //This is where my eyebrow starts to raise.
  data.forEach(function(e) {
    c[e[0]] = c[e[0]] ? c[e[0]] + 1 : 1;
  });

  // Merge cells.
  data.forEach(function(e) {
    if (k != e[0]) {
      ss.getRange(4, start + offset, 1, c[e[0]]).merge();
      offset += c[e[0]];
    }
    k = e[0];
  });
}

只需100%清除: 我希望检查给定(排序)行中具有重复内容相同的单元格,然后合并重复的单元格。 (我正在制作日历类型图表,每个单元格每周一次,但希望将顶部标记为几个月,因此合并重复的“ ... Dec,Jan,Jan,Jan,Jan,Feb ...”进入标题。

如果有人想向我介绍一些可能对我的旅程有帮助或可以伸出援助之手的书,将不胜感激。

1 个答案:

答案 0 :(得分:4)

如果我理解正确,则希望转换一行像这样的单元格:

Jan | Jan | Feb | Feb | Feb | Mar | Apr | Apr | Apr |

对此:

Jan | Feb | Mar | Apr |

如果可以,我可以帮忙!

步骤1。获取数据

我认为您的问题的部分原因在于您致电getRange(row, column, numRows, numColumns)

在注释中,您说var start = 6是开始行,但是将其放在列位置。不确定您的意图是什么,但是拥有一个startRow和一个startCol变量可能会更清楚。例如,

var startRow = 1;
var startCol = 1;

// Later...
ss.getRange(startRow, startCol, 1, ss.getLastColumn())

在Google脚本中调用Range.getValues()会返回二维的“数组数组”。在我提供的示例单元格中,您将得到类似:

data = [['Jan', 'Jan', 'Feb', 'Feb', 'Feb', 'Mar', 'Apr', 'Apr', 'Apr']]

由于我们只处理一行,所以我们可以采用此外部数组的第一项并调用 that 数据,从而简化了一些事情。所以我会做:

var data = ss
 .getRange(startRow, startCol, 1, ss.getLastColumn())
 .getValues()
 .filter(String)[0];

哪个给你:

data = ['Jan', 'Jan', 'Feb', 'Feb', 'Feb', 'Mar', 'Apr', 'Apr', 'Apr']

步骤2。计算重复值

下一部分代码用于计算每月重复的次数。使用我们的漂亮的一维数组,我们可以使代码更简单:

data.forEach(function(e) {
  c[e] = c[e] ? c[e] + 1 : 1;
});

在这里,我们遍历数组data,依次处理每个条目“ e”。 ({e将是“ Jan”,然后是“ Jan”,然后是“ Feb”)。我们将计数存储在对象c中,该对象开始为空白,完成后将如下所示:

c = {Feb: 3.0, Apr: 3.0, Jan: 2.0, Mar: 1.0}

?:的东西是精美的JavaScript ternary语法,基本上是这样说的:

    c[e] = c[e] ? c[e] + 1 : 1;
   [-----] [-----][-------][---]
      |       |       |      |
      |       v       |      |
(1) "have we already created an entry in c for this month e (eg, "Jan")?
      |               |      |
      |               v      |
(2) "if so, COUNT is the current value (look it up) plus 1
      |                      |
      |                      v
(3)   |            "if not, COUNT is 1"
      |
      v
(4) "store the COUNT we found in c"

步骤3。合并重复值

最后一步可能像这样:

data.forEach(function(e) {
  if (e != k) {
    ss.getRange(startRow, startCol + offset, 1, c[e]).merge();
    offset += c[e];
  }
  k = e;
});

同样,事情要简单一点,因为data现在是一个1d数组,而不是2d数组。

完整代码

function mergeMonths() {

  var startRow = 1;
  var startCol = 1;
  var c = {};
  var k = "";
  var offset = 0;

  var ss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("BlockingChart1");

  // Get data from sheet
  var data = ss
  .getRange(startRow, startCol, 1, ss.getLastColumn())
  .getValues()
  .filter(String)[0];

  // Count duplicates
  data.forEach(function(e) {
    c[e] = c[e] ? c[e] + 1 : 1;
  });

  // Merge duplicate cells
  data.forEach(function(e) {
    if (e != k) {
      ss.getRange(startRow, startCol + offset, 1, c[e]).merge();
      offset += c[e];
    }
    k = e;
  });

}

快速提示

最后一条提示:记录器对于查看代码中的正在发生的事情非常有用。当您测试代码时,我会坚持以下代码:

Logger.log("data: %s", data);

Logger.log("e: %s", e);

在所有地方,然后查看Google脚本日志(查看>日志)以了解变量在不同点的位置。