【问题标题】:Global variable defined in function appears not defined?函数中定义的全局变量似乎未定义?
【发布时间】:2014-12-08 17:51:22
【问题描述】:

我正在为 Google 电子表格编写一个脚本,我想让我的标题索引在整个脚本中全局可用。

According to the theory,我应该可以在函数中定义全局变量。

function testFunc() {
testVar = 1;       // `testVar` is a Global variable now
}

在我的代码中,它或多或少是这样的:

function getHeaders() {
  var sheet = SpreadsheetApp.getActiveSheet();
  var data = sheet.getDataRange().getValues();
  var headers = data[0]

  headerIdIndex = headers.indexOf("ID")
  headerNameIndex = headers.indexOf("First-Last")
}

但是,稍后在我的代码中,当我调用变量 headerNameIndex 时,它显示为未定义:

function tellMeNames() {
  var sheet = SpreadsheetApp.getActiveSheet();
  var data = sheet.getDataRange().getValues();
  for (var i = 1; i < data.length; i++) {
    Logger.log("Name: " + data[i][headerNameIndex])
  }
}

那我做错了什么?谢谢。

【问题讨论】:

  • 你确定getHeaders() 是在tellMeNames() 之前被调用的吗?如果不是,则变量设置不正确。
  • 是的,因为我从 Google 脚本编辑器的菜单中运行该函数,首先运行 getHeaders(),然后运行 ​​tellMeNames()。最后,我希望getHeaders() 被onOpen() 调用,并且在整个脚本中都可以使用全局变量。
  • 请参阅this question 和this question 了解可能的解决方案。关键问题似乎是每次您从 Google 脚本编辑器的菜单中调用一个函数时,都会创建一个新的全局上下文。因此,您不能从第二个上下文引用第一个上下文中的全局集。

标签: google-apps-script google-sheets


【解决方案1】:

好吧,我正在阅读 some relevant SO 在 Google Apps 脚本中定义全局变量的帖子,从 this answer 看来,您无法更新处理函数中的全局变量,即 GAS 中的全局变量是静态的。

现在,这取决于您的具体用例,但我假设既然您已经定义了一个函数 getHeaders(),您会想要多次调用它。但是,如果情况并非如此,那么您可以简单地将所有函数范围之外的这些变量声明和初始化为全局变量,并在任何其他函数中读取它们。

所以你可能想在你的情况下尝试这样的事情(没有测试过以下代码):

 var sheet = SpreadsheetApp.getActiveSheet();
 var data = sheet.getDataRange().getValues();
 var headers = data[0]

 headerIdIndex = headers.indexOf("ID")
 headerNameIndex = headers.indexOf("First-Last")

 ....

 function tellMeNames() {
  var sheet = SpreadsheetApp.getActiveSheet();
  var data = sheet.getDataRange().getValues();
 for (var i = 1; i < data.length; i++) {
  Logger.log("Name: " + data[i][headerNameIndex])
 }
}

如果你想在处理函数中存储和更新全局变量,你可能想试试Script-DB。希望这能让您朝着正确的方向开始。

【讨论】:

  • @Benjamin,请接受一个合适的答案,以便其他有类似问题的人也可以从中受益。谢谢
  • “您不能在处理程序中更新全局变量”是不正确的。这不是它失败的原因。您可以从任何地方更新它们。只是每次到达脚本的入口点时都会重置整个上下文。因此,稍后来自另一个入口点的调用将看不到任何尚未在该点创建的全局变量。将 cacheservice 与 propertiesService 一起使用。
【解决方案2】:

我找到了一个我相信的解决方案,但我不确定这是不是“正确”的方法。

我只是在脚本中定义了上面的全局变量:

headerNameIndex = SpreadsheetApp.getActiveSheet().getDataRange().getValues()[0].indexOf("First-Last")

这似乎有效。

我错误地认为它只有在 onOpen() 函数中定义时才有效。

【讨论】:

  • 使用PropertiesService 来存储值而不是全局变量可能是一种“正确”的方式来做到这一点。或者正如 Vivek 所说,使用 Script-DB。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-07
  • 1970-01-01
  • 1970-01-01
  • 2022-11-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多