简体中文
English 简体中文 繁體中文
Methodox 首页

工作表函数

工作簿可以携带自己的函数,它们用 Lua、C#、Python 编写,或以 Divooka 图的形式编写,公式可以像调用任何内置函数一样调用它们:=LUA.TAX(B2)、=CS.SUMSQ(A1:A10)、=PY.TAX(B2)、=DVK.LOANPAYMENT(B1, B2, B3)。它们是 Function:根据实参计算出一个值,不能更改工作簿,并在其读取的单元格发生变化时重新计算。

声明函数

在 Scripts 窗格中,把它们写在名为 functions.lua、functions.csx 或 functions.py(或 anything.functions.lua 等)的脚本中,然后保存。每个名称全部为大写字母的顶层函数都会成为工作表函数;其他函数是工作表看不到的辅助函数。

--- Twice its argument.
---@param x number
function DOUBLE(x) return x * 2 end

--- Tax on an amount, at 20% unless a rate is given.
---@param rate? number
function TAX(amount, rate) return amount * (rate or 0.2) end
/// <summary>Tax on an amount.</summary>
double TAX(double amount, double rate = 0.2) => amount * rate;
double SUMSQ(double[] values) => values.Sum(v => v * v);
int COUNT(params object[] items) => items.Length;

Lua 函数以 LUA.NAME 的形式调用,C# 函数以 CS.NAME 的形式调用,因此上述函数分别为 =LUA.DOUBLE(A1)、=LUA.TAX(B2, 0.15)、=CS.SUMSQ(A1:A10) 和 =CS.COUNT(A1, B1, C1)。它们会连同参数和说明一起出现在 Insert Function 中。

  • 说明和参数。 在 Lua 中,函数上方的 --- 行是它的说明;---@param name type 为参数指定类型(number、string、boolean),name? 使其成为可选参数,... 可接受任意数量的实参。在 C# 中,/// 摘要是说明,参数类型决定实参的转换方式,默认值使参数成为可选参数,params 可接受任意数量的实参。
  • 区域。 在 Lua 中声明为表(---@param values table)或在 C# 中声明为数组(double[]、object[,])的参数会接收整个区域,形式为由值组成的行。对于其他任何被传入区域的参数,函数会应用到每个单元格,结果会溢出。
  • 结果。 数字、文本或逻辑值;返回由行组成的表(Lua)或二维数组(C#)会将其溢出。返回图片的函数(例如图的图表或 host.getImage(url))会在其单元格中按比例适应显示图片,与 Excel 的 IMAGE 相同,单元格的值为 Image W×H。

保存函数脚本会重新加载它,并重新计算所有调用其函数的单元格。

Python 和 Divooka 图

functions.py 中的 Python 函数以 =PY.NAME(...) 的形式调用;参见 Python。工作簿的图文档中每个以大写字母命名的 Function 图都是一个工作表函数,以 =DVK.NAME(...) 的形式调用;参见 Divooka 图。

参数和获取的数据

函数在 Lua 和 Python 中以 param.Name、在 C# 中以 Param["Name"] 读取文档的参数,公式则以 =PARAM("Name") 直接读取参数;更改参数会精确地重新计算读取它的单元格。

通过宿主(host.get 及其同类调用)从网络获取数据或读取文件的函数是数据源 Function:在 Data ▸ Refresh Data(Ctrl+Shift+F5)获取数据之前,它显示 #N/A,之后会以上次刷新获取并保存在工作簿中的内容作答,直到下一次刷新或它读取的参数发生变化。第一次刷新时会要求你 Allow 它要获取的内容。如需不编写代码就从数据库或 Web API 获取表格,请使用 Data Source。

限制

  • 计算时间超过 2 秒的 Lua 函数调用(等待宿主获取数据的时间不计入)会被停止,并返回错误。函数只能通过其实参和文档的参数读取工作簿,没有 app、doc 或 os。
  • 对于相同实参,函数的结果会被重复使用,而不会重新计算。
  • 命名的 LAMBDA 尚未出现在 Insert Function 中。

启用

函数存储在工作簿中,因此工作簿到哪里,函数就到哪里。在工作簿被启用之前,它们不会运行:在此之前,调用它们的单元格显示 #BLOCKED!(Excel 中表示资源被阻止的错误),网格上方的栏显示 Scripts disabled 以及一个 Enable 按钮。工作簿根本没有声明的函数仍显示 #NAME?。参见信任。启用之后,如果活动单元格的函数失败,该栏会显示失败原因,以及脚本的文件和行号。

在 Excel 中

Excel 会在文件中保留函数的脚本,并保留公式的原样,但无法运行它们:这些单元格在 Excel 中显示 #NAME?。

扩展可以为每个工作簿添加函数,以扩展自身的前缀调用,例如 =TOOLS.SPELLNUMBER(1234.5)。

另请参阅