【问题标题】:Trigger API call when cell is edited编辑单元格时触发 API 调用
【发布时间】:2018-08-10 16:56:28
【问题描述】:

使用 Google 表格,其中每一行都包含一个 ID 和一个 picklist 值。示例:Google Sheet

我要做的是在有人编辑 picklist 单元格时运行自定义函数。该函数接受两个参数,来自同一行的 ID 和选项列表单元格的值,然后执行 HTTP POST 请求以更新我们 CRM 中的记录。

//When STAGE cell on Google Sheet is updated, run this function:

function updateProjectStage(status, id) {
  var baseURL = 'https://crm.zoho.com/crm/private/json/Potentials/updateRecords?authtoken=xxx&scope=crmapi&id=', // see docs https://www.zoho.com/crm/help/api/updaterecords.html
      recordID = id, // building id from A column
      stage = '<Potentials><row no="1"><FL val="Stage">' + status + '</FL></row></Potentials>'; // status from B column

  var postURL = baseURL + recordID + '&xmlData=' + stage;
  Logger.log(postURL);

  var response = UrlFetchApp.fetch(postURL); // update record in crm
  var sanitizedResponse = JSON.parse(response.getContentText()); // get confirmation/failure
  Logger.log(sanitizedResponse);
}

我不知道如何为这种选择列表类型的单元格运行该函数 - 我不能像以前那样在单元格中输入=updateProjectStage(status, id),因为它会出错。

例如:Error Message

这可能吗?

【问题讨论】:

  • 您的 Go 代码似乎没有任何问题,只是如何从 Google 表格进行 API 调用,所以这可能更适合 Super User
  • 嗯,这必须用 golang 编写,所以我不知道你为什么这么说 - 这正是我遇到的问题。我什至不知道该写什么;当然必须有一些辅助函数来处理事件 - 但它们可以在 Google 表格自定义函数脚本中使用吗?
  • Google 表格脚本在浏览器中运行,Go 没有。我以为您在某种服务中运行此 Go 代码,也许我不太理解您的问题。

标签: google-apps-script google-sheets google-sheets-api


【解决方案1】:

您的答案在于在用户修改工作表上的任何单元格时捕获编辑事件。当然,用户可以修改任何单元格。您的工作是确定该单元格是否在您关心的范围内。可以使用此函数捕获onEdit 事件:

function onEdit(eventObj) {
  //--- check if the edited cell is in range, then call your function
  //    with the appropriate parameters
}

传递给事件的对象描述了被编辑的单元格。所以我们设置了一个“检查范围”,然后将该范围与编辑过的单元格进行比较。函数如下:

function isInRange(checkRange, targetCell) {
  //--- check the target cell's row and column against the given
  //    checkrange area and return True if the target cell is
  //    inside that range
  var targetRow = targetCell.getRow();
  if (targetRow < checkRange.getRow() || targetRow > checkRange.getLastRow()) return false;

  var targetColumn = targetCell.getColumn();
  if (targetColumn < checkRange.getColumn() || targetColumn > checkRange.getLastColumn()) return false;

  //--- the target cell is in the range!
  return true;
}

编辑事件的完整事件函数是

function onEdit(eventObj) {
  //--- you could set up a dynamic named range for this area to make it easier
  var checkRange = SpreadsheetApp.getActiveSheet().getRange("B2:B10");  
  if (isInRange(checkRange, eventObj.range)) {
    //--- the ID cell is on the same row, one cell to the left
    var idCell = eventObj.range.offset(0,-1);
    //--- the status cell is the one that was edited
    var statusCell = eventObj.range;
    updateProjectStage(statusCell, idCell);
  }
}

这就是全部内容:

function isInRange(checkRange, targetCell) {
  Logger.log('checking isInRange');

  //--- check the target cell's row and column against the given
  //    checkrange area and return True if the target cell is
  //    inside that range
  var targetRow = targetCell.getRow();
  if (targetRow < checkRange.getRow() || targetRow > checkRange.getLastRow()) return false;
  Logger.log('not outside the rows');

  var targetColumn = targetCell.getColumn();
  if (targetColumn < checkRange.getColumn() || targetColumn > checkRange.getLastColumn()) return false;
  Logger.log('not outside the columns');

  //--- the target cell is in the range!
  return true;
}

function onEdit(eventObj) {
  //--- you could set up a dynamic named range for this area to make it easier
  var checkRange = SpreadsheetApp.getActiveSheet().getRange("B2:B10");  
  if (isInRange(checkRange, eventObj.range)) {
    Logger.log('cell is in range');
    //--- the ID cell is on the same row, one cell to the left
    var idCell = eventObj.range.offset(0,-1);
    //--- the status cell is the one that was edited
    var statusCell = eventObj.range;
    updateProjectStage(statusCell, idCell);
  }  else {
    Logger.log('must be outside the range');
  }
}

function updateProjectStage(status, id) {
  Logger.log('we are updating');
}

【讨论】:

  • 嗯,我主要是按照你的逻辑让它工作的,但最后一个函数 updateProjectStage 并没有触发 HTTP Post 请求。我收到某种 Invalid Ticket Id 错误。如果我记录 sanitizedResponse 它会完美地打印到日志中 - 我可以手动将其输入到新选项卡中,它会更新 CRM 记录。但它不会触发该网址。嗯,会是什么……?!
  • {"response":{"error":{"code":"4834","message":"Invalid Ticket Id"},"uri":"/crm/private/json/Potentials/updateRecords"}}
  • 听起来这是一个单独的问题。我发布的示例应该让您使用 updateProjectStage 函数,以便发出您的 HTTP Post 请求。您可以记录statusid 参数和/或整个postURL 以验证请求格式和信息。但这听起来更像是您的数据访问您在 crm 服务器上的私人帐户的问题,鉴于上述信息,我无法帮助您。
  • 是的,你是对的。我已经使用您的解决方案完成了所有工作,但是您将这两个变量混淆了。 statusCell 实际上是 idCelll,反之亦然。如果您可以编辑这些,我会继续将此问题标记为已解决。 thumbs_up
  • 答案已被编辑和更新。很抱歉混淆了
猜你喜欢
  • 2012-12-20
  • 1970-01-01
  • 1970-01-01
  • 2020-02-20
  • 1970-01-01
  • 2017-07-16
  • 1970-01-01
  • 2011-05-28
  • 1970-01-01
相关资源
最近更新 更多