10

我有一个Google时间表数据电子表格;它每个月都有一个表格,每个表格有六个列块,每个客户端一个块。脚本来总结数据不更新

我创建了去,并得到总额为每个客户端,并将其显示在列表汇总单:

function getClientTotals(sheetname, colcount) 
{ 
    colcount = colcount ? colcount : 6; 
    var res;  
    var ss = SpreadsheetApp.openById('myid_goes_here'); 
    if(ss) 
    { 
    res = []; 
    var totrow = ss.getRange(sheetname + '!A1:ZZ1').getValues()[0]; 
    for(var i = 0; i < totrow.length; i += colcount) 
    { 
     res.push([totrow[i], totrow[i + colcount - 1]]); 
    } 
    } 
    return res; 
} 

我已经然后只是增加了一个电池含有=getClientTotals($C$7,$C$8)其通过在我的汇总表表格名称和每个客户端的列数(在“模式”修改的情况下)

这一切工作正常,但是,它不会更新源数据更改时我添加了一个onEdit触发器;没有喜悦,它更新如果你去脚本编辑器并点击保存,但这不是有用的湖我错过了什么吗?

+0

不缺少任何东西;这可能有助于在Google问题跟踪器中投票申请此功能请求:https://issuetracker.google.com/issues/36763858 –

回答

28

您错过了挑剔的高速缓存错误功能。它的工作原理如下:

Google认为您的所有自定义函数都依赖于只有直接返回它们的参数值(您可以选择性地依赖于其他静态数据)。

有了这个先决条件,他们只有在参数改变时才能评估你的函数。例如

让我们假设我们有B1单元格中的文字“10”,然后在其他一些细胞中我们输入=myFunction(B1)

myFunction的进行评估,并将其结果检索。然后,如果将单元格B1的值更改为“35”,则将按照预期重新评估自定义,并正常检索新结果。 现在,如果您再次将单元格B1更改为原始“10”,则不会重新评估,原始结果将立即从缓存中检索出来。

因此,当您使用工作表名称作为参数来动态获取并返回结果时,您正打破缓存规则。

不幸的是,没有这个惊人的功能,你不能拥有自定义功能。因此,您必须将其更改为直接接收值,而不是表名,或者不要使用自定义函数。例如,您可以在脚本上拥有一个参数,告诉其摘要应该到哪里,并且每当总数发生变化时,都会有一个参数更新它们onEdit

+1

嗯,这很烦人,但谢谢你的答案!通过向函数添加一个虚拟参数,我得到了一个讨厌的解决方法;如果我然后传递一个单元格引用,我可以通过在该单元格中增加一个数字来强制刷新数据。不要以为无论如何我都可以创建一个刷新按钮,点击就可以做到这一点,是吗?这很好,它不需要自动,只是简单明了。 – Whelkaholism

+0

那么,你可以创建一个按钮,实际上是一个绘图并为其分配一个脚本函数,这将增加你将强制更新的虚拟参数单元。 –

+0

太棒了,完美的作品,谢谢! – Whelkaholism

1

缓存问题的另一种解决方案。

在您的方法中有一个虚拟变量。 pass

Filter(<the cell or cell range>,1=1) 

作为该参数的值。

例如

=getValueScript("B1","B4:Z10", filter(B4:Z10,1=1)) 

过滤器的输出未被使用。但是它向电子表格显示此公式对B4:Z10范围敏感。

+3

它不再工作。您将看到错误“如果您尝试以这种方式执行此功能,则不允许使用NOW(),RAND()或RANDBETWEEN()引用单元格 –

-1

正如@Brionius所说的那样在功能上加了一个额外的动态论据。如果你现在使用()你可能有超时问题,使更新慢一点...

cell A1 = int(now()*1000) 
cell A2 = function(args..., A1) 
+2

它不再起作用。您将看到错误“如果您尝试以这种方式执行此操作,则不允许此函数使用NOW(),RAND()或RANDBETWEEN()引用单元格 –

0

你可以做的是地方设立另一个单元格将被每次添加新的工作表时更新电子表格。请确保它不更新的每一个变化,但只有当你想要做的计算(在你的情况下,当您添加纸张)。然后,您将对此单元格的引用传递给您的自定义函数。如前所述,自定义函数可以忽略此参数。

1

我也有类似的问题,创造工作的仪表板。以上(即使用的值在你的函数传递给一个虚拟变量表的Filter功能)Chamil的解决方案工作得很好,尽管阿尔森更近的评论。就我而言,我是用一个函数来监控范围,因为它创造了一个循环引用无法使用的过滤器在同一个范围内。所以我只是有一个电池(在我的情况E45在下面的代码)中,我改变了数只要我希望我的功能更新:

=myFunction("E3:E43","D44",filter(E45,1=1)) 

由于Chamil表示,过滤器是不是在脚本中使用:

function myFunction(range, colorRef, dummy) { 
    variable 'dummy' not used in code here 
} 
0

鉴于由恩里克·阿布雷乌解释功能,您可以尝试出的现成的电子表格功能QUERY,即SQL喜欢查询是我在工作 经常使用的原始数据,并获取数据汇总到不同的选项卡,结果数据在更改后实时更新原始数据。

我的建议是基于你的剧本还没有先进的工作,如URL抓取,只是数据的工作,因为没有实际的数据读取,我不能给人以查询精确的解决方案的事实。

关于由恩里克·阿布雷乌提到缓存功能(我没有足够的声誉直接他的回答下评论),我做了测试,结果发现:

  1. 看起来没有缓存工作以下所示的测试功能的脚本:

    功能加法器(基){ 使用Utilities.sleep(5000); return base + 10; }

通过调用一个细胞施加在片材的自定义功能加法器(),然后将每个时间我看到的装载消息,并总时间超过5秒改变了单元格的值来回。 这可能与在此GAS issue:

此问题现已得到解决提到的更新。新表格中的自定义功能现在可以识别上下文,并且不会积极缓存值。

  • 本主题中提到的问题仍然存在,我的测试表明,谷歌片重新计算自定义函数每个只有当

    • 值直接函数调用的是时间改变。

    功能getCellValue(SHEETNAME,行,列) { 变种SS = SpreadsheetApp.getActiveSpreadsheet(); var sh = ss.getSheetByName(sheetName); return sh.getRange(row,col).getValue(); }

    enter image description here
    在黄色细胞的任何值的变化将导致自定义函数的重新计算;函数忽略实际的数据源值更改。

    • 包含单元格位置的函数在表单中更改。恩。插入/删除上方或左侧的行/列。