为自定义函数自动生成 JSON 元数据

在使用 JavaScript 或 TypeScript 编写 Excel 自定义函数时,使用 JSDoc 标记提供有关自定义函数的额外信息。 我们提供了一个 Webpack 插件,该插件使用这些 JSDoc 标记在生成时自动创建 JSON 元数据文件。 使用插件可避免 手动编辑 JSON 元数据文件

重要

请注意,以下平台上可以使用 Excel 自定义函数。

  • Windows 版 Office
    • Microsoft 365 订阅
    • 零售永久 Office 2016 及更高版本
  • Mac 版 Office
  • Office 网页版

以下各项当前不支持 Excel 自定义函数:

  • iPad 版 Office
  • Office 2019 或更早版本的批量许可永久版本

CustomFunctionsMetadataPlugin

插件为 CustomFunctionsMetadataPlugin。 若要安装和配置它,请使用以下步骤。

注意

  1. 打开命令提示符或 bash shell,并在项目的根目录中运行 npm install custom-functions-metadata-plugin

  2. 打开 webpack.config.js 文件,并在顶部添加以下行: const CustomFunctionsMetadataPlugin = require("custom-functions-metadata-plugin");

  3. 向下滚动到数组, plugins 并将以下内容添加到数组顶部。 根据需要更改 input 路径和文件名以匹配项目,但 output 值必须为“functions.json”。 如果使用 TypeScript,请使用 *.ts源文件名称, 而不是 转换的 *.js 文件。

    new CustomFunctionsMetadataPlugin({
       output: "functions.json",
       input: "./src/functions/functions.js", 
    }),
    

多个自定义函数源文件

如果并且仅当已将自定义函数组织到多个源文件中时,还需要执行其他步骤。

  1. 在 webpack.config.js 文件中,将 的 input 字符串值替换为指向每个文件的字符串 URL 数组。 示例如下:

    new CustomFunctionsMetadataPlugin({
       output: "functions.json",
       input: [
                "./src/functions/someFunctions.js", 
                "./src/functions/otherFunctions.js"
              ], 
    }),
    
  2. 滚动到 entry.functions 属性,并将其值替换为在上一步中使用的相同数组。 示例如下:

    entry: {
       polyfill: ["core-js/stable", "regenerator-runtime/runtime"],
       taskpane: ["./src/taskpane/taskpane.js", "./src/taskpane/taskpane.html"],
       functions: [
                "./src/functions/someFunctions.js", 
                "./src/functions/otherFunctions.js"
              ],
     },
    

运行工具

无需执行任何操作即可运行该工具。 当 Webpack 运行时,它会创建 functions.json 文件,并在开发模式下将其放入内存中,或在生产模式下将其放入 /dist 文件夹。

JSDoc 标记的基础知识

为 JavaScript 或 TypeScript 函数添加代码注释中的 @customfunction 标记以将其标记为自定义函数。

可以使用 JavaScript 中的 @param 标记或从 TypeScript 中的函数类型提供函数参数类型。 有关详细信息,请参阅 @param 标记和类型部分。

向函数添加说明

当用户需要帮助来了解自定义函数的功能时,将向用户显示用作帮助文本的说明。 说明不需要任何特定标记。 只需在 JSDoc 注释中输入简短的文本说明即可。 一般来说,说明位于 JSDoc 注释部分的开头,但无论位于何处,它都有用。

若要查看内置函数说明的示例,请打开 Excel,转到“公式”选项卡,然后选择“插入函数”。 然后,你可以浏览所有函数说明,还可以查看列出的自定义函数。

在以下示例中,短语“计算球体的体积”。是自定义函数的说明。

/**
/* Calculates the volume of a sphere.
/* @customfunction VOLUME
...
 */

支持的 JSDoc 标记

Excel 自定义函数支持以下 JSDoc 标记。


@cancelable

指示自定义函数在取消函数时执行操作。

