【发布时间】:2018-06-24 14:57:25
【问题描述】:
我目前正在使用 ImportJSON 通过在 Sheet DATA 的 Google 电子表格单元格中调用 ImportJSON 函数来导入带有数据 Keenio 提取查询 API URL 的 Sendgrid 电子邮件。
=ImportJSON("https://api.keen.io/3.0/projects/"& PROJECT_KEY & "/queries/extraction?api_key=" & API_KEY & "&event_collection=" & EVT_COL & "&timezone=" & TIMEZONE & "&latest=" & LATEST & "&property_names..........", PTDATA!$AB$1)
在 Sheet PTDATA 中,在最后一列单元格中,我设置了一个随机数,以便 ImportJSON 重新计算。该函数在电子表格打开事件上运行。我还添加了一个自定义菜单来调用 ReCalcCell 自定义函数。
function onOpen() {
var ui = SpreadsheetApp.getUi();
// Or DocumentApp or FormApp.
ui.createMenu('IMPORT DATA')
.addItem('KEENIO DATA', 'ReCalcCell')
.addToUi();
}
function ReCalcCell(){
var min = Math.ceil(0);
var max = Math.floor(9999);
var randomNum = Math.floor(Math.random() * (max - min + 1)) + min
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sh = ss.getSheetByName("PTDATA");
sh.getRange("$AB$1").setValue(randomNum);
}
PTDATA 表 具有我想从 DATA 表 中提取数据的特定列标题名称。在这些列的右侧,我有其他计算列适用于这些特定列。
由于 DATA sheet 中的列总是以随机/打乱的顺序出现,我不得不编写一个小的自定义函数 GCL 接受标题名称并返回其数据表中的数据范围地址作为字符串。
function GCL(header,dummy) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("DATA");
var headings = sheet.getRange(1, 1, 1, sheet.getLastColumn()); // get the range representing the whole sheet
var width = headings.getWidth();
var lrow = sheet.getLastRow();
// search every cell in row 1 from A1 till the last column
for (var i = 1; i <= width; i++) {
var data = headings.getCell(1,i).getValue();
if (data == header) {
return ((sheet.getSheetName() + "!" + columnToLetter(i)+"2:" + columnToLetter(i) + lrow).toString()); // return the column range if we find it
break; // exit when found
}
}
return(-1); // return -1 if it doesn't exist
}
function columnToLetter(column)
{
var temp, letter = '';
while (column > 0)
{
temp = (column - 1) % 26;
letter = String.fromCharCode(temp + 65) + letter;
column = (column - temp - 1) / 26;
}
return letter;
}
然后我在每个特定列中使用自定义函数 GCL 来获取它的数据范围。填充数据后,PDATA 表用于创建不同的数据透视表以用于报告目的。
=ARRAYFORMULA(间接(GCL(A1,$AB$1)))
我面临的问题是,虽然 ImportJSON 数据填充了 数据表:
- 列每次都显示为随机排列,因此随着引用消失,我的计算列无法计算。这使得枢轴无用!为了解决这个问题,我必须创建 PDATA 表 以使用 自定义函数 GCL 拉入特定列。
- 自定义函数 GCL 并不总是刷新,大部分时间显示 #Ref 错误。
顺便说一句,我来自 Keenio 的 JSON 输出如下所示:
{
"result":
[
{
"sg_event_id": "92-OndRfTs6fZjNdHWzLBw",
"timestamp": 1529618395,
"url": "https://noname.com?utm_campaign=website&utm_source=sendgrid.com&utm_medium=email",
"ip": "192.168.1.1",
"event": "click",
"keen": {
"timestamp": "2018-06-21T21:59:55.000Z",
"created_at": "2018-06-21T22:00:28.532Z",
"id": "555c1f7c5asdf7000167d87b"
},
"url_offset": {
"index": 38,
"type": "text"
},
"sg_message_id": "F5mwV1rESdyKFA_2bn1IEQ.filter0042p3las1-15933-5B2A68E8-36.0",
"useragent": "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)",
"email": "no.name@noname.com"
}, {
"sg_event_id": "bjMlfsSfRyuXEVy8LndsYA",
"timestamp": 1529618349,
"url": "https://noname.com?utm_campaign=website&utm_source=sendgrid.com&utm_medium=email",
"ip": "192.168.1.1",
"event": "click",
"keen": {
"timestamp": "2018-06-21T21:59:09.000Z",
"created_at": "2018-06-21T21:59:39.491Z",
"id": "555c1f7c5asdf7000167d87b"
},
"url_offset": {
"index": 36,
"type": "text"
},
"sg_message_id": "F5mwV1rESdyKFA_2bn1IEQ.filter0042p3las1-15933-5B2A68E8-36.0",
"useragent": "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)",
"email": "no.name@noname.com"
}, {
"sg_event_id": "fru_s2s1RtueuqBMNoIoTg",
"timestamp": 1529618255,
"url": "https://noname.com?utm_campaign=website&utm_source=sendgrid.com&utm_medium=email",
"ip": "192.168.1.1",
"event": "click",
"keen": {
"timestamp": "2018-06-21T21:57:35.000Z",
"created_at": "2018-06-21T21:58:20.374Z",
"id": "555c1f7c5asdf7000167d87b"
},
"url_offset": {
"index": 29,
"type": "text"
},
"sg_message_id": "F5mwV1rESdyKFA_2bn1IEQ.filter0042p3las1-15933-5B2A68E8-36.0",
"useragent": "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)",
"email": "no.name@noname.com"
}
]
}
我的问题是:
- 有没有一种方法可以在不使用 ImportJSON 的情况下解析 JSON 结果,而 ImportJSON 必须作为自定义函数输入到同样依赖于重新计算的单元格中? ImportJSON 有时无法正常工作。
- 如何重构或优化此代码,以便始终将数据返回到 PDATA 表列?
- 有没有更好的方法来完成我想要的,而无需使用 PDATA 表中的 GCL 或 DATA 表中的 ImportJSON 等自定义函数?
【问题讨论】:
-
如果我误解了您的问题,我很抱歉。您的问题中的 Q1 和 Q3 似乎是相同的。如果有区别,能告诉我吗?您可以使用
JSON.parse()解析 JSON 对象。关于it can always return data to PDATA sheet columns,“总是”是什么意思?您想使用时间驱动的触发器更新数据吗?你能提供一个示例电子表格吗?我认为这将帮助用户思考您的解决方案。当然,请删除您的私人信息。 -
嗨@Tanaike,Keenio URL 每隔几个小时就会自动刷新一次。有时,由于此刷新,ImportJSON 不会导入数据,从而导致错误。我不想要一个时间驱动的触发器,而是一个菜单选择,可以随时提取数据。让我为返回的 Keenio 数据创建一个样本表并与您分享链接。
-
@Tanaike 我已经用两张显示数据外观的图片更新了我的帖子。这会有帮助吗?如果没有,我会尝试创建一个示例电子表格并立即分享。告诉我。
-
感谢您回复和更新您的问题。从添加的图像中,我认为可以使用 Google Apps 脚本从 API 中检索 JSON 对象,并且可以从菜单中运行该脚本。关于列标题,我无法从图像中看到所有这些。因此,如果您提供一个示例电子表格,我认为我可以将您的脚本修改为使用类 UrlFetchApp 的版本。当然,请删除您在电子表格中的个人信息。
-
当然@Tanaike。我分享了包含所有相关列的 JSON。我仍然会创建一个电子表格并现在与您分享。
标签: json google-apps-script google-sheets sendgrid keen-io