刷新单元格而不是手动按ctrl-Shift-E

时间:2013-06-08 16:44:47

标签: google-apps-script google-sheets

我在工作表上有一些查询,我将信息提取到数据库。

我遇到的问题是实现的代码很好,直到某些工作表不显示查询显示:“警告:这些结果中的一个或多个”条目可能不会显示。选择ctrl + Shift + E显示它们。

我尝试清除这些值并将它们粘贴回来无济于​​事。

我还能做什么?

1 个答案:

答案 0 :(得分:6)

恕我直言,我不认为有一个规范的回答了这个问题 - 一直存在着来自各地用户特定主题这只是消散到谷歌文档的工程团队的寂静(一嗷这个问题似乎是像IMPORTRANGE经常失败或SPLIT没有创造完美的矩阵一样笼罩在同一个永恒的奥秘中。

我被自己多次咬过,所以有一些经验。我使用了heath-robinson解决方法,这对我有用。但是YMMV。

OP的问题讨论了有一个运行良好的公式的情况,但经过一段时间的操作后,开始出现Ctrl + Shift + E情况。

(还有一些情况,由于一个公式试图覆盖到另一个公式写入的单元格的结果,可能会出现Ctrl + Shift + E.在这种情况下,有时在所需公式的开头添加EXPAND就可以了。同样使用过滤函数而不是'IF'比较,确实可以删除之前的= CONTINUE(1,2,3)单元格......但是这些单元格中的任何一个都可能对OP问题都没有帮助。“

根据我的经验,电子表格可能会随着时间的推移产生这种“混淆”的行为,因此需要Ctrl + Shift + E,这意味着一段时间内电子表格的多次使用会导致数据发生变化。我可能进一步推测,当所引用的数据更具动态性时,这种混淆行为的可能性更大,例如添加行,删除行或者还有其他公式也可以从同一数据集计算(更不用说这两个公式相互关联)。

我认为成语'混淆行为'是合适的,因为电子表格的实际工程设计只对谷歌工程师开放;我们无法使其运作合理化。所以看起来神秘而神奇的是,在OP的情况和我的经验中,电子表格运行良好,但随后改变了行为以要求Ctrl + Shift + E,而公式中没有任何变化,仅在工作表的累积数据变化中通过使用。

我使用我的示例案例给出了我的解决方法示例。请注意,在我的情况下,数据以及有问题的公式都在一张表中,我称之为生产表

解决方法涉及使用脚本在与生产表相同的电子表格中复制“模板表”。模板表在结构上与具有相同列标题的生产单相同,但只有几行样本数据。它具有与生产单相同的公式,它们指的是自相同模板表中的样本数据(而不是生产单)。重要的是,模板表没有显示“confused-behavior” - 如果模板的示例数据有任何更改,则公式单元格中不需要Ctrl + Shift + E.它还包含生产单的格式化。

因此,当脚本运行时,它会创建模板表的副本;随后,它将生产单的数据复制到此模板副本并重新应用这些格式。此副本成为新的生产表。隐藏旧的生产工作表(在我的情况下,但可以删除)。

我在每天12个人使用的任务列表电子表格上运行此系统,其中任务全天以谷歌形式进入(并且它们本身被另一个脚本复制到生产表中,未显示为与这个OP)。任务完成后,任务的行将从生产工作表中删除。因此,数据在一天中不断增长和缩小。每天晚上,通过insertSheet()函数的定时触发器创建重复的工作表。这是我使用的脚本:

function insertSheet(){
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheet =ss.getSheets()[0]; //first sheet is the production sheet
  var sheetRange = sheet.getRange('A3:P');
  var sheetValues= sheetRange.getValues();
  var d = Utilities.formatDate(new Date(), Session.getTimeZone(), 'ddMMMyyyy-hh:mm:ss');
  var ex = sheet.setName('CCEs' + d);
  var templateSheet = ss.getSheetByName('templateSheet');
  var s2 = ss.insertSheet(0,{template: templateSheet});
  var height = sheetRange.getHeight();
  s2.insertRowsAfter(2, height)
  s2.setName('CCEs');
  templateSheet.hideSheet();
  ex.hideSheet();
  s2.getRange('A3:P' + (sheetValues.length+2)).setValues(sheetValues);
  format(); //
  templateSheet.hideSheet();
  ex.hideSheet();
}

function format(){
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var formatRange = ss.getSheetByName('templateSheet').getRange('B2:N2').copyTo(ss.getSheetByName('CCEs').getRange(2,2, ss.getSheetByName('CCEs').getMaxRows() -1,14), {formatOnly:true});
}

在部署此策略之前,电子表格会在几天左右后出现“混乱行为”。

该表包含三个会混淆的公式。它们对OP并不重要,但我在此复制只是为了让读者感受到这一策略的成功:

=arrayformula(IFERROR(FILTER(if(row(O:O) =1,"Auto Time Stamp ",iferror(1/0)) &O:O&if(row(O:O) =1,"copy",),len(A:A)),"Error"))

=Arrayformula(iferror(if(filter(L:L, len(A:A)) - filter(A:A, len(A:A))>0, if( int(filter(L:L, len(A:A)) - filter(A:A, len(A:A))) = 0 , text( text(filter(L:L, len(A:A)), "HH:mm") -text(filter(A:A, len(A:A)), "HH:mm") , "H:mm") , int(filter(L:L, len(A:A)) - filter(A:A, len(A:A))) & "Day(s), " & text( text(filter(L:L, len(A:A)), "HH:mm") -text(filter(A:A, len(A:A)), "HH:mm") , "H:mm") ) ,iferror(1/0)),"Time Taken"))

=arrayformula( IFERROR(if((ISBLANK(FILTER(J1:J,LEN(A1:A))) * (FILTER(G1:G,LEN(A1:A)) = "Normal")* (now()-FILTER(A1:A,LEN(A1:A))> OverdueTimings!A1 )),"OVERDUE Normal", if((ISBLANK(FILTER(J1:J,LEN(A1:A))) * (FILTER(G1:G,LEN(A1:A)) = "Urgent")* (now()-FILTER(A1:A,LEN(A1:A))> OverdueTimings!A2 )),"OVERDUE Urgent", if((ISBLANK(FILTER(J1:J,LEN(A1:A))) * (FILTER(G1:G,LEN(A1:A)) = "Very Urgent")* (now()-FILTER(A1:A,LEN(A1:A))> OverdueTimings!A3 )),"OVERDUE V. Urgent", IFERROR(1/0)))),countif(if((ISBLANK(FILTER(J1:J,LEN(A1:A))) * (FILTER(G1:G,LEN(A1:A)) = "Normal")* (now()-FILTER(A1:A,LEN(A1:A))> OverdueTimings!A1 )),"OVERDUE Normal", if((ISBLANK(FILTER(J1:J,LEN(A1:A))) * (FILTER(G1:G,LEN(A1:A)) = "Urgent")* (now()-FILTER(A1:A,LEN(A1:A))> OverdueTimings!A2 )),"OVERDUE Urgent", if((ISBLANK(FILTER(J1:J,LEN(A1:A))) * (FILTER(G1:G,LEN(A1:A)) = "Very Urgent")* (now()-FILTER(A1:A,LEN(A1:A))> OverdueTimings!A3 )),"OVERDUE V. Urgent", iferror(1/0)))),"OVERDUE *")& " OVERDUE"))

几天后,我们删除了所有累积的旧生产单。