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

Javascript Google Sheets-水平合并单行中相同的单元格,javascript,google-apps-script,google-sheets,Javascript,Google Apps Script,Google Sheets,我正在努力更新代码示例,见: 由@Tanaike提供 我基本上是在尝试做与上面的示例代码相同的事情,但有一点不同,我希望将其旋转到类似的列上,而不是垂直于类似的行 我已经尽了最大的努力来翻转功能,但我是一个初学者,已经陷入了僵局。下面是我编辑的代码片段,我已经标记了我的理解超出窗口的特定行,因此我假设那里有错误,或者是这样 function mergeMonths() { var start = 6; // Start row number for values. var c = {};

我正在努力更新代码示例,见: 由@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,Feb…”合并到标题中


如果有人想给我指点一些阅读材料,这些阅读材料可能会对我的旅程有所帮助,或者可以帮我一把,那将不胜感激。

如果我理解正确,您希望转换一行如下所示的细胞:

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

为此:

1月| 2月| 3月| 4月|

如果是这样,我可以帮忙

步骤1.获取数据 我认为你的问题部分来自你打电话给我

在一条注释中,您说
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']]
因为我们只处理一行,所以我们可以取这个外部数组的第一项,并调用该数据,从而简化一些事情。所以我要做:

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;
});
在这里,我们在数组
数据上循环,依次处理每个条目“
e
”(
e
将是“Jan”,然后是“Jan”,然后是“Feb”)。我们将计数存储在一个对象中,
c
,该对象开始为空,完成后看起来是这样的:

c = {Feb: 3.0, Apr: 3.0, Jan: 2.0, Mar: 1.0}
这两种东西都是花哨的JavaScript语法,基本上就是说:

c[e]=c[e]?c[e]+1:1;
[-----] [-----][-------][---]
|       |       |      |
|v||
(1) “我们是否已经为本月e(如“一月”)创建了c条目?”?
|               |      |
|五|
(2) “如果是,COUNT是当前值(查找)加1
|                      |
|五
(3) |“如果不是,则计数为1”
|
v
(4) “存储我们在c中找到的计数”
步骤3.合并重复值 最后一步可以如下所示:

data.forEach(function(e) {
  if (e != k) {
    ss.getRange(startRow, startCol + offset, 1, c[e]).merge();
    offset += c[e];
  }
  k = e;
});
同样,事情稍微简单了一点,因为
数据
现在是1d数组而不是2d数组

完整代码 快速提示 最后一个提示:记录器非常有助于查看代码中发生了什么。当您测试代码时,我会像这样粘贴行:

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


到处都是,然后检查谷歌脚本日志(查看>日志)了解不同点上的变量。

哇,这是一个非常棒和彻底的回答,谢谢!我将自己重新键入每个元素以帮助学习,并在运行后报告!特别感谢对三元语法的解释(“运算符”)真的很感激!再次感谢,我好像有一个问题,SS。GETLASTROLLUN(),因为在纸的最右边有2个空白列。使用记录器并使它工作(!),但我不确定的是:由于某种原因,我不得不抵消SS。by-5,这似乎是一个奇数,因为有两列要忽略?很高兴这很有用!我不知道为什么会出现问题。该命令应该返回“最后一列有内容的位置”。如果在工作表下面有其他行的内容比标题行多,这可能会导致问题?
Logger.log("e: %s", e);