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