那些Excel中的脚本:自定义函数(4)

没想到一下子写了三篇关于自定义函数的短文,分别介绍了如何用Script Lab快速创建和体验自定义函数,以及解析了背后的原理,然后还看到了在自己开发的Add-in中如何实现同样的效果。

这一篇将专注于自定义函数的三种类型:.

1)普通函数

2)流式函数

3)易失函数

普通函数,就是如它名字一样,很普通。你输入函数,回车,它帮你计算一次,除非你再次选中它,又按下一次回车。又或是你强制整个工作表重新计算(F9)。

定义普通函数的方式如下

/** * Adds two numbers. * @customfunction * @param first First number * @param second Second number * @returns The sum of the two numbers. */export function add(first: number, second: number): number {  return first + second;}

@customfunction 是声明这是一个自定义函数

@param 分别声明了两个参数

@returns 说明了返回值的信息

流式函数则比较特殊,它会自动进行重新计算,可以把最新数据源源不断地提供过来。它的定义方式如下,和普通函数相比,它会多一个特殊的参数 invocation, 这个函数的结果是通过 invocation.setResult来发送,而不是函数的return语句。

/** * Displays the current time once a second. * @customfunction * @param invocation Custom function handler */export function clock(invocation: CustomFunctions.StreamingInvocation<string>): void {  const timer = setInterval(() => {    const time = currentTime();    invocation.setResult(time);  }, 1000);
  invocation.onCanceled = () => {    clearInterval(timer);  };}

代码已经说明了一切,神奇的地方是因为它用了一个定时器,每隔一定的时间重新计算而已。

魔法的背后还有一个细节,就是在metadata定义中,这个函数比普通函数会多出来一个 option, stream = true

{    "description": "Displays the current time once a second.",    "id": "CLOCK",    "name": "CLOCK",    "options": {        "stream": true    },    "parameters": [],    "result": {        "type": "string"    }},

第三种易失函数,可以理解为随时会发生变化的函数。内置函数中的NOW, RAND等都属于这一类。它的易失性,是当工作表任何单元格发生计算时它都会重新计算。

下面是一个简单的例子,掷色子。你可以看到,关键就在于 多了一个 @volatile的定义。

/** * Simulates rolling a 6-sided dice. * @customfunction * @volatile */function roll6sided() {  return Math.floor(Math.random() * 6) + 1;}