没想到一下子写了三篇关于自定义函数的短文,分别介绍了如何用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;}