处理和返回自定义函数中的错误

当自定义函数收到无效的输入、无法访问资源或无法计算结果时,将返回可以返回最具体的 Excel 错误。 尽早验证参数以立即失败,并使用 try...catch 块将低级别异常转换为清晰的 Excel 错误。

检测和引发错误

以下示例使用正则表达式验证U.S. ZIP代码,然后再继续。 如果格式无效,则会引发 #VALUE! 错误。

/**
* Gets a city name for the given U.S. ZIP Code.
* @customfunction
* @param {string} zipCode
* @returns The city of the ZIP Code.
*/
function getCity(zipCode: string): string {
  let isValidZip = /(^\d{5}$)|(^\d{5}-\d{4}$)/.test(zipCode);
  if (isValidZip) return cityLookup(zipCode);
  let error = new CustomFunctions.Error(CustomFunctions.ErrorCode.invalidValue, "Please provide a valid U.S. zip code.");
  throw error;
}

CustomFunctions.Error 对象

CustomFunctions.Error 对象向单元格返回错误。 通过从以下列表中选择值来 ErrorCode 指定哪个错误。

ErrorCode 枚举值 Excel 单元格值 说明
divisionByZero #DIV/0 函数尝试除以零。
invalidName #NAME? 函数名称中存在拼写错误。 请注意,支持将此错误作为自定义函数输入错误,但不支持作为自定义函数输出错误。
invalidNumber #NUM! 公式中的数字存在问题。
invalidReference #REF! 函数引用无效的单元格。 请注意,支持将此错误作为自定义函数输入错误,但不支持作为自定义函数输出错误。
invalidValue #VALUE! 公式中的值的类型不正确。
notAvailable #N/A 函数或服务不可用。
nullReference #NULL! 公式中的范围不相交。

下面的代码示例演示了如何创建并返回无效数字 (#NUM!) 错误。

let error = new CustomFunctions.Error(CustomFunctions.ErrorCode.invalidNumber);
throw error;

#VALUE!#N/A 错误还支持自定义错误消息。 自定义错误消息显示在错误指示器菜单中,可通过将鼠标悬停在每个单元格上的错误标志上并显示错误来访问该菜单。 以下示例演示如何返回带有 错误的 #VALUE! 自定义错误消息。

// You can only return a custom error message with the #VALUE! and #N/A errors.
let error = new CustomFunctions.Error(CustomFunctions.ErrorCode.invalidValue, "The parameter can only contain lowercase characters.");
throw error;

处理动态数组时出现的错误

自定义函数可以返回包含错误的动态数组。 例如,自定义函数可以输出数组 [1],[#NUM!],[3]。 下面的代码示例演示如何将三个参数传递到自定义函数,将一个 #NUM! 参数替换为错误,然后返回包含每个输入的结果的二维数组。

/**
* Returns the #NUM! error as part of a 2-dimensional array.
* @customfunction
* @param {number} first First parameter.
* @param {number} second Second parameter.
* @param {number} third Third parameter.
* @returns {number[][]} Three results, as a 2-dimensional array.
*/
function returnInvalidNumberError(first, second, third) {
  // Use the `CustomFunctions.Error` object to retrieve an invalid number error.
  const error = new CustomFunctions.Error(
    CustomFunctions.ErrorCode.invalidNumber, // Corresponds to the #NUM! error in the Excel UI.
  );

  // Enter logic that processes the first, second, and third input parameters.
  // Imagine that the second calculation results in an invalid number error. 
  const firstResult = first;
  const secondResult =  error;
  const thirdResult = third;

  // Return the results of the first and third parameter calculations and a #NUM! error in place of the second result. 
  return [[firstResult], [secondResult], [thirdResult]];
}

作为自定义函数输入的错误

即使输入范围包含错误,自定义函数也可以计算。 例如,即使 A6:A7 包含错误,自定义函数也可以将范围 A2:A7 作为输入。

若要处理包含错误的输入,自定义函数必须将 JSON 元数据属性 allowErrorForDataTypeAny 设置为 true。 有关详细信息 ,请参阅手动为自定义函数创建 JSON 元数据

重要

属性 allowErrorForDataTypeAny 只能与 手动创建的 JSON 元数据一起使用。 此属性不适用于自动生成的 JSON 元数据进程。

使用 try...catch

使用 try...catch 块捕获潜在错误,并将有意义的错误消息返回给用户。 默认情况下,Excel 针对未经处理的错误或异常返回 #VALUE!

在以下代码示例中,自定义函数使用 fetch 来调用 REST 服务。 如果调用失败,例如当 REST 服务返回错误或网络不可用时,自定义函数将 #N/A 返回以显示 Web 调用失败。

/**
 * Gets a comment from the hypothetical contoso.com/comments API.
 * @customfunction
 * @param {number} commentID ID of a comment.
 */
function getComment(commentID) {
  let url = "https://www.contoso.com/comments/" + commentID;
  return fetch(url)
    .then(function (data) {
      return data.json();
    })
    .then(function (json) {
      return json.body;
    })
    .catch(function (error) {
      throw new CustomFunctions.Error(CustomFunctions.ErrorCode.notAvailable);
    })
}

后续步骤

了解如何解决自定义函数中的问题

另请参阅