【问题标题】:Google sheets scripts editor and correctly parsing JSON谷歌表格脚本编辑器和正确解析 JSON
【发布时间】:2018-06-01 13:54:20
【问题描述】:

我正在尝试解析来自 Binance API 的 JSON 文件,因此我可以在 google spreadsheets 上创建一个 candlestick chart

但我似乎无法弄清楚如何实现这一点...... 这是我迄今为止尝试过的:

function myJSON(){
  url = "https://api.kraken.com/0/public/OHLC?pair=XXBTZEUR&since=0&interval=1"
  var ss = SpreadsheetApp.getActiveSpreadsheet(),
  coinsheet = ss.getSheetByName('Sheet1')
  var response = UrlFetchApp.fetch(url, {'muteHttpExceptions': true});
  var json = response.getContentText();
  var rawdata = JSON.parse(json);
  var data = JSON.stringify(rawdata.result.XXBTZEUR)
  data = JSON.parse(data)
  for (var i = 0; i < data.length; i++) {
    for (var j = 0; j < data[i].length; j++) {
       var mdata = new Array();var obj = {};
       var utcSeconds = data[i][0];
       var mdate = new Date(0); // The 0 there is the key, which sets the date to the epoch
       mdate.setUTCSeconds(utcSeconds);
       open = parseFloat(data[i][1])
       high = parseFloat(data[i][2])
       low = parseFloat(data[i][3])
       close = parseFloat(data[i][4])
       obj['date'] = mdate
       obj['open'] = open
       obj['high'] = high
       obj['low'] = low
       obj['close'] = close
       mdata.push(obj);
       Logger.log(mdata);
       coinsheet.appendRow(mdata);
    }
  }
}

在运行Logger gives this output 函数时会产生以下错误:

此操作会将工作簿中的单元格数量增加到超过 2000000 个单元格的限制

这怎么可能?只有 720 条记录,为什么 mdata 变量不会在每个循环中被覆盖?这不应该自动创建一个包含列名和数据的表吗?完全迷失在这里。任何帮助都将不胜感激。

【问题讨论】:

  • 如果你登录coinsheet.getLastRow(),你会得到什么?
  • 嗨@LioraHaydont 感谢您提出这个问题。它产生“0.0”
  • 试试coinsheet.appendRow(mdata[j]);
  • 不。同样的错误。而mdata[j] 没有用。尝试使用data[j]
  • 带有变量 j 的 for 循环正在为结果中的每个项目执行 8 次代码。由于您不会在循环中以外的任何地方使用变量j,因此您似乎可以删除此循环。这很可能会解决单元格限制问题。

标签: javascript arrays json google-apps-script google-sheets


【解决方案1】:

这是一个更新的实现(在工作表上测试,它成功地追加了行):

function appendApiData() {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var coinsheet = ss.getSheetByName('Sheet1');
  var url = 'https://api.kraken.com/0/public/OHLC?pair=XXBTZEUR&since=0&interval=1';
  var response = UrlFetchApp.fetch(url, {'muteHttpExceptions': true});
  var parsedResponse = JSON.parse(response.getContentText());
  var data = parsedResponse.result['XXBTZEUR'];
  for (var i = 0; i < data.length; i++) {
    var utcSeconds = data[i][0];
    var mdate = new Date(0); // The 0 there is the key, which sets the date to the epoch
    mdate.setUTCSeconds(utcSeconds);
    var open = parseFloat(data[i][1])
    var high = parseFloat(data[i][2])
    var low = parseFloat(data[i][3])
    var close = parseFloat(data[i][4])
    var row = [mdate, open, high, low, close];
    Logger.log(row)
    coinsheet.appendRow(row);
  }
}

以下是日志的摘录:

[18-06-01 11:44:41:028 PDT] [Thu May 31 23:45:00 GMT-07:00 2018, 6452.5, 6452.5, 6447.6, 6448.2]
[18-06-01 11:44:41:146 PDT] [Thu May 31 23:46:00 GMT-07:00 2018, 6450.5, 6450.9, 6450.5, 6450.6]
[18-06-01 11:44:41:263 PDT] [Thu May 31 23:47:00 GMT-07:00 2018, 6450.6, 6450.6, 6447.1, 6449.7]
[18-06-01 11:44:41:364 PDT] [Thu May 31 23:48:00 GMT-07:00 2018, 6449.5, 6449.7, 6447.2, 6447.2]
[18-06-01 11:44:41:446 PDT] [Thu May 31 23:49:00 GMT-07:00 2018, 6447.2, 6450.5, 6447.2, 6450.5]

关于我所做更改的一些说明:

  • 如果您不打算使用中间值,您可以将方法调用串在一起(即JSON.parse(response.getContentText())
  • 避免JSON.stringify() 后跟JSON.parse(),你是在不必要地编码/解码数据
  • 删除内部循环,您通过索引显式引用数组项,因此不需要它。就目前而言,内部循环导致您处理每一行 [行项目数]
  • 避免使用new Array(),只需使用数组字面量(即[]
  • 在构造行时,您需要创建行值数组,而不是包含单个对象的数组。见Sheet.appendRow() example in the documentation

【讨论】:

  • 非常感谢您。 @LioraHaydont 第一次是对的。只有 getLastRow() 不会返回所有可用行。我必须使用getMaxRows() 来获取实际上超过数量限制的所有行,然后使用deleteRows() 添加以将它们全部删除(除了1)。像这样var start = 1; var end = coinsheet.getMaxRows() -1; if (end != "0.0"){coinsheet.deleteRows(start, end)}。无论如何,由于chuckx 的回答,我的代码有一系列不好的做法/误解,我现在更清楚了。谢谢你们。干杯
  • chuckx 试图投票,但我没有必要的声誉来改变这一点。再次感谢您。
  • 您可以mark this answer as accepted。那将不胜感激。
猜你喜欢
  • 1970-01-01
  • 2022-01-23
  • 2023-03-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-18
  • 2017-04-16
相关资源
最近更新 更多