将引用方法添加到单元格值,使用户能够基于单元格值访问动态计算。
EntityCellValue
和 LinkedEntityCellValue
类型支持引用方法。 例如,向将权重转换为不同单位的产品实体值添加方法。
以下屏幕截图显示了向表示煎饼混合的产品实体值添加 ConvertWeight
方法的示例。
DoubleCellValue
、 BooleanCellValue
和 StringCellValue
类型还支持引用方法。 以下屏幕截图显示了向双值类型添加 ConvertToRomanNumeral
方法的示例。
引用方法不会出现在用户的数据类型卡上。
向实体值添加引用方法
若要向实体值添加引用方法,请使用 类型在 JSON Excel.JavaScriptCustomFunctionReferenceCellValue
中描述它。 以下代码示例演示如何定义返回值 27 的简单方法。
const referenceCustomFunctionGet27: Excel.JavaScriptCustomFunctionReferenceCellValue = {
type: Excel.CellValueType.function,
functionType: Excel.FunctionCellValueType.javaScriptReference,
namespace: "CONTOSO",
id: "GET27"
}
下表介绍了这些属性。
属性 | 说明 |
---|---|
类型 | 指定引用的类型。 此属性仅支持 function ,并且必须设置为 Excel.CellValueType.function 。 |
functionType | 指定函数的类型。 此属性仅支持 JavaScript 引用函数,并且必须设置为 Excel.FunctionCellValueType.javaScriptReference 。 |
Namespace | 包含自定义函数的命名空间。 此值必须与统一清单中的 customFunctions.namespace 元素 指定的命名空间或仅外接程序清单中的 Namespace 元素 匹配。 |
id | 要映射到此引用方法的自定义函数的名称。 该名称是自定义函数名称的大写版本。 |
创建实体值时,请将 reference 方法添加到属性列表。 下面的代码示例演示如何创建名为 的 Math
简单实体值,并向其添加引用方法。
Get27
是将向用户显示的方法名称。 例如 A1.Get27()
。
function makeMathEntity(value: number){
const entity: Excel.EntityCellValue = {
type: Excel.CellValueType.entity,
text: "Math value",
properties: {
"value": {
type: Excel.CellValueType.double,
basicValue: value,
numberFormat: "#"
},
Get27: referenceCustomFunctionGet27
}
};
return entity;
}
下面的代码示例演示如何创建实体的 Math
实例并将其添加到所选单元格。
// Add entity to selected cell.
async function addEntityToCell(){
const entity: Excel.EntityCellValue = makeMathEntity(10);
await Excel.run( async (context) => {
const cell = context.workbook.getActiveCell();
cell.valuesAsJson = [[entity]];
await context.sync();
});
}
最后,引用方法由自定义函数实现。 以下代码示例演示如何实现自定义函数。
/**
* Returns the value 27.
* @customfunction
* @excludeFromAutocomplete
* @returns {number} 27
*/
function get27() {
return 27;
}
在前面的代码示例中 @excludeFromAutocomplete
,标记可确保在搜索框中输入自定义函数时,不会在 Excel UI 中向用户显示该函数。 但请注意,如果用户直接在单元格中输入自定义函数,则仍可以独立于实体值调用该函数。
当代码运行时,它会创建一个 Math
实体值,如以下屏幕截图所示。 当用户从公式引用实体值时,方法将显示在公式自动完成中。
添加参数
如果引用方法需要参数,请将它们添加到自定义函数。 下面的代码示例演示如何将名为 的参数添加到名为 x
AddValue
的方法。 方法通过调用名为 的AddValue
自定义函数将x
一个添加到值。
/**
* Adds a value to 1.
* @customfunction
* @excludeFromAutocomplete
* @param {number} x The value to add to 1.
* @return {number[][]} Sum of x and 1.
*/
function addValue(x): number[][] {
return [[x+1]];
}
引用实体值作为调用对象
一种常见方案是,方法需要引用实体值本身的属性来执行计算。 例如,如果 AddValue
方法将参数值添加到实体值本身,则它更有用。 通过将 标记应用于 @capturesCallingObject
自定义函数,指定将实体值作为第一个参数传入,如以下代码示例所示。
/**
* Adds x to the calling object.
* @customfunction
* @excludeFromAutocomplete
* @capturesCallingObject
* @param {any} math The math object (calling object).
* @param {number} x The value to add.
* @return {number[][]} Sum.
*/
function addValue(math, x): number[][] {
const result: number = math.properties["value"].basicValue + x;
return [[result]];
}
请注意,只要参数名称符合 公式中“名称”中指定的 Excel 语法规则,就可以是你决定的任何参数名称。 由于我们知道这是一个数学实体,因此我们将调用对象参数 math
命名为 。 参数名称可用于正文计算。 在前面的代码示例中,它将检索 math.[value]
属性以执行计算。
以下代码示例演示函数的 Contoso.AddValue
实现。
/**
* Adds x to the calling object.
* @customfunction
* @excludeFromAutocomplete
* @param {any} math The math object (calling object).
* @param {number} x The value to add.
* @return {number[][]} Sum.
*/
function addValue(math, x): number[][] {
const result: number = math.properties["value"].basicValue + x;
return [[result]];
}
请注意以下有关上一个代码示例。
- 标记
@excludeFromAutocomplete
可确保在搜索框中输入自定义方法时,不会在 Excel UI 中向用户显示该自定义方法。 但请注意,如果用户直接在单元格中输入自定义函数,则仍可以独立于实体值调用该函数。 - 调用对象始终作为第一个参数传递,并且必须按 类型
any
传递。 在本例中,它命名math
为 ,用于从math
对象获取值属性。 - 它返回数字的双精度数组。
- 当用户与 Excel 中的引用方法交互时,他们不会将调用对象视为参数。
示例:计算产品销售税
以下代码演示如何实现计算产品单价销售税的自定义函数。
/**
* Calculates the price when a sales tax rate is applied.
* @customfunction
* @excludeFromAutocomplete
* @capturesCallingObject
* @param {any} product The product entity value (calling object).
* @param {number} taxRate The tax rate (0.11 = 11%).
* @return {number[][]} Product unit price with tax rate applied.
*/
function applySalesTax(product, taxRate): number[][] {
const unitPrice: number = product.properties["Unit Price"].basicValue;
const result: number = unitPrice * taxRate + unitPrice;
return [[result]];
}
下面的代码示例演示如何指定引用方法,并包括 id
自定义函数的 applySalesTax
。
const referenceCustomFunctionCalculateSalesTax: Excel.JavaScriptCustomFunctionReferenceCellValue = {
type: Excel.CellValueType.function,
functionType: Excel.FunctionCellValueType.javaScriptReference,
namespace: "CONTOSO",
id: "APPLYSALESTAX"
}
以下代码演示如何将引用方法添加到 product
实体值。
function makeProductEntity(productID: number, productName: string, price: number) {
const entity: Excel.EntityCellValue = {
type: Excel.CellValueType.entity,
text: productName,
properties: {
"Product ID": {
type: Excel.CellValueType.string,
basicValue: productID.toString() || ""
},
"Product Name": {
type: Excel.CellValueType.string,
basicValue: productName || ""
},
"Unit Price": {
type: Excel.CellValueType.formattedNumber,
basicValue: price,
numberFormat: "$* #,##0.00"
},
applySalesTax: referenceCustomFunctionCalculateSalesTax
},
};
return entity;
}
从 Excel UI 中排除自定义函数
@excludeFromAutoComplete
在引用方法使用的自定义函数的注释说明中使用 标记,以指示该函数将从自动完成下拉列表和公式生成器中排除。 这有助于防止用户意外地将自定义函数与其实体值分开使用。
注意
如果在网格中手动正确输入函数,则函数仍将执行。 此外,函数不能同时 @excludeFromAutoComplete
包含 和 @linkedEntityLoadService
标记。
标记@excludeFromAutoComplete
在生成过程中进行处理,以便通过 Custom-Functions-Metadata 包生成functions.json文件。 如果你从 yo office 开始并选择自定义函数模板,则此包会自动添加到生成过程。 如果不使用此包,则需要手动将 属性添加到 excludeFromAutoComplete
functions.json 文件。
以下代码示例演示如何在 functions.json 文件中使用 JSON 手动描述 APPLYSALESTAX
。
excludeFromAutoComplete
属性设置为 true
。
{
"description": "Calculates the price when a sales tax rate is applied.",
"id": "APPLYSALESTAX",
"name": "APPLYSALESTAX",
"options": {
"excludeFromAutoComplete": true,
"capturesCallingObject": true
},
"parameters": [
{
"description": "The product entity value (calling object).",
"name": "product",
"type": "any"
},
{
"description": "The tax rate (0.11 = 11%).",
"name": "taxRate",
"type": "number"
}
],
"result": {
"dimensionality": "matrix",
"type": "number"
}
},
有关详细信息,请参阅 手动为自定义函数创建 JSON 元数据。
将函数添加到基本值类型
若要将函数添加到 、 double
和 string
的基本值类型Boolean
,该过程与实体值的过程相同。 使用 JSON 作为引用方法描述函数。 下面的代码示例演示如何使用向基本值添加值的x
函数AddValue()
创建双基本值。
/**
* Adds the value x to the number value.
* @customfunction
* @capturesCallingObject
* @param {any} numberValue The number value (calling object).
* @param {number} x The value to add to 1.
* @return {number[][]} Sum of x and 1.
*/
export function addValue(numberValue: any, x: number): number[][] {
return [[x+numberValue.basicValue]];
}
以下代码示例演示如何在 Excel 中将 addValue
引用方法添加到简单数字。
const referenceCustomFunctionAddValue: Excel.JavaScriptCustomFunctionReferenceCellValue = {
type: Excel.CellValueType.function,
functionType: Excel.FunctionCellValueType.javaScriptReference,
namespace: "CONTOSO",
id: "ADDVALUE"
}
async function createSimpleNumber() {
await Excel.run(async (context) => {
const sheet = context.workbook.worksheets.getActiveWorksheet();
const range = sheet.getRange("A1");
range.valuesAsJson = [
[
{
type: Excel.CellValueType.double,
basicType: Excel.RangeValueType.double,
basicValue: 6.0,
properties: {
addValue: referenceCustomFunctionAddValue
}
}
]
];
await context.sync();
});
}
Optional 参数
以下代码示例演示如何创建接受可选参数的引用方法。 引用方法命名 generateRandomRange
为 ,它生成一系列随机值。
const referenceCustomFunctionOptional: Excel.JavaScriptCustomFunctionReferenceCellValue = {
type: Excel.CellValueType.function,
functionType: Excel.FunctionCellValueType.javaScriptReference,
namespace: "CONTOSO",
id: "GENERATERANDOMRANGE"
}
function makeProductEntity(productID: number, productName: string, price: number) {
const entity: Excel.EntityCellValue = {
type: Excel.CellValueType.entity,
text: productName,
properties: {
"Product ID": {...},
"Product Name": {...},
"Unit Price": {...},
generateRandomRange: referenceCustomFunctionOptional
},
};
return entity;
}
下面的代码示例将 reference 方法的实现显示为名为 的 generateRandomRange
自定义函数。 它返回与 和 指定的数目rows
columns
匹配的随机值的动态数组。
min
和 max
参数是可选的,如果未指定,则默认为 1
和 10
。
/**
* Generate a dynamic array of random numbers.
* @customfunction
* @excludeFromAutocomplete
* @param {number} rows Number of rows to generate.
* @param {number} columns Number of columns to generate.
* @param {number} [min] Lowest number that can be generated. Default is 1.
* @param {number} [max] Highest number that can be generated. Default is 10.
* @returns {number[][]} A dynamic array of random numbers.
*/
function generateRandomRange(rows, columns, min, max) {
// Set defaults for any missing optional arguments.
if (min===null) min = 1;
if (max === null) max = 10;
let numbers = new Array(rows);
for (let r = 0; r < rows; r++) {
numbers[r] = new Array(columns);
for (let c = 0; c < columns; c++) {
numbers[r][c] = Math.round(Math.random() * (max - min) ) + min;
}
}
return numbers;
}
当用户在 Excel 中输入函数时,自动完成会显示函数的属性,并通过在括号 [] 中括起可选参数来指示可选参数。 下图显示了使用 generateRandomRange
reference 方法输入可选参数的示例。
多个参数
引用方法支持多个参数,类似于 Excel SUM
函数支持多个参数的方式。 下面的代码示例演示如何创建一个引用函数,该函数连接在 product 数组中传递的零个或多个产品名称。 函数以 的形式 concatProductNames([products], ...)
向用户显示。
/**
* @customfunction
* @excludeFromAutocomplete
* @description Concatenate the names of given products, joined by " | "
* @param {any[]} products - The products to concatenate.
* @returns A string of concatenated product names.
*/
function concatProductNames(products: any[]): string {
return products.map((product) => product.properties["Product Name"].basicValue).join(" | ");
}
下面的代码示例演示如何使用 concatProductNames
reference 方法创建实体。
const referenceCustomFunctionMultiple: Excel.JavaScriptCustomFunctionReferenceCellValue = {
type: Excel.CellValueType.function,
functionType: Excel.FunctionCellValueType.javaScriptReference,
namespace: "CONTOSO",
id: "CONCATPRODUCTNAMES"
}
function makeProductEntity(productID: number, productName: string, price: number) {
const entity: Excel.EntityCellValue = {
type: Excel.CellValueType.entity,
text: productName,
properties: {
"Product ID": {...},
"Product Name": {...},
"Unit Price": {...},
concatProductNames: referenceCustomFunctionMultiple,
},
};
return entity;
}
下图显示了使用 concatProductNames
reference 方法输入多个参数的示例。
具有范围的多个参数
若要支持将范围传递给引用方法(如 B1:B3),请使用多维数组。 下面的代码示例演示如何创建一个引用函数,该函数对可以包含范围的零个或多个参数求和。
/**
* @customfunction
* @excludeFromAutocomplete
* @description Calculate the sum of arbitrary parameters.
* @param {number[][][]} operands - The operands to sum.
* @returns The sum of all operands.
*/
function sumAll(operands: number[][][]): number {
let total: number = 0;
operands.forEach(range => {
range.forEach(row => {
row.forEach(num => {
total += num;
});
});
});
return total;
}
下面的代码示例演示如何使用 sumAll
reference 方法创建实体。
const referenceCustomFunctionRange: Excel.JavaScriptCustomFunctionReferenceCellValue = {
type: Excel.CellValueType.function,
functionType: Excel.FunctionCellValueType.javaScriptReference,
namespace: "CONTOSO",
id: "SUMALL"
}
function makeProductEntity(productID: number, productName: string, price: number) {
const entity: Excel.EntityCellValue = {
type: Excel.CellValueType.entity,
text: productName,
properties: {
"Product ID": {...},
"Product Name": {...},
"Unit Price": {...},
sumAll: referenceCustomFunctionRange
},
};
return entity;
}
下图显示了使用 reference 方法输入多个参数(包括范围参数) sumAll
的示例。
支持详细信息
所有自定义函数类型(例如 volatile 和 流式处理 自定义函数)都支持引用方法。 此外,支持所有自定义函数返回类型 (矩阵、标量和错误) 链接实体不能具有同时结合引用方法和数据提供程序的自定义函数。 在开发链接实体时,请务必将这些类型的自定义函数分开。