向单元格值添加引用方法

将引用方法添加到单元格值,使用户能够基于单元格值访问动态计算。 EntityCellValueLinkedEntityCellValue 类型支持引用方法。 例如,向将权重转换为不同单位的产品实体值添加方法。

以下屏幕截图显示了向表示煎饼混合的产品实体值添加 ConvertWeight 方法的示例。

显示 =A1 的 Excel 公式的屏幕截图。ConvertWeight ( 盎司 )

DoubleCellValueBooleanCellValueStringCellValue 类型还支持引用方法。 以下屏幕截图显示了向双值类型添加 ConvertToRomanNumeral 方法的示例。

显示 =A1 的 Excel 公式的屏幕截图。ConvertToRomanNumeral ()

引用方法不会出现在用户的数据类型卡上。

Pancake mix 数据类型的数据卡的屏幕截图,但未列出引用方法。

向实体值添加引用方法

若要向实体值添加引用方法,请使用 类型在 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 实体值,如以下屏幕截图所示。 当用户从公式引用实体值时,方法将显示在公式自动完成中。

输入 A1 的屏幕截图。中的 Excel 和公式自动完成,显示 Get27 引用方法。

添加参数

如果引用方法需要参数,请将它们添加到自定义函数。 下面的代码示例演示如何将名为 的参数添加到名为 xAddValue的方法。 方法通过调用名为 的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 开始并选择自定义函数模板,则此包会自动添加到生成过程。 如果不使用此包,则需要手动将 属性添加到 excludeFromAutoCompletefunctions.json 文件。

以下代码示例演示如何在 functions.json 文件中使用 JSON 手动描述 APPLYSALESTAXexcludeFromAutoComplete 属性设置为 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 元数据

将函数添加到基本值类型

若要将函数添加到 、 doublestring的基本值类型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自定义函数。 它返回与 和 指定的数目rowscolumns匹配的随机值的动态数组。 minmax 参数是可选的,如果未指定,则默认为 110

/**
 * 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 中输入 generateRandomRange 方法的屏幕截图。

多个参数

引用方法支持多个参数,类似于 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 方法输入多个参数的示例。

在 Excel 中输入 concatProductNames 方法的屏幕截图,其中传递了包含自行车和独轮车产品实体值的 A1 和 A2。

具有范围的多个参数

若要支持将范围传递给引用方法(如 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 的示例。

在 Excel 中输入 sumAll 方法传递可选范围 B1:B2 的屏幕截图。

支持详细信息

所有自定义函数类型(例如 volatile流式处理 自定义函数)都支持引用方法。 此外,支持所有自定义函数返回类型 (矩阵、标量和错误) 链接实体不能具有同时结合引用方法和数据提供程序的自定义函数。 在开发链接实体时,请务必将这些类型的自定义函数分开。

另请参阅