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

2023-12-28

我正在努力更新在以下位置看到的代码示例:合并具有相同单词的单元格 https://stackoverflow.com/questions/49212749/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...”到标题中。

如果有人想给我指点一些可能对我的旅程有帮助的读物,或者可以伸出援手,我将不胜感激。


如果我理解正确的话,您想要转换一行单元格,如下所示:

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

进入这个:

Jan | Feb | Mar | Apr |

如果是这样,我可以帮忙!

步骤 1. 获取数据

我认为你的问题部分来自于你的电话getRange(row, column, numRows, numColumns) https://developers.google.com/apps-script/reference/spreadsheet/sheet#getrangerow-column-numrows-numcolumns.

在评论中你说var start = 6是起始行,但您将其放在列位置。不确定你的意图是什么,但有一个可能更清楚startRow and a startCol多变的。例如,

var startRow = 1;
var startCol = 1;

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

Calling Range.getValues()在 Google 脚本中返回一个二维“数组的数组”。通过我提供的示例单元格,您将得到类似以下内容的内容:

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将是“一月”,然后再次是“一月”,然后是“二月”)。我们将计数存储在一个对象中,c它开始时是空白的,当我们完成时将如下所示:

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

The ? and :东西很花哨的 JavaScriptternary https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Conditional_Operator语法,基本上是说:

    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现在是一维数组而不是二维数组。

完整代码

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);

and

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

到处查看,然后检查 Google 脚本日志(查看 > 日志)以了解不同点的变量。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Google Sheets - 水平合并单行中的相同单元格 的相关文章

随机推荐