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