通过 importJSON 导入额外的 API 数据 + 在公式中使用来自 json 的数据
Importing extra API data via importJSON + usage of data from json in formulas
在 Tanaike 的支持下,我做了一个 google sheet。它功能齐全,但我想更改输入中的某些内容,并且还有一个列导致另一种格式或公式。这就是我被困的地方。首先这是我的代码:
function updateStampInSheet(e) {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheets()[0];
var stamp = new Date();
sheet.getRange(1,1).setValue(stamp);
}
function SAMPLE() {
const url1 = "https://prices.runescape.wiki/api/v1/osrs/mapping";
const url2 = "https://prices.runescape.wiki/api/v1/osrs/latest";
const [res1, res2] = [url1, url2].map(url => JSON.parse(UrlFetchApp.fetch(url).getContentText()));
const head = ['id', 'name', 'examine', 'members', 'lowalch', 'highalch', 'limit', 'high', 'low', 'lowTime', 'highTime','icon'];
const obj1 = res1.reduce((o, e) => (o[e.id] = e, o), {});
const obj2 = Object.entries(res2.data).reduce((o, [k, v]) => (o[k] = v, o), {});
const keys = Object.keys(obj1).map(e => Number(e)).sort((a, b) => a - b);
const timeZone = Session.getScriptTimeZone();
const values = [head, ...keys.map(k => {
const o = Object.assign(obj1[k], obj2[k]);
return head.map(h => o[h] ? (['lowTime', 'highTime'].includes(h) ? Utilities.formatDate(new Date(o[h] * 1000), timeZone, "HH:mm:ss") : o[h]) : "");
})];
return values;
}
json 每秒更新一次,日期戳打印在 sheet 中。更新时还有一个名为“lowTime”和“highTime”的列。是否可以使用以下数据添加 2 个额外的列,并将现在的数据减去“lowTime”或“highTime”?在 sheet 中是可能的,但我无法弄清楚如何在代码中做到这一点。见下图:https://postimg.cc/GTRJ3FP5
id是已知的,根据id我想展示一张图片然后可以在下面找到link:例如id=2:https://static.runelite.net/cache/item/icon/2.png .是否有可能将公式中有价值的 id 添加到额外的列中,例如 =IMAGE("https://static.runelite.net/cache/item/icon/2.png") ?
我已经在下图说明了:https://postimg.cc/nCbczdDz
我试图在数据库中添加第三个 json 但它总是给出一个错误(一个额外的列)。这是以下内容:https://prices.runescape.wiki/api/v1/osrs/volumes。它给出了对应于 id 的卷。
我的最后一个问题,如何在公式(额外列)中使用来自 json 数据库的数据?比如看link里的图片,我试了一些函数,结果不行https://postimg.cc/PCPNBLss.
希望大家已经清楚了,如果不清楚请评论(这是google电子表格,我添加了列:https://docs.google.com/spreadsheets/d/1fFrVLCWyCwDcqSU5-Bpt_C4sHXzLHFA30gk84TaUwOE/edit#gid=0)。
为了实现你的4个请求,下面的示例脚本怎么样?不幸的是,为了实现你的4个请求,自定义函数无法使用。因此,在此示例脚本中,请 运行 使用脚本编辑器编写脚本。
示例脚本:
请将以下脚本复制粘贴到Spreadsheet的脚本编辑器中。并且,请设置 sheet 名称。并且,请 运行 sample2
使用脚本编辑器。这样,脚本就是运行.
function sample2() {
const sheetName = "Sheet1"; // Please set the sheet name.
// Set the value to the cell "A1".
const stamp = new Date();
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(sheetName);
sheet.clearContents();
sheet.getRange("A1").setValue(stamp);
const date = stamp.getTime();
// Retrieve values from URLs.
const url1 = "https://prices.runescape.wiki/api/v1/osrs/mapping";
const url2 = "https://prices.runescape.wiki/api/v1/osrs/latest";
const url3 = "https://prices.runescape.wiki/api/v1/osrs/volumes";
const [res1, res2, res3] = [url1, url2, url3].map(url => JSON.parse(UrlFetchApp.fetch(url).getContentText()));
// Create an array for putting to Spreadsheet.
const head = ['id', 'name', 'examine', 'members', 'lowalch', 'highalch', 'limit', 'high', 'low', 'lowTime', 'highTime'];
const exHead = ["Icon", "Low Time (mins)", "High Time (mins)", "margin", "profit", "tax", "roi", "volume"];
const obj1 = res1.reduce((o, e) => (o[e.id] = e, o), {});
const obj2 = Object.entries(res2.data).reduce((o, [k, v]) => (o[k] = v, o), {});
const obj3 = res3.data;
const keys = Object.keys(obj1).map(e => Number(e)).sort((a, b) => a - b);
const values = [[...head, ...exHead], ...keys.map(k => {
const o = Object.assign(obj1[k], obj2[k]);
const temp = head.map(h => o[h] ? (['lowTime', 'highTime'].includes(h) ? new Date(o[h] * 1000) : o[h]) : "");
const colO = temp[7] - temp[8];
const colQ = temp[7] * 0.01;
const colP = colO - colQ;
const exTemp = [`=IMAGE("https://static.runelite.net/cache/item/icon/${temp[0]}.png")`, temp[9] ? Math.floor((date - temp[9].getTime()) / 60000) : null, temp[10] ? Math.floor((date - temp[10].getTime()) / 60000) : null, colO, colP, colQ, colP && temp[8].toString() ? colP / temp[8] : 0, obj3[k] || 0];
return [...temp, ...exTemp];
})];
sheet.getRange(2, 1, values.length, values[0].length).setValues(values);
// Set number format. These formats are retrieved from your sample Spreadsheet.
sheet.getRange(3, 10, values.length, 2).setNumberFormat("d-m-yyyy");
const formats = ['#,##0 "minutes ago"', '#,##0 "minutes ago"', "0", "0", "0", "0.00%"];
const numberFormats = Array(values.length).fill(formats);
sheet.getRange(3, 13, values.length, formats.length).setNumberFormats(numberFormats);
}
测试:
当这个脚本用脚本编辑器运行时,得到如下结果。通过从您提供的示例 Spreadsheet.
中检索来使用数字格式
注:
- 首先,我认为可以使用 CellImageBuilder 将图像直接放入单元格。但是,在您的情况下,数据很大。在这种情况下,我注意到当使用
IMAGE
公式时,处理成本可以比 CellImageBuilder 降低。所以在这个示例中,我使用了 IMAGE
公式。
参考:
在 Tanaike 的支持下,我做了一个 google sheet。它功能齐全,但我想更改输入中的某些内容,并且还有一个列导致另一种格式或公式。这就是我被困的地方。首先这是我的代码:
function updateStampInSheet(e) {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheets()[0];
var stamp = new Date();
sheet.getRange(1,1).setValue(stamp);
}
function SAMPLE() {
const url1 = "https://prices.runescape.wiki/api/v1/osrs/mapping";
const url2 = "https://prices.runescape.wiki/api/v1/osrs/latest";
const [res1, res2] = [url1, url2].map(url => JSON.parse(UrlFetchApp.fetch(url).getContentText()));
const head = ['id', 'name', 'examine', 'members', 'lowalch', 'highalch', 'limit', 'high', 'low', 'lowTime', 'highTime','icon'];
const obj1 = res1.reduce((o, e) => (o[e.id] = e, o), {});
const obj2 = Object.entries(res2.data).reduce((o, [k, v]) => (o[k] = v, o), {});
const keys = Object.keys(obj1).map(e => Number(e)).sort((a, b) => a - b);
const timeZone = Session.getScriptTimeZone();
const values = [head, ...keys.map(k => {
const o = Object.assign(obj1[k], obj2[k]);
return head.map(h => o[h] ? (['lowTime', 'highTime'].includes(h) ? Utilities.formatDate(new Date(o[h] * 1000), timeZone, "HH:mm:ss") : o[h]) : "");
})];
return values;
}
json 每秒更新一次,日期戳打印在 sheet 中。更新时还有一个名为“lowTime”和“highTime”的列。是否可以使用以下数据添加 2 个额外的列,并将现在的数据减去“lowTime”或“highTime”?在 sheet 中是可能的,但我无法弄清楚如何在代码中做到这一点。见下图:https://postimg.cc/GTRJ3FP5
id是已知的,根据id我想展示一张图片然后可以在下面找到link:例如id=2:https://static.runelite.net/cache/item/icon/2.png .是否有可能将公式中有价值的 id 添加到额外的列中,例如 =IMAGE("https://static.runelite.net/cache/item/icon/2.png") ? 我已经在下图说明了:https://postimg.cc/nCbczdDz
我试图在数据库中添加第三个 json 但它总是给出一个错误(一个额外的列)。这是以下内容:https://prices.runescape.wiki/api/v1/osrs/volumes。它给出了对应于 id 的卷。
我的最后一个问题,如何在公式(额外列)中使用来自 json 数据库的数据?比如看link里的图片,我试了一些函数,结果不行https://postimg.cc/PCPNBLss.
希望大家已经清楚了,如果不清楚请评论(这是google电子表格,我添加了列:https://docs.google.com/spreadsheets/d/1fFrVLCWyCwDcqSU5-Bpt_C4sHXzLHFA30gk84TaUwOE/edit#gid=0)。
为了实现你的4个请求,下面的示例脚本怎么样?不幸的是,为了实现你的4个请求,自定义函数无法使用。因此,在此示例脚本中,请 运行 使用脚本编辑器编写脚本。
示例脚本:
请将以下脚本复制粘贴到Spreadsheet的脚本编辑器中。并且,请设置 sheet 名称。并且,请 运行 sample2
使用脚本编辑器。这样,脚本就是运行.
function sample2() {
const sheetName = "Sheet1"; // Please set the sheet name.
// Set the value to the cell "A1".
const stamp = new Date();
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(sheetName);
sheet.clearContents();
sheet.getRange("A1").setValue(stamp);
const date = stamp.getTime();
// Retrieve values from URLs.
const url1 = "https://prices.runescape.wiki/api/v1/osrs/mapping";
const url2 = "https://prices.runescape.wiki/api/v1/osrs/latest";
const url3 = "https://prices.runescape.wiki/api/v1/osrs/volumes";
const [res1, res2, res3] = [url1, url2, url3].map(url => JSON.parse(UrlFetchApp.fetch(url).getContentText()));
// Create an array for putting to Spreadsheet.
const head = ['id', 'name', 'examine', 'members', 'lowalch', 'highalch', 'limit', 'high', 'low', 'lowTime', 'highTime'];
const exHead = ["Icon", "Low Time (mins)", "High Time (mins)", "margin", "profit", "tax", "roi", "volume"];
const obj1 = res1.reduce((o, e) => (o[e.id] = e, o), {});
const obj2 = Object.entries(res2.data).reduce((o, [k, v]) => (o[k] = v, o), {});
const obj3 = res3.data;
const keys = Object.keys(obj1).map(e => Number(e)).sort((a, b) => a - b);
const values = [[...head, ...exHead], ...keys.map(k => {
const o = Object.assign(obj1[k], obj2[k]);
const temp = head.map(h => o[h] ? (['lowTime', 'highTime'].includes(h) ? new Date(o[h] * 1000) : o[h]) : "");
const colO = temp[7] - temp[8];
const colQ = temp[7] * 0.01;
const colP = colO - colQ;
const exTemp = [`=IMAGE("https://static.runelite.net/cache/item/icon/${temp[0]}.png")`, temp[9] ? Math.floor((date - temp[9].getTime()) / 60000) : null, temp[10] ? Math.floor((date - temp[10].getTime()) / 60000) : null, colO, colP, colQ, colP && temp[8].toString() ? colP / temp[8] : 0, obj3[k] || 0];
return [...temp, ...exTemp];
})];
sheet.getRange(2, 1, values.length, values[0].length).setValues(values);
// Set number format. These formats are retrieved from your sample Spreadsheet.
sheet.getRange(3, 10, values.length, 2).setNumberFormat("d-m-yyyy");
const formats = ['#,##0 "minutes ago"', '#,##0 "minutes ago"', "0", "0", "0", "0.00%"];
const numberFormats = Array(values.length).fill(formats);
sheet.getRange(3, 13, values.length, formats.length).setNumberFormats(numberFormats);
}
测试:
当这个脚本用脚本编辑器运行时,得到如下结果。通过从您提供的示例 Spreadsheet.
中检索来使用数字格式注:
- 首先,我认为可以使用 CellImageBuilder 将图像直接放入单元格。但是,在您的情况下,数据很大。在这种情况下,我注意到当使用
IMAGE
公式时,处理成本可以比 CellImageBuilder 降低。所以在这个示例中,我使用了IMAGE
公式。