最后一个函数参数的类型必须是 CustomFunctions.CancelableInvocation。 函数可以向 属性分配函数, oncanceled 以在取消函数时表示结果。

如果最后一个函数参数的类型为 CustomFunctions.CancelableInvocation,则即使标记不存在,也会被视为 @cancelable

函数不能同时具有 @cancelable@streaming 标记。

@customfunction

语法: @customfunctionid名称

此标记指示 JavaScript/TypeScript 函数是 Excel 自定义函数。 需要为自定义函数创建元数据。

下面显示了此标记的示例。

/**
 * Increments a value once a second.
 * @customfunction
 * ...
 */

id

标识 id 自定义函数。

  • 如果未提供 id,请将 JavaScript/TypeScript 函数名称转换为大写并删除禁用字符。
  • id 对于所有自定义函数必须是唯一的。
  • 允许的字符限制为:A-Z、a-z、0-9、下划线 (_) 和句点 (.) 。

在下面的示例中,增量是函数的 idname

/**
 * Increments a value once a second.
 * @customfunction INCREMENT
 * ...
 */

name

提供自定义函数的显示name

  • 如果未提供名称,则 id 还会用作名称。
  • 允许的字符:字母 Unicode 字母、数字、句点 (.) 和下划线 (_) 。
  • 必须以字母开头。
  • 最大长度为 128 个字符。

在下面的示例中,INC 是函数的 id,并且 incrementname

/**
 * Increments a value once a second.
 * @customfunction INC INCREMENT
 * ...
 */

说明

用户在 Excel 中输入函数时会显示一个说明,并指定函数的作用。 说明不需要任何特定标记。 通过在 JSDoc 注释中添加一个短语来描述函数的功能,为自定义函数添加说明。 默认情况下,JSDoc 注释部分中未标记的任何文本都是该函数的说明。

在以下示例中,短语“对两个数字求和的函数”是 id 属性为 ADD 的自定义函数的相关说明。

/**
 * A function that adds two numbers.
 * @customfunction ADD
 * ...
 */

@helpurl

语法: @helpurlurl

提供的 url 显示在 Excel 中。

在以下示例中, helpurlhttp://www.contoso.com/weatherhelp

/**
 * A function which streams the temperature in a town you specify.
 * @customfunction getTemperature
 * @helpurl http://www.contoso.com/weatherhelp
 * ...
 */

@param

JavaScript

JavaScript 语法: @param {type} 名称说明

  • {type} 指定大括号内的类型信息。 有关可能使用的类型的详细信息,请参阅类型部分。 如果未指定类型,将使用默认类型 any
  • name 指定 @param 标记应用于的参数。 它是必需的。
  • description 为函数参数提供显示在 Excel 中的说明。 它是可选的。

若要将自定义函数参数表示为可选,请在参数名称周围放置方括号。 例如,@param {string} [text] Optional text

注意

可选参数的默认值为 null

以下示例演示一个 ADD 函数,该函数添加两个或三个数字,其中第三个数字作为可选参数。

/**
 * A function which sums two, or optionally three, numbers.
 * @customfunction ADDNUMBERS
 * @param firstNumber {number} First number to add.
 * @param secondNumber {number} Second number to add.
 * @param [thirdNumber] {number} Optional third number you wish to add.
 * ...
 */

TypeScript

TypeScript 语法: @param名称说明

  • name 指定 @param 标记应用于的参数。 它是必需的。
  • description 为函数参数提供显示在 Excel 中的说明。 它是可选的。

有关可能使用的函数参数类型的详细信息,请参阅类型部分。

若要将自定义函数参数表示为可选,请执行以下操作之一:

  • 使用可选参数。 例如:function f(text?: string)
  • 为该参数提供默认值。 例如:function f(text: string = "abc")

有关 @param 的详细说明,请参阅:JSDoc

注意

可选参数的默认值为 null

下面的示例显示了将两个数字相加的 add 函数。

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

@requiresAddress

表示应提供计算函数所在的单元格的地址。

