【问题标题】:How can i convert a 3D array to 2D array in GAS?如何在 GAS 中将 3D 数组转换为 2D 数组?
【发布时间】:2016-10-30 22:49:48
【问题描述】:

我有一个包含几张工作表的电子表格,我想获取一个数据范围,对其进行过滤并将过滤后的数据的值设置到另一张工作表中。 我可以使用 .getvalues 并循环遍历该数组中的所有值,将我需要的值推送到新数组和 .setvalue(逐行)到新工作表。 我真正想要的是使用批处理.setvalues 来加快速度。 问题是当我将值推送到我的第二个数组时,我最终得到一个 3D 数组,而 .setvalues 只接受 2D 数组。 我一直在搜索并发现了类似的问题(herehere),但还没有解决我的问题。 我需要一个比逐行循环设置值更快的解决方案。

我的代码如下所示:

var shSales=ss.getSheetByName('Relação de Vendas'), lrowSales=shSales.getLastRow();
var shArchive=ss.getSheetByName('Hx Faturação')
var shSalesData=shSales.getRange(7,1,lrowSales-6,15).getValues();
var InvoicedSales=[];
var deleted=0;

for (var i in shSalesData) {
  if (shSalesData[i][12]!=[] && shSalesData[i][13]!=[] && shSalesData[i][14]!=[]) {
    InvoicedSales[i]=[];
    InvoicedSales[i].push(shSalesData[i]);
    shSales.deleteRow((parseInt(i)+7)-deleted);
    deleted++;
  }
}
var lrowArchive=shArchive.getLastRow();
var range=shArchive.getRange(lrowArchive+1, 1, 2, 15);
range.setValues(InvoicedSales);

SpreadsheetApp.flush();

你能帮我解决这个问题吗?

【问题讨论】:

  • 请添加示例输入数据和minimal reproducible example
  • InvoicedSales.push(shSalesData[i]);?
  • @RobinGertenbach 你的评论出现在我写答案的时候。在最短的时间内,你是对的。至于 OP,我的回答也解释了你在哪里以及为什么会遇到这个问题。不过,我会投票赞成该评论!
  • @RobinGertenbach 感谢您的回答,因为 Vytautas 也提出了解决方案,但由于我是 javascript 新手,在阅读 Vytautas 评论之前我不明白。
  • 作为活跃用户,我也是 SO 新手。谁能解释一下为什么对这个问题投反对票?

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


【解决方案1】:

据我所知,您正在从头开始创建一个数组,因此您需要找到它变成 3D 数组的位置,并通过使用适当的算法来构建您希望推送到电子表格的数组来防止它发生。

通过快速调试,您可以发现问题确实发生在以下 2 行:

InvoicedSales[i]=[];
InvoicedSales[i].push(shSalesData[i]);

所以在第一行之后我们得到一个InvoicedSales[[]],在第二行之后你将得到InvoicedSales[[[data]]],它现在是一个 3D 数组。

正如我所提到的,解决此问题的一个简单方法是用不同的方式构造数组。这两行可以简单地替换为

InvoicedSales.push(shSalesData[i]);

这样做的缺点是,如果您希望保留空格,这将简单地创建一个不反映不符合您的if 语句的数据的数组。为了在您的数组中也有空白行,您必须包含一个 else 段,它将 push 一个空数组添加到您的 InvoicedSales 中,这样我们就会有以下内容:

for (var i in shSalesData) {
  if (shSalesData[i][12]!=[] && shSalesData[i][13]!=[] && shSalesData[i][14]!=[]) {
    InvoicedSales.push(shSalesData[i]);
    shSales.deleteRow((parseInt(i)+7)-deleted);
    deleted++;
  }
  else {
    InvoicedSales.push([])
  }
}

因此,当满足if 时,该代码会将数据数组推送到InvoicedSales,并在不满足if 时推送一个空数组。这样,如果第 1 行符合条件,则将其作为第 1 行推送,如果第 3 行接下来符合条件,则在输出数组上它仍然是第 3 行。

请注意,通过这样做然后使用setValues(),所有空行都会清除该特定行中的任何内容!所以[[a,b,c],[],[1,2,3]] 会将电子表格值设置为

a b c

1 2 3

无论之前的单元格是什么,中间的行都是空白的

【讨论】:

  • 感谢您的努力和出色的解释,但是当我删除第一行时:InvoicedSales[i]=[]; 我得到一个 TypeError cannot call method 'push' of undefined 我一定是做错了,也许:-(
  • @JoséLuísSincereSepúlveda 仅删除该行是不够的,仔细查看您的代码,最初您有 InvoicedSales[i].push(shSalesData[i]); 因此您必须从 InvoicedSales[i] 中删除 [i],因为它需要一个数组在数组内部,但我们只想使用主数组来代替
  • 我的错,我错过了。它工作得很好。非常感谢你,很抱歉让你在这件事上浪费了额外的时间。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-01
  • 2019-10-31
  • 1970-01-01
  • 2017-07-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多