【问题标题】:Trying to understand setFormula vs setValue behaviour [duplicate]试图了解 setFormula 与 setValue 行为[重复]
【发布时间】:2020-06-07 19:16:18
【问题描述】:

这只是我在这里的第三篇文章。 我从来没有写过代码,我没有任何技能,我只是想学习一些概念,这样我就可以“修复”一个 Google Apps 脚本。

问题:我想了解setFormulasetValue 的行为,以及为什么单元格值会更新。

我正在使用UrlFetchApp.fetch 从 URL 中获取一些值并在单元格中设置该值。

我正在使用 setFormulasetValue 写入值。

这些功能是从工作表中的菜单手动触发的(未在下面的脚本中编码)

所以我从“Url”中获取数据并将它们写在单元格上。

函数的首次运行:

如果 URL 中的数据是:“A”,那么:

--> setFormula 写“A” --> setValue 写“A”

函数的第二次运行:

URL 中的数据已从“A”变为“B”,则:

--> setFormula 没有覆盖单元格,仍然是“A” --> setValue用“B”覆盖“A”

我知道脚本正在按预期运行,完全没有问题。我只是想了解为什么 setFormula 从上一次运行中“知道”单元格已经被写入,因此它不会更新值。

这是解释问题的简短脚本。 网址值在工作表上设置,如您在这张图片中看到的那样,它是https://engaliao.com/html.htm


function onOpen() {
  var sheet = SpreadsheetApp.getActiveSpreadsheet();
  var entries = [
    {name: "Formula", functionName: "runFormula"},
    {name: "SetValue", functionName: "runSet"}

  ];
  sheet.addMenu("Menu", entries);
}

function runFormula() {
  var activeSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(
    'hoja'
  );
  activeSheet.getRange(2, 2).setFormula('=RunCheck' + '(A2)');
}

function runSet() {
  var activeSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(
    'hoja'
  );
  var workingCell = activeSheet.getRange(3, 1).getValue();
  activeSheet.getRange(3, 2, 1, 1).setValue(RunCheck(workingCell));
}

function RunCheck(Url) {
  var array = [];
  var response = UrlFetchApp.fetch(Url);
  if (response.getResponseCode() == 200) {
    var content = JSON.parse(response.getContentText());
    var score = content['loadingExperience']['id'];
  }
  array.push([score]);
  return array;
}

不需要外部提取来解释我的问题的新简化脚本:

function onOpen() {
  var sheet = SpreadsheetApp.getActiveSpreadsheet();
  var entries = [
    {name: "Formula", functionName: "runFormula"},
    {name: "SetValue", functionName: "runSet"}

  ];
  sheet.addMenu("Menu", entries);
}



function runFormula() {
var activeSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("hoja");


    activeSheet.getRange(2, 2).setFormula("=RunCheck" + "(A2)");

     }   


function runSet() {
var activeSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("hoja");

          var workingCell = activeSheet.getRange(3, 1).getValue();

          activeSheet.getRange(3,2,1,1).setValue(RunCheck(workingCell));


}



function RunCheck(text) {

    var array = [];

   var number = (Math.random())



    array.push([text + " " + number]);

    return array;
}

【问题讨论】:

  • 如果你添加“SpreadsheetApp.flush();”你会得到同样的行为吗?到 runSet() 结束?我的猜测是公式已更新,但尚未调用该函数,因此没有更新。顺便说一句,在不知道您在“hoja”表的单元格中放入什么的情况下,很难测试代码。
  • 已编辑帖子以显示实际工作表。 SpreadsheetApp.flush(); 没有对行为做出任何改变。这是一个用于解释我的问题的示例脚本。真正的事情是Url 目标 html 文件并不总是包含相同的信息,它在变化,而且我有一个时间触发器来每小时运行这些函数。我想理解为什么setFormula 不去runCheck 更新值,并且单元格值从第一次触发器运行中保留,但setValues 确实更新了值。为了测试代码,我应该在你的第一次和第二次运行之间更新文件
  • 您真的应该将 setValue() 用于单个单元格。 setValues() 旨在编写一个二维数组。
  • 谢谢@Cooper,你是对的,那是因为脚本来自一个更大的脚本,我设置了超过 1 个值。无论如何,帖子已被编辑。
  • 是的,当然,setValue 和 setFormula 都可以正常工作。那不是我的问题。我的问题是为什么 setFormula 在 Url 数据更改后的第二次运行中不更新该值,但 setValue 确实更新了它。我知道这不是“问题”或错误代码,我只是想了解原因。

标签: google-apps-script google-sheets


【解决方案1】:

您的声明不可重复

我使用这些函数来测试您是否声明 setForumula 在检测到单元格中的某些内容时不会更改公式,我发现它会更新公式,无论它是否已被 setFormula 或 setValue 更改,实际上两者都会更新公式。

function setMyValue() {
  const ss=SpreadsheetApp.getActive();
  const sh=ss.getSheetByName('Sheet40');
  const v=sh.getActiveCell().getFormula();
  sh.getRange('A1').setValue(v);
  ss.toast(sh.getRange('A1').getFormula());
}

function setMyFormula() {
  const ss=SpreadsheetApp.getActive();
  const sh=ss.getSheetByName('Sheet40');
  const v=sh.getActiveCell().getFormula();
  sh.getRange('A1').setFormula(v);
  ss.toast(sh.getRange('A1').getFormula());
}

那么,如何分享您的菜单驱动功能。也许这就是问题所在。

动画:

【讨论】:

  • 感谢@cooper 提供的示例,这很有帮助。我认为我的情况与您的情况不同。我的公式是自定义公式,其值取决于运行脚本。对于第一次运行,=runcheck(B2) 运行自定义公式并检索外部数据。但在第二次运行中, =runcheck(B2) 保持不变,无需再次运行自定义公式。我想我发现它与脚本无关,而是继承到 Google Sheets 应用程序。将公式设置为单元格时,如果设置的参数相同,则不会更新值。请参阅i.imgur.com/yOMcLKj.gif.BTW,主帖子使用我的自定义菜单代码编辑。
  • 用新的、不言自明的脚本编辑了主帖,说明我对 setFormula 是否更新的意思。
  • 库珀专门为展示行为而拼凑了一个侧边栏这一事实,没有其他人印象深刻吗? +1 为清楚起见加倍努力!另外,出于自私的考虑,如果您可以分享侧边栏 Cooper 的代码,那将会很有趣(尽管与手头的问题没有直接关系)。
  • 其实我并没有把那个侧边栏放在一起。我使用相同的电子表格来处理 SO 问题,它有很多我觉得很有帮助的特殊功能,其中之一是我可以从下拉列表中选择文件 ag1...ag3 中所有函数的名称并将它们分派到 run(1...n) 函数中,以便我可以单击一个按钮来快速测试新的 SO 答案函数。是的,我还考虑了 gif 视频的术语,因为我倾向于尽量减少答案中的文本数量。如果我认为我可以摆脱它,我的最少文字是Try this:
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多