【问题标题】:Google Apps Script - Function doesn't work in GaS, but does in JSGoogle Apps 脚本 - 函数在 GaS 中不起作用,但在 JS 中起作用
【发布时间】:2019-09-30 20:41:14
【问题描述】:

我对 Google Apps Script 和 JavaScript 都很陌生,但我对两者之间的异同进行了广泛的阅读。然而,尽管如此,我似乎无法理解为什么我一直在研究的谷歌表格的这个自定义函数将在 Javascript 中正确运行,但不能在 GaS 中运行。

我的基本目标是检查名称列表,计算所有重复项,并显示出现次数最多的五个名称,以及它们出现的频率。下面的代码只考虑了最高的结果。

目前脚本如下:

//Initial Declarations
function watchList(data) {
  var first = {};
  var rcount = 0;
  if (data === undefined){data = SpreadsheetApp.getActiveSheet().getRange("B2:B139")}; //Utilized for testing within the script editor

  for (var i = 0; i < data.length; i++){//loop through the names

    rcount = 0;// Reset duplicate count

    for (var r = 0; r < data.length; r++) {//loop through the entire list again for each increment of the array above

      if (data[i] === data[r]) {//Is this name a duplicate?

        rcount++;//If yes, add 1 to the count

      } 
  } 
    if (first.count == undefined || first.count < rcount) {//Does this value have the most duplicates?

      first.name = data[i];//If so, assign the name and count values to the first object
      first.count = rcount;

  } 
  }
return [first.name, first.count];
}

不过,我返回的是: first name on the list, 1

然后,当我将所有代码打入 javascript 编辑器并将结果记录到控制台时,它运行良好!稍作改动(考虑到没有附表)的javascript代码如下:

function watchList() {
  var range = new Array('Name 1', 'Name 1', 
               'Name 1','Name 2',
               'Name 2', 'Name 2', 
               'Name 2', 'Name 3');
  var first = {};
  var rcount = 0;

  for (var i = 0; i < range.length; i++){
    rcount = 0;
    for (var r = 0; r < range.length; r++) {

      if (range[i] == range[r]) {
        rcount++;   
      }   
  } 
    if (first.count === undefined || first.count < rcount) {

      first.name = range[i];
      first.count = rcount;

  } 
  }
 console.log([first.name, first.count]);
 return first.name;
}

watchList();

有人能告诉我我在这里遗漏了什么失误吗?提前致谢!

编辑 - 这已被链接为“如何比较 JS 数组”问题的副本,但至少在我看来,这是一个不同的问题,因为这是关于两个整个数组,而我的问题正在寻找以不同的速度将各个数组元素相互比较。

【问题讨论】:

  • getRange() 不返回数组
  • 欢迎。 @TheMaster 可能要提到的是,您需要使用 getValues() 从范围中获取数据。所以它可能看起来像这样:data = SpreadsheetApp.getActiveSheet().getRange("B2:B139").getvalues();。 Doc Ref
  • @Tedinoz,谢谢!知道了,很高兴知道,但最终,当它通过初始行(“watchList(data)”)连接到工作表时,这些值被作为一个数组拉出;我尝试通过将返回行设置为简单地“返回数据”来对此进行测试;如果然后在工作表上使用它,则会将整个数组吐出。
  • @TheMaster ,我认为这是一个不同的问题,因为这是比较整个数组,这是比较数组的元素与自身

标签: javascript google-apps-script google-sheets custom-function


【解决方案1】:

问题:

  • getRange() 不返回数组。需要.getValues() 从范围中获取数组值。

  • 假设上面是一个简单的错字,getValues() 也不会返回一维数组。它返回一个二维数组。自定义函数也返回一个二维数组。

  • 说明问题,

function watchList() {
  var range = new Array('Name 1', 'Name 1', 
           'Name 1','Name 2',
           'Name 2', 'Name 2', 
           'Name 2', 'Name 3').map(e=>[e]);// modified to mimick the 2D array returned by `getValues` or in a custom function
  var first = {};
  var rcount = 0;
  
  for (var i = 0; i < range.length; i++){
rcount = 0;
for (var r = 0; r < range.length; r++) {

  if (range[i] == range[r]) {//Two objects are never equal, except when they refer to the same object,i.e., the first time, when both sides refer to the same object in memory. See duplicate question.
    rcount++;   //rcount is 1
  }   
  } 
if (first.count === undefined || first.count < rcount) {//1<1 will never be true; The first name and  first count will stay
  
  first.name = range[i];
  first.count = rcount;
  
  } 
  }
 console.log([first.name, first.count]);
 return first.name;
}

watchList();

解决方案:

  • 在范围内使用.getValues()
  • 比较基元而不是数组对象。

片段:

function watchList() {
var range = [
  [ 'Name 1' ],
  [ 'Name 1' ],
  [ 'Name 1' ],
  [ 'Name 2' ],
  [ 'Name 2' ],
  [ 'Name 2' ],
  [ 'Name 2' ],
  [ 'Name 3' ]
];// simulate getValues() or custom function arguments B1:B8

  var first = {};
  var rcount = 0;
  
  for (var i = 0; i < range.length; i++){
rcount = 0;
for (var r = 0; r < range.length; r++) {

  if (range[i][0] == range[r][0]) {//compare primitives 
    rcount++;   
  }   
  } 
if (first.count === undefined || first.count < rcount) {
  
  first.name = range[i];
  first.count = rcount;
  
  } 
  }
 console.log([first.name, first.count]);
 return first.name;
}

watchList();

参考资料:

【讨论】:

  • 不过,getRange() 实际上并没有在我的代码中使用。该范围是通过电子表格输入拉出的——它就在那里,因此在脚本编辑器中运行它时不会引发错误。尽管如此,我对getValue() 并不了解,所以谢谢
  • @Crunchpuff 如果这解决了您的问题,请考虑接受答案。无论您在哪里拉范围,您都在拉 2D 数组,问题与图示相同。自定义函数还会发送一个二维数组,而不是您在 JavaScript 代码中制作的一维数组。
  • 明白了——并不是不接受它,只是想确保我清楚逻辑。那确实解决了这个问题,我会这样标记它。谢谢!
  • @Crunchpuff 编辑了我的答案以反映自定义函数。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-10
  • 1970-01-01
  • 1970-01-01
  • 2016-06-23
  • 1970-01-01
相关资源
最近更新 更多