范围
我开始编写一个脚本,它将对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.
答案 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行的数据求和。
我找到的解决方案:
在我的示例中,我将SUMIFS公式更改为从第4行(标题)开始求和。我总是喜欢这样,在上一页中,脚本运行良好。
在开发过程中,我没有注意到如何更改这些公式以从第4行求和,并且由于Google表格中出现的此问题,脚本停止运行。