找回密码
 立即注册

QQ登录

只需一步,快速开始

Lynn.Dou 讲师达人认证 悬赏达人认证 SpreadJS 开发认证
超级版主   /  发表于:2022-9-30 17:15  /   查看:2166  /  回复:0
本帖最后由 Lynn.Dou 于 2023-9-20 17:01 编辑

熟悉SpreadJS功能的小伙伴可能有了解或使用过自定义函数,相关知识点在学习指南也有相关介绍:
https://demo.grapecity.com.cn/sp ... om-functions/purejs
本篇教程就结合附件demo来讲解下在定义自定义函数时,不同类型的参数是如何获取以及处理的。

步骤:
结合附件demo调试看看各参数的作用,

在evaluate方法内,可以通过arguments获取传参数组,如下图:
image.png903743286.png
仔细观察,你会发现arguments中有6个元素,但实际自定义函数传入的是5个参数。
  1. sheet.setFormula(2, 0, '=FACTORIAL(Sheet1!B2:B4, Sheet2!D2, Sheet3!C2:C4, "test", 12)');
复制代码

它的存在与isContextSensitive这个设置有关。
  1. FactorialFunction.prototype.isContextSensitive = function () {
  2.         return true;// 函数的计算是否依赖于计算的上下文
  3.     }
复制代码
如果isContextSensitive设置为true,那么arguments实际的个数会比自定义函数的传参多1,且位于第一个位置。
如果为false,这个元素就不存在了,arguments实际的个数也就与自定义函数的传参相同了。

那么arguments[0]这个参数是做什么的呢?
其实第一个元素是上下文,可以通过它获取sheet对象/spread对象。
  1. var mySheet = arguments[0].source.getSheet();
  2. var mySpread = arguments[0].source.getSheet().getParent();
复制代码
也可以获取自定义函数应用的单元格索引信息:
3b07ea442c0027a95e79c7e89f0fe74.png526692504.png
在定义自定义函数时,我们往往需要借助上下文信息对sheet对象/spread对象做一下操作,比如说获取当前sheet的name。
但,它也并不是获取上下文对象的唯一方式,具体与自定义函数的参数有关,我们带着问题继续看下文。

1、参数为字符串 或 数值

可以直接从argument中获取参数值
image.png223843383.png

这种情况下,如果要用到sheet对象/spread对象,就需要通过arguments[0]来获取。

也就是说,在自定义函数参数为数值或字符串的情况下,如果函数逻辑中需要用到上下文对象,就需要设置isContextSensitive为true。


2、参数为单元格区域

参数为单元格区域时,即使不设置isContextSensitive为true,在argument内部也是可以获取到上下文信息的。
如下图,argument.getSource().getSheet() 获取sheet,进而获取sheetName
image.png134112547.png
使用getRow等方法获取参数区域的行列信息,最后使用rangeToFormula方法将区域信息转换为区域字符串
image.png907610473.png
最后可以拼接输出。
image.png377292174.png
也就是说,在参数为单元区域时,也可以不设置isContextSensitive为true,通过其他元素内部获取上下文信息。
当然加上也是没问题的,这里更想带大家了解的是各参数具体的作用,这样开发起来就心中有数了。

具体代码如下:
  1. FactorialFunction.prototype.evaluate = function (arg) {
  2.         console.log(arguments);
  3.         // arguments 中第一个参数为计算上下文(即通过上下文可获取spread对象)。
  4.         // 若isContextSensitive设置false,则此参数不存在。
  5.         // 若isContextSensitive设置为true,则此参数存在。
  6.         var mySheet = arguments[0].source.getSheet();
  7.         //var mySpread = arguments[0].source.getSheet().getParent();

  8.         var length = arguments.length;
  9.         for (var i = 1; i < length; i++) {
  10.             var argument = arguments[i];
  11.             if (typeof (argument) == 'string' || typeof (argument) == 'number') {
  12.                 console.log("参数" + i + "为" + argument);
  13.             } else {
  14.                 // 参数为单元格区域时,通过argument也可以获取到上下文
  15.                 // var mySheet = argument.getSource().getSheet();
  16.                 var sheetName = mySheet.name();
  17.                 console.log("参数" + i + "sheetName为:" + sheetName);
  18.                 var r = argument.getRow();
  19.                 var c = argument.getColumn();
  20.                 var rc = argument.getRowCount();
  21.                 var cc = argument.getColumnCount();
  22.                 var range = new GC.Spread.Sheets.Range(r, c, rc, cc);
  23.                 var string = GC.Spread.Sheets.CalcEngine.rangeToFormula(range, 0, 0, GC.Spread.Sheets.CalcEngine.RangeReferenceRelative.allRelative);
  24.                 var setFormulaString = "" + sheetName + "!" + string;
  25.                 console.log("参数" + i + "为" + setFormulaString);
  26.             }
  27.         }
  28.         return "anything";
  29.     };
复制代码

理论知识有些复杂,大家可以结合demo实际调试看看,感受到自定义函数这些参数的具体作用。
附件为完整demo,以供参考。




image.png714281310.png
3b07ea442c0027a95e79c7e89f0fe74.png303120726.png
5e65eb9708434f092c423537a20285d.png449378966.png

自定义函数-参数解析.zip

2.09 KB, 下载次数: 116

评分

参与人数 1满意度 +5 收起 理由
陈皮 + 5

查看全部评分

0 个回复

您需要登录后才可以回帖 登录 | 立即注册
返回顶部