【发布时间】:2019-11-18 23:35:56
【问题描述】:
您是否遇到过Google表格的所有者在运行绑定脚本时没有“超出内存限制”错误,而同一文档的编辑器却有的情况?
我在 Google 表格中有一份报告,它是根据对 Google BigQuery 的 API 请求而创建的。这是我的绑定脚本(我排除了完整的 SQLquery 文本,因为这不是问题):
function Report_detailed() {
var t = new Array(0);
var projectId = 'project_id';
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Detailed_report");
var result = sheet;
var dateFrom = Utilities.formatDate(new Date(SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Detailed_report").getRange("B1:B1").getValue()),"GMT+3", "yyyy-MM-dd");
var dateTo = Utilities.formatDate(new Date(SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Detailed_report").getRange("B2:B2").getValue()),"GMT+3", "yyyy-MM-dd");
var lastRow = sheet.getLastRow();
sheet.getRange(6,1,lastRow,55).clearContent();
var cell = sheet.getRange("G6:BC");
cell.setNumberFormat("0.00");
var request = {
query:
' SELECT * '+
' FROM '+
' `project_id.dataset_id.table_name` '+
' WHERE '+
' date BETWEEN "'+dateFrom+'" AND "'+dateTo+'" ',
useLegacySql: "FALSE",
} ;
t[0] = new Date();
t[0] = 'Stage 1'+t[0];
var queryResults = BigQuery.Jobs.query(request, projectId);
t[1] = new Date();
t[1] = 'Stage 2'+t[1];
var jobId = queryResults.jobReference.jobId;
// Check on status of the Query Job.
var sleepTimeMs = 1000;
var n = 0;
while (!queryResults.jobComplete) {
n = n + 1;
Utilities.sleep(sleepTimeMs);
sleepTimeMs *= 2;
queryResults = BigQuery.Jobs.getQueryResults(projectId, jobId);
}
t[2] = new Date();
t[2] = 'Stage 3'+t[2];
Logger.log ('jobs');
// Get all the rows of results.
var rows = queryResults.rows;
while (queryResults.pageToken) {
queryResults = BigQuery.Jobs.getQueryResults(projectId, jobId, {
pageToken: queryResults.pageToken,
});
rows = rows.concat(queryResults.rows);
}
t[3] = new Date();
t[3] = 'Stage 4'+t[3];
if (rows) {
// Append the results.
var data = new Array(rows.length);
for (var i = 0; i < rows.length; i++) {
var cols = rows[i].f;
data[i] = new Array(cols.length);
for (var j = 0; j < cols.length; j++) {
data[i][j] = cols[j].v;
}
}
t[4] = new Date();
t[4] = 'Stage 5'+t[4];
Logger.log ('datas');
sheet.getRange(6, 1, rows.length, 55).setValues(data);
t[5] = new Date();
t[5] = 'Stage 6'+t[5];
Logger.log(t.join('\\n'));
Logger.log('Results spreadsheet created: %s');
} else {
Logger.log('No rows returned.');
}
return n;
}
其他信息:
- 从 UI 调用该函数。
- 查询大小约为 100 MB,因此执行速度非常快。
- 前 4 个阶段在 1-2 分钟内运行
- 结果表有大约 25 000 行。因此,该过程中最长的部分是为单元格设置值。
- Sheets 区域设置为美国,所有者在乌克兰,文件的编辑在其他国家/地区。
当我从我的 Google 帐户运行该函数时,一切正常,我在 5-6 分钟内得到结果表。
但是当我来自其他国家/地区的同事尝试在他们的 Google 帐户中刷新报告时,应用与我相同的日期范围,他们没有任何详细解释就出现“超出内存限制”。
您能帮我找出问题的根源吗?
我将不胜感激任何线索和建议。 非常感谢!
【问题讨论】:
-
您是否有付费的 G Suite 帐户,您的同事是否使用免费的 Gmail 帐户?
-
您可以将整个函数包装在
try/catch中,并在出现错误时获取堆栈。这将告诉您错误发生在哪一行。我会使用console.log()而不是Logger.log()。console.log()会将信息记录到堆栈驱动程序。try{ all your function code }catch(e){console.log('Error: ' + e + "\n" + e.stack)}从代码编辑器的 View 菜单中,选择 Stackdriver Logging。有关更多信息,请选择帮助、文档、搜索故障排除。 -
@Diego 感谢您的提示。我的同事有免费的 G Suite。他们尝试了不同的 gmail 帐户来刷新报告,并且他们已经停止调用功能 24 小时。不幸的是,它没有帮助。你知道我应该注意哪些限制吗?我检查了触发器的运行时间。
-
@AlanWells 非常感谢。我试过这种方法,但是 Stackdriver 中没有出现日志。最后一个问题日志是在 10 月注册的。你知道日志记录可能有什么问题吗?
-
如果您尚未创建“标准”GCP 项目并将标准 GCP 项目与 Apps 脚本项目相关联,那么您将看不到任何日志,除非您展开“执行”列表中的行.
标签: google-apps-script google-sheets