服务错误:Google脚本上的电子表格

时间:2014-04-19 02:29:53

标签: javascript json google-apps-script

范围

我开始编写一个脚本,它将对API进行链式调用(带有JSON响应)并将结果写入电子表格。

发生了什么:

一旦我调试脚本代码,它运行得很好,没有任何重大问题,但一旦我从电子表格按钮本身(从我创建的菜单)运行它它运行脚本的一些步骤,然后弹出一个: Service Error: Spreadsheet没有其他错误详情。

怪诞

我开始将进程的当前步骤“记录”到Spreadsheet单元格,以便我可以在调试器中运行脚本时监视其进度。

问题是,一旦我移动了一些“随机”的部分,例如:

sheet.getRange("F2").setValue(currentPage);

代码往往会在不同的点上破解。

代码示例:

您可以在此处找到重现问题的代码:http://pastebin.com/HjmSwEYZ

您所要做的就是:

1 - 在Google云端硬盘上创建新的电子表格

2 - 点击工具 - >脚本编辑器

3 - 创建新脚本,粘贴代码并保存

4 - 重新加载电子表格(F5),以便自定义菜单现在显示为“Guild Wars 2 Tracker”

5 - 点击按钮并点击“全部列出”

期望输出:

这段代码应该(如果不是这个错误)这样做:

1 - 对此网址执行请求:http://www.gw2spidy.com/api/v0.9/json/items/all/1(将返回激战2的第一页)

2 - 遍历每个页面,解析json并将返回的值写入电子表格

声明:

对于表格中的所有“日志”消息感到抱歉。这是追踪我进步的绝望尝试,我知道我不应该这样做。

提前致谢

更新1:

创建另一个电子表格并将pastebin代码粘贴到自己的脚本项目后,我可以运行它进行交互,但就是这样。这一次,它引发了一个不同的错误:We're sorry, a server error occurred. Please wait a bit and try again.

8 个答案:

答案 0 :(得分:3)

我喜欢ellockie所说的 - 我(不知不觉中)有同样的问题。我试图使用range.sort(8),但为了收集范围,我使用了:

sheet.getRange(2,1,sheet.getMaxRows(), sheet.getMaxColumns());

但我应该使用的是:

sheet.getRange(2, 1, sheet.getMaxRows()-1, sheet.getMaxColumns());

截至2015年5月1日的错误消息仍然非常神秘,并没有提供比“服务错误:电子表格”更详细的信息。

答案 1 :(得分:2)

Marchello,我今天遇到了同样的问题,并且刚刚找到了答案来解决这个问题:https://code.google.com/p/google-apps-script-issues/issues/detail?id=3815(参见#4)。我们的想法是在工作表底部添加行,让脚本重新开始工作。它确实适用于我的情况。

答案 2 :(得分:1)

当您访问不正确的范围时,您会收到这样的服务错误,并且只有在后续访问之后,该错误才会引发。例如,如果您得到一个Range来引用不存在的列(如只有A-E则为H),或不存在的行(如只有10000行则为10001)。 Apps脚本问题跟踪器中对此进行了说明:https://issuetracker.google.com/issues/68062620

关于问题的根源,您的脚本未经高度优化,并且在使用电子表格服务方面未遵循Apps脚本"Best Practices"。即,您应该使用诸如Range#setValues操作之类的批处理操作来写入整个块,或者至少使用appendRow来附加每行(而不是sheet.getRange(rowIndex, someColumn).setValue(oneValue))。这些方法将在需要时添加相关行以保存数据。

代码修改示例:

var itemFields = [ "name",
                   "rarity",
                   "price_last_changed",
                   "max_offer_unit_price",
                   "min_sale_unit_price",
                   "offer_availability",
                   "sale_availability" ];
function addResultPage_(sheet, results) {
  const imgs = [],
  const data = results.map(function (result, index) {
    if (result.img)
      imgs.push({row: index, url: result.img});
    return itemFields.map(function (field) { return result[field] || ""; });
  });
  if (!data.length) return;

  const startRow = sheet.getLastRow() + 1;
  sheet.getRange(startRow, 2, data.length, data[0].length).setValues(data);
  if (imgs.length)
    imgs.forEach(function (imgInfo) {
      sheet.insertImage(imgInfo.url, 1, startRow + imgInfo.row);
    });
}
function listAllItems() {
  const sheet = SpreadsheetApp.getActiveSheet(),
        totalPages = updateStartStatus("List All Items");

  for (var page = 1, page <= totalPages; ++page) {
    var pageResults = getItemsByPage(page);
    if (pageResults.results)
      addResultPage_(sheet, pageResults.results);
    else
      console.warn({message: "No results for page '" + page + "'", resp: pageResults});
  }
}

答案 3 :(得分:0)

在我的情况下,我使用了“动态”范围的公式,即=sum(b2:b),我记得在新的Google电子表格中提到了一些问题。

更正sum(b2:b22)(确保范围不超过工作表的最后一行)解决了问题。

答案 4 :(得分:0)

在我的情况下,我收到此错误,因为当电子表格中只有19个时,我要求另一个电子表格对25个列的数据进行排序。

根据我的智慧,我认为在编写脚本以排序25列而不是使用getLastColumn之后删除不需要的列时,我会整理电子表格 - 不要问我原因。

答案 5 :(得分:0)

我有与ellockie提到的相同的问题原因:公式中的动态范围。在我的情况下,我使用=INDEX(B7:B,1)来获取我的列标题之后的第一个单元格,即单元格B7。我正在使用它,因为我使用sript插入一个新单元格,将所有实际数据向下移动,所以我需要在其他单元格中获取第一行值,无论我移动单元格。我将其更改为=INDIRECT(CONCATENATE(CHARACTER(COLUMN()+64);ROW()+4))以引用它动态

  • CHARACTER(COLUMN()+64)给出了专栏信。替换=INDEX(B7:B,1)表示B
  • ROW()+4给我我想要的行号,我把这个公式下的4行。替换=INDEX(B7:B,1)表示7

答案 6 :(得分:0)

我也一样。但是找出了根本原因,那就是试图复制一个单元格...您相信吗?

脚本的一部分试图清除一行,那该死的单元格在那里。 我试图复制一行并且整个电子表格崩溃。重新启动并继续进行操作,一个接一个地复制单元格,并发现空单元格会导致崩溃。删除了整列和所有其他空列...然后穿过天堂的大门!

现在,可以复制整行,脚本工作正常!!!!

答案 7 :(得分:0)

我遇到了类似的问题,突然我开始在执行脚本时出现错误。

例外:访问具有ID的文档时,服务电子表格失败

问题出在与移动范围相关的公式中。

因此,通过使用标头或一个额外的单元格来修改使用问题范围的公式(如果从编辑器运行脚本,则显示脚本在哪一步进行堆叠)完全解决了我的问题。

在我的示例中,我在脚本的第5行上方添加了新单元格,在其他工作表上,我有SUMIFS公式对第5行的数据求和。

我找到的解决方案:

  1. 在公式中添加一个额外的单元格,以便在其中添加新单元格时保持不变。

在我的示例中,我将SUMIFS公式更改为从第4行(标题)开始求和。我总是喜欢这样,在上一页中,脚本运行良好。

在开发过程中,我没有注意到如何更改这些公式以从第4行求和,并且由于Google表格中出现的此问题,脚本停止运行。

  1. 如果第一种方法不适合您,则可以使用INDIRECT函数代替实际范围。 这样,我可以从第5行开始求和,脚本运行良好。