最后一个函数参数必须是 类型 CustomFunctions.Invocation 或派生类型才能使用 @requiresAddress。 调用函数时,address 属性将包含地址。

下面的示例演示如何将 invocation 参数与 @requiresAddress 结合使用,以返回调用自定义函数的单元格的地址。 有关详细信息 ,请参阅调用参数

/**
 * Return the address of the cell that invoked the custom function. 
 * @customfunction
 * @param {number} first First parameter.
 * @param {number} second Second parameter.
 * @param {CustomFunctions.Invocation} invocation Invocation object. 
 * @requiresAddress 
 */
function getAddress(first, second, invocation) {
  const address = invocation.address;
  return address;
}

@requiresParameterAddresses

指示函数应返回输入参数的地址。

最后一个函数参数必须是 类型 CustomFunctions.Invocation 或派生类型才能使用 @requiresParameterAddresses。 JSDoc 注释还必须包含一个 @returns 标记,该标记指定返回值是矩阵,例如 @returns {string[][]}@returns {number[][]}。 有关其他信息 ,请参阅矩阵类型

调用 函数时, parameterAddresses 属性将包含输入参数的地址。

以下示例演示如何将 invocation 参数与 @requiresParameterAddresses 结合使用以返回三个输入参数的地址。 有关详细信息 ,请参阅检测参数的地址

/**
 * Return the addresses of three parameters. 
 * @customfunction
 * @param {string} firstParameter First parameter.
 * @param {string} secondParameter Second parameter.
 * @param {string} thirdParameter Third parameter.
 * @param {CustomFunctions.Invocation} invocation Invocation object. 
 * @returns {string[][]} The addresses of the parameters, as a 2-dimensional array.
 * @requiresParameterAddresses
 */
function getParameterAddresses(firstParameter, secondParameter, thirdParameter, invocation) {
  const addresses = [
    [invocation.parameterAddresses[0]],
    [invocation.parameterAddresses[1]],
    [invocation.parameterAddresses[2]]
  ];
  return addresses;
}

@returns

语法:@returns {type}

提供返回值的类型。

如果省略 {type},则将使用 TypeScript 类型信息。 如果没有类型信息,则类型将为 any

下面的示例显示了使用 @returns 标记的 add 函数。

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

@streaming

用于表示自定义函数是一个流式处理函数。

最后一个参数的类型 CustomFunctions.StreamingInvocation<ResultType>为 。 函数返回 void

流式处理函数不直接返回值,而是使用最后一个参数调用 setResult(result: ResultType)

由流式处理函数引发的异常将被忽略。 setResult() 可能称为“错误”,以指示错误结果。 有关流式处理函数的示例和更多信息,请参阅生成流式处理函数

流式处理函数不能标记为 @volatile

@volatile

可变函数是指其结果不断变化的函数,即使不采用任何参数或参数未发生更改都是如此。 Excel 在每次完成计算后,都会重新计算包含可变函数和所有依赖项的单元格。 因此,过于依赖可变函数会使重新计算时间变慢,请谨慎使用。

流式处理函数不能为可变函数。

以下函数是可变函数并使用 @volatile 标记。

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

类型

通过指定参数类型,Excel 会在调用函数之前将值转换为该类型。 如果类型为 any,则不会执行任何转换。

值类型

可以使用以下类型之一表示单个值:booleannumberstring

矩阵类型

使用二维数组类型将参数或返回值变为值的矩阵。 例如,类型 number[][] 指示数字矩阵,并 string[][] 指示字符串矩阵。

错误类型

非流式处理函数可以通过返回错误类型来指示错误。

流式处理函数可以通过使用错误类型调用 setResult() 来指示错误。

Promise

自定义函数可以返回一个 promise,该承诺在解析承诺时提供值。 如果承诺被拒绝,则自定义函数将引发错误。

其他类型

任何其他类型都将被视为错误。

后续步骤

了解 自定义函数的命名和本地化

另请参阅