【问题标题】:Excel Script run from Power Automate failing with error 504从 Power Automate 运行的 Excel 脚本失败并出现错误 504
【发布时间】:2021-07-10 09:19:27
【问题描述】:

我每天都在使用 PowerAutomate 向报告中添加数据。数据以 CSV 附件的形式通过电子邮件传入,使用 Azure 函数将其解析为 2D 数组并字符串化为 JSON,然后将其传递给解析 JSON 的 excel 脚本,将行数组截断为正确的宽度,添加将公式添加到计算列的行数组中,并使用table.addRows() 函数将数据添加到表中。

这发生在来自三个不同报告的三个不同表格上(间隔 30 分钟)。

  • 一个很小,每天添加约 10 行,没有添加公式列,这在 PowerAutomate 中总是很好并且很成功。
  • 第二个是每天约 150 行,添加了一个公式列。这总是会成功添加数据,但有时 PowerAutomate 连接器会失败并显示 504 BadGateway - Request to Graph API has timed out
  • 第三个是每天约 150 行,添加了一些公式列。这通常会失败,要么成功添加日期但返回上述错误,要么添加数据失败并返回 我们无法运行脚本。请再试一次。 Office JS 错误:第 44 行:表 addRows:请求失败,状态代码为 504,错误代码 UnknownError

这是函数本身(特别是第三个示例):

function main(workbook: ExcelScript.Workbook, inputData: string) {

  // Get formula columns as array of strings
  const additionalData = workbook.getWorksheet(`contact_time`).getRange("W2:AG2").getFormulas()[0]

  // Parse inputData to get actual array
  const dataToAdd: Array<Array<string>> = JSON.parse(inputData)

  // Remove first row's data as is just headers
  dataToAdd.shift()

  if (dataToAdd.length == 0) {
    return
  }

  // Truncate each input array row and add formula array columns on to the end
  for (const row of dataToAdd) {
    row.length = 22
    for (const column of additionalData) {
      row.push(column)
    }
  }

  // Add data to table
  workbook.getTable("t").addRows(null, dataToAdd)
}

为了尝试优化这个,我有

  • 在脚本中,尽可能少地访问工作簿以减少请求
  • 删除了对 .getFormulas() 的调用,改为硬编码一个数组
  • 将 PowerAutomate 超时更改为 P1D 并重试为无
  • 已将工作簿/集计算模式的重新计算关闭为手动(在工作簿级别和脚本本身的开头)

如果我将 JSON 粘贴到函数中并在浏览器中运行它,这 100% 的时间都有效。 我无法确定这是由于实际函数超时、PowerAutomate 未能等待足够长的时间以获得结果、Graph API 中的一些超时,还是其他原因。

工作簿大小小于 5mb,最常失败的表大约有 13.000 行。

编辑:

我要添加的工作簿包含这三个表的工作表,另外还有一些带有分析表的工作表。我还测试了删除不同的工作表、引用等。减速似乎是表中已经存在的公式列,因为只有完全删除这些列才能使函数在每个实例中都成功。现在不是在 90 秒内超时,而是在 8 秒内完成,没有任何问题。为什么这会影响重新计算关闭时的速度?

【问题讨论】:

  • 这可能是一个愚蠢的问题,但是您是否检查过 inputData 是您所期望的,以及当它被解析时 dataToAdd 是您所期望的?
  • @norie 是的,通过日志记录和其他检查完成了这项工作,当数据实际上存在错误时,错误是非常直接的,并且善于说出问题所在。行数组中太多或太少的项目在一两秒内在.addRows() 处失败,所以我知道实际的.addRows()ing 才是需要时间的。
  • FWIW,在 VBA 中将计算设置为手动是尝试提高效率时的标准做法,尽管我从未听说过自动计算实际上会破坏代码。
  • 目前开启或关闭计算的结果是一样的。但是,如果我将公式粘贴为前几行的文本,它现在可以正常工作。如果即使将计算设置为手动,表格中的公式也会影响速度,那么 API 或后端似乎存在一些问题。

标签: excel microsoft-graph-api power-automate office-scripts


【解决方案1】:

这可能是由于在向表中添加新行时表运行自动重新计算而发生的。对大小合适的表执行此操作时,图形可能会超时。我们可以通过将计算选项设置为 Manual 来将 recalc 操作与 table 操作解耦,然后在 table 操作完成后回到 Automatic 以启动 recalc。

// At the beginning of the script right after main() function,
...
// Set calculation mode to manual
workbook.getApplication().setCalculationMode(ExcelScript.CalculationMode.manual);
// do your processing...
// Set calculation mode back to automatic
workbook.getApplication().setCalculationMode(ExcelScript.CalculationMode.automatic);   

【讨论】:

  • 不幸的是,这不起作用,如问题中所述,整个工作簿的重新计算已关闭。我进行了编辑以使这一点更清楚。在脚本的开头使用这个,行为和错误是相同的。
【解决方案2】:

从进一步的测试看来,即使将计算设置为手动,任何包含公式的表在使用 table.addRows() 时都会导致速度变慢,并且 Graph API 或 PowerAutomate 连接器无法等待足够长的时间来获得响应。

我发现的唯一解决方案是最小化或消除那些公式

  • 正在添加到的表中
  • 引用要添加到的表

当我将问题表中的公式作为值粘贴并重新尝试添加行时,它第一次工作,没有对其他任何内容进行任何更改。

在我的情况下,我需要直接在我的表中计算列,因此我会定期将脚本添加的公式替换为值。这可以手动完成,也可以使用脚本通过在您指定的范围上使用 range.setFormulas(range.getValues()) 来完成(我建议将此范围限制在您需要的范围内,因为即使在浏览器中它在超时之前也只完成了大约 1000 行,所以您不应该在整张桌子上使用它)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-06-28
    • 1970-01-01
    • 2014-11-04
    • 1970-01-01
    • 2016-09-20
    • 1970-01-01
    • 2018-09-13
    • 2021-01-07
    相关资源
    最近更新 更多