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

如果在自定义函数运行时出现问题,请返回错误以通知用户。 如果具有特定的参数要求(例如只有正数),请测试参数,如果参数不正确,则引发错误。 还可以使用 try...catch 块来捕获自定义函数运行时发生的任何错误。

检测和引发错误

让我们看一下需要确保邮政编码参数的格式正确,才能使自定义函数正常工作。 下面的自定义函数使用正则表达式来检查邮政编码。 如果邮政编码格式正确,它将使用另一个函数查找城市并返回值。 如果格式无效,则该函数会向单元格返回错误 #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! 输入参数替换为错误,然后返回包含处理每个输入参数的结果的 2 维数组。

/**
* 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。 默认情况下,Excel 针对未经处理的错误或异常返回 #VALUE!

在下面的代码示例中,自定义函数对 REST 服务执行 fetch 调用。 此调用有可能会失败,例如,如果 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);
    })
}

后续步骤

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

另请参阅