【问题标题】:Issues reading cells using map() in a range in Google Sheets在 Google 表格的某个范围内使用 map() 读取单元格时出现问题
【发布时间】:2018-03-06 19:03:57
【问题描述】:

我有一个函数在为每个单元分配它时可以完美运行,但是当我尝试使用 map() 函数创建一个数组时,单元值没有被正确读取。有人可以帮忙吗?

我已尝试阅读此内容,这可能与 Google 表格 map() 函数无法处理某些场景有关,因为所有计算都是在服务器端完成的?不确定。

无论如何,我正在尝试从一列中读取日期,并查看另一列中是否有折扣,并根据日期和折扣令牌“DSC”,返回百分比折扣值:25% 或 30如果在 2 个日期之间,则为 %。

第三列中没有 30% 值的图片

以下是分配给范围的工作函数(分配给每个单元格)和非工作 map() 函数的代码,然后是 Google 表格链接:

// ==================================== Using .map 
/**
@customfunction
*/
function Disc_Perc_Map (input1, input2){ // input1 is product ID column, input2 is Date
  var Date_1_a = Date.parse(String("1/3/2017")) ;// put start date of discount change here
  var Date_1_b = Date.parse(String("1/4/2017")) ;// put end date of discount change here
  var Disc_Def = .25;
  var Disc_1 = .30;
  if (input1.map){ // Checks if array 
    return input1.map(Disc_Perc_Map);   // added along with added brace at end
  } else { 

    // Main part of code 
    if (String(input1).indexOf(",") >-1) { // if there are commas
      Cell_Array = input1.split(",");
      Cell_Len = input1.split(',').length;
      var Date_Num = Date.parse(String(input2));
      if (Date_Num >= Date_1_a && Date_Num <= Date_1_b){
        return Disc_1;
      } else {
        return Disc_Def;
      }
    } else {                          // if there are NO commas
      return "";
      //Cell_Len = 1;
    }
  }
}


// ==================================== without using .map
/**
@customfunction
*/
function Disc_Perc_No_Map(input1, input2) { // input1 is product ID column, input2 is Date
  var Date_1_a = Date.parse(String("1/3/2017")) ;// put start date of discount change here
  var Date_1_b = Date.parse(String("1/4/2017")) ;// put end date of discount change here
  var Disc_Def = .25;
  var Disc_1 = .30;

  // Main part of code 
  if (String(input1).indexOf(",") > -1) { // if there are commas
    Cell_Array = input1.split(",");
    Cell_Len = input1.split(',').length;
    var Date_Num = Date.parse(String(input2));
    if (Date_Num >= Date_1_a && Date_Num <= Date_1_b){
      return Disc_1;
    } else {
      return Disc_Def;
    }
  } else {   // if there are NO commas
    return "";
    //Cell_Len = 1;
  }         
}

Link to example Google Sheets:

任何帮助都非常感谢。

【问题讨论】:

  • Google Apps 脚本不是 JavaScript,尽管它与大约 2007 年或 2008 年的 JavaScript 非常、非常、非常相似。您确定数组具有 map 函数(在 2009 年添加)吗?
  • 显然,在您自己的代码中,您可以使用任何您喜欢的缩进策略,但是当要求其他人花时间帮助您时,请花时间以合理、一致的方式格式化和缩进代码,可读的方式。
  • 谢谢 TJ。我对这一切都很陌生。对不起格式。不完全确定我在格式方面做错了什么。如果允许,我会将标签更新为 Google Apps 脚本。
  • 关于您确定数组是否具有映射功能的问题......不知道如何回答。我可以让 Map 函数在一个范围内作为数组工作。但是当尝试从地图函数中的另一个单元格 读取 时,我遇到了问题。再说一次,我是新手,所以......我可能会遗漏一些明显的东西。
  • 当您在 Disc_Perc_Map 的第一行设置断点(通过单击脚本编辑器中的行号),在调试模式下执行脚本(通过使用错误而不是播放符号)时会发生什么,然后使用“Step Into”逐行推进。这应该可以让您看到传递到哪里的内容,以及数组的外观等。执行这种调试任务对于确定脚本或程序如何出错是非常宝贵的。

标签: arrays function google-apps-script google-sheets


【解决方案1】:

我认为问题的原因如下。

  • Disc_Perc_Map()做回调时,input2成为input1.map()的索引。
    • 所以从自定义函数输入的input2的值从运行脚本中删除。

为了避免这个问题,这次修改怎么样?

修改点:

  • 备份input2并在回调中使用。
  • 为了使用备份的input2,添加一个计数器。
    • 使用计数器检索日期值。

修改后的脚本:

var cnt = -1; // Added
var input2bk; // Added

function Disc_Perc_Map (input1, input2){ // input1 is product ID column, input2 is Date

  if (isNaN(input2)) input2bk = input2; // Added

  var Date_1_a = Date.parse(String("1/3/2017")) ;// put start date of discount change here
  var Date_1_b = Date.parse(String("1/4/2017")) ;// put end date of discount change here
  var Disc_Def = .25;
  var Disc_1 = .30;

  if (input1.map){ // Checks if array 
    return input1.map(Disc_Perc_Map);   // added along with added brace at end
  } else {

    cnt += 1; // Added

    // Main part of code 
    if (String(input1).indexOf(",") > -1) { // if there are commas
      Cell_Array = input1.split(",");
      Cell_Len = input1.split(',').length;
      var Date_Num = Date.parse(String(input2bk[cnt][0])); // Modified
      if (Date_Num >= Date_1_a && Date_Num <= Date_1_b){
        return Disc_1;
      } else {
        return Disc_Def;
      }
    } else {   // if there are NO commas
      return "";
      //Cell_Len = 1;
    }
  }
}

另一种模式:

作为另一种模式,这个修改怎么样?这也是与上面相同的结果。

function Disc_Perc_Map (input1, input2) { // input1 is product ID column, input2 is Date
  var Date_1_a = Date.parse(String("1/3/2017")) ;// put start date of discount change here
  var Date_1_b = Date.parse(String("1/4/2017")) ;// put end date of discount change here
  var Disc_Def = .25;
  var Disc_1 = .30;
  return input1.map(function(e, i) {
    // Main part of code 
    if (String(e[0]).indexOf(",") > -1) { // if there are commas
      Cell_Array = e[0].split(",");
      Cell_Len = e[0].split(',').length;
      var Date_Num = Date.parse(String(input2[i][0])); // Modified
      if (Date_Num >= Date_1_a && Date_Num <= Date_1_b) {
        return [Disc_1];
      } else {
        return [Disc_Def];
      }
    } else {   // if there are NO commas
      return [""];
      //Cell_Len = 1;
    }
  });
}

如果我误解了你的问题,我很抱歉。

【讨论】:

  • 太棒了!! 修复 #2 就像一个魅力一样。 你的第一个修复我没有精力去工作。也许我做错了什么。我在函数声明之前和之后使用 2 个添加的 var 进行了尝试,但出现错误:错误类型错误:无法从未定义中读取属性“0”。但可以肯定你的第二个解决方案有效!非常感谢......我将不得不坐下来彻底了解你所做的一切! :)
  • 我试图理解为什么我们需要这个:input2[i][0] 当我们不需要 e[0] 的相同格式时。显然我们这样做了,否则它不起作用......我将不得不继续思考它......仍然没有完全沉没:)
  • @Thonex1234 很抱歉给您带来不便。你问“另一种模式:”吗?如果是这样,e[0]input2[i][0] 分别表示input1input2 的元素。我将索引i 用于input1,因为input1input2 的索引在您的情况下都是同步的。并使用i 检索input2 的元素。我对您的评论的理解正确吗?
  • 谢谢!您的理解是 100% 正确的。我只需要进行实验,以便我能完全理解。对不起..有时我很慢:)
  • @I'-'I 感谢您提供更多信息和您的支持!
猜你喜欢
  • 2012-05-10
  • 1970-01-01
  • 2011-01-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-26
  • 2020-06-06
相关资源
最近更新 更多