[]
LAMBDA 函数允许用户在 Excel 中创建自定义且可重用的函数,为其分配易于识别的名称,并像使用 Excel 内置函数一样在整个工作簿中使用它们。
您可以将常用公式封装到自定义函数中,并在 Excel 的“名称管理器”中进行定义。使用时,直接调用定义好的名称即可,无需重复复制粘贴,从而降低出错风险。LAMBDA 函数不依赖 VBA、宏或 JavaScript,这显著提高了公式的可重用性和可维护性。
LAMBDA 函数的语法为 =LAMBDA([参数 1, 参数 2, …], 计算过程),各参数说明如下:
参数 | 描述 |
|---|---|
参数 | [可选] 要传递给函数的值,例如单元格引用、字符串或数字。最多可输入 253 个参数。此参数为可选。 |
计算过程 | [必需] 要执行并作为函数结果返回的公式。它必须是最后一个参数,且必须返回一个结果。此参数为必需。 |
以下示例演示了如何在 GcExcel 中使用“名称管理器”自定义一个 LAMBDA 公式,用于批量将华氏温度转换为摄氏温度。
// 创建工作簿。
Workbook workbook = new Workbook();
IWorksheet sheet = workbook.getWorksheets().get(0);
// 设置数据。
Object[][] data = {
{ "日期","华氏度" },
{ "2025-06-01", 95},
{ "2025-06-02", 95},
{ "2025-06-03", 96.8},
{ "2025-06-04", 86},
{ "2025-06-05", 82.4},
{ "2025-06-06", 89.6},
{ "2025-06-07", 86},
{ "2025-06-08", 87.8}
};
sheet.getRange("B3:C11").setValue(data);
ITable table = sheet.getTables().add(sheet.getRange("B3:C11"), true);
ITable table1 = sheet.getTables().add(sheet.getRange("E3:E11"), true);
sheet.getRange("B3:B11").setNumberFormat("yyyy-mm-dd");
table.convertToRange();
table1.convertToRange();
// 定义 LAMBDA 名称 ToCelsius,实现华氏度转换为摄氏度的公式。
workbook.getNames().add("ToCelsius", "=LAMBDA(temp, (5/9) * (temp-32))");
// 在 E4:E11 区域插入公式,将 C 列的华氏度值转换为摄氏度。
sheet.getRange("E4:E11").setFormula2("ToCelsius(C4)");
sheet.getRange("E3").setValue("=ToCelsius(C4:C11)");
sheet.getRange("B:E").autoFit();
// 保存 Excel 文件。
workbook.save("LAMBDAToCelsius.xlsx");输出结果如下图所示:

注意:setFormula2 允许您设置支持动态数组函数和最新 Excel 公式功能的公式,同时保持与 Formula 的完全兼容性。有关更多信息,请参见 动态数组公式。
LAMBDA 函数在分配给定义的名称时可以引用自身,从而实现递归计算。在 GcExcel Java 中,LAMBDA 的最大递归深度为 256 级。以下示例演示了如何在“名称管理器”中创建自定义 LAMBDA 函数来计算一个数的阶乘。
// 创建工作簿。
Workbook workbook = new Workbook();
IWorksheet sheet = workbook.getWorksheets().get(0);
sheet.setName("FactorialLambda");
// 设置数据。
sheet.getRange("A1").setValue("n");
sheet.getRange("A2").setValue(1);
sheet.getRange("A3").setValue(2);
sheet.getRange("A4").setValue(3);
sheet.getRange("A5").setValue(4);
sheet.getRange("A6").setValue(5);
sheet.getRange("A7").setValue(6);
sheet.getColumns().get(1).setColumnWidth(10);
sheet.getColumns().get(0).setHorizontalAlignment(HorizontalAlignment.Right);
sheet.getColumns().get(1).setHorizontalAlignment(HorizontalAlignment.Right);
sheet.getRange("A1:B1").getFont().setBold(true);
// 添加定义名称“Factorial”以实现一个数的阶乘计算。
workbook.getNames().add("Factorial", "=LAMBDA(n, IF(n<=1, 1, n*Factorial(n-1)))");
sheet.getRange("B1").setValue("=Factorial(A2:A7)");
// 在 B2:B7 中插入公式,计算 A 列中数字的阶乘。
sheet.getRange("B2:B7").setFormula2("Factorial(A2)");
sheet.getColumns().get(1).autoFit();
// 保存 Excel 文件。
workbook.save("LAMBDAFactorial.xlsx");输出结果如下图所示:

您可以从其他工作表甚至其他工作簿中引用在一个工作表中添加的定义名称。以下示例演示了在一个工作表上定义名称后,如何在另一个工作表的公式中引用该定义名称。
// 创建工作簿。
Workbook workbook = new Workbook();
IWorksheet sheet1 = workbook.getWorksheets().get(0);
// 添加定义名称 Test,其内容为 ABS。
sheet1.getNames().add("Test", "=ABS");
// 添加第二个工作表。
IWorksheet sheet2 = workbook.getWorksheets().add();
// 在 Sheet2 的 B2 单元格中设置公式,引用在 Sheet1 中添加的定义名称 Test。
sheet2.getRange("B2").setFormula2("=Sheet1!Test(-2)");
sheet2.getRange("B1").setFormula2("=FORMULATEXT(B2)");
sheet2.getRange("A1").setValue("公式文本:");
sheet2.getRange("A2").setValue("公式结果:");
sheet2.getColumns().get(1).autoFit();
sheet2.getColumns().get(0).autoFit();
sheet2.getRange("A1:A2").getFont().setBold(true);
// 保存 Excel 文件。
workbook.save("LAMBDACrossWorksheet.xlsx");输出结果如下图所示:

注意:如果定义的名称与 Excel 内置函数同名(例如
sheet.Names.Add("SUM", "ABS");),使用=Sheet1!SUM(-2)直接跨工作表引用会导致错误。在这种情况下,您需要使用双括号来显式引用定义的名称(例如=((Sheet1!SUM))(-2)),以避免与内置函数冲突。
LAMBDA 函数不仅可以命名并重用,还可以在公式中立即调用。您可以在单元格公式中定义一个 LAMBDA 函数,并立即用实际参数调用它,这样无需在“名称管理器”中预先定义函数,就能快速实现一次性的计算逻辑。在涉及复杂公式或嵌套计算的场景中,临时使用自定义函数可以增强计算的灵活性。
LAMBDA 立即调用的基本语法为:=LAMBDA(参数 1, 参数 2, ..., 计算过程)(参数值 1, 参数值 2, ...)。定义好 LAMBDA 函数后,只需在其后的括号中传递参数值,函数就会执行。例如,如果单元格公式设置为 =LAMBDA(x, x+1)(3),它会立即返回结果 4。
Eta 简化的 LAMBDA(Eta LAMBDA)是 LAMBDA 的一种语法简化形式。当一个 LAMBDA 函数仅用于直接传递参数时,可以省略 LAMBDA 声明,直接将函数名用作 BYROW、BYCOL、MAP、SCAN、MAKEARRAY、REDUCE、PIVOTBY 和 GROUPBY 等函数的参数。
例如,在引入 Eta LAMBDA 之前,将绝对值 LAMBDA 函数传递给 BYROW 函数需要写成 =BYROW(A1:A10, LAMBDA(a, ABS(a)))。支持 Eta LAMBDA 后,可以简化为 =BYROW(A1:A10, ABS)。
GcExcel Java 支持在定义的名称、LET 函数的 name_value 参数以及 LAMBDA 函数中使用 Eta LAMBDA。它还支持在公式中引用自定义函数。
以下示例演示了 Eta LAMBDA 与普通 LAMBDA 在语法上的区别。
// 创建工作簿。
Workbook workbook = new Workbook();
IWorksheet sheet1 = workbook.getActiveSheet();
sheet1.setName("BYROW");
sheet1.getRange("$B$2").setValue("Eta LAMBDA 与普通 LAMBDA 对比");
sheet1.getRange("$B$2").getFont().setBold(true);
ITable table1 = sheet1.getTables().add(sheet1.getRange("$B$5:$E$10"), true);
table1.convertToRange();
// 设置数据。
Object[][] sheet1rngB5E10 = new Object[][] {
{ "学生", "数学", "英语", "物理"},
{ "汤姆", 19.0, 23.0, 19.0},
{ "杰瑞", 21.0, 15.0, 18.0},
{ "马里奥", 19.0, 22.0, 22.0},
{ "路易吉", 17.0, 15.0, 23.0},
{ "盖伦", 16.0, 22.0, 24.0}
};
ITable table2 = sheet1.getTables().add(sheet1.getRange("G5:G10"), true);
table2.convertToRange();
ITable table3 = sheet1.getTables().add(sheet1.getRange("G13:G18"), true);
table3.convertToRange();
sheet1.getRange("$B$5:$E$10").setValue(sheet1rngB5E10);
// 将普通 LAMBDA 传递给 BYROW 函数。
sheet1.getRange("$G$4").setValue("普通 LAMBDA");
sheet1.getRange("$G$5").setFormula2("=FORMULATEXT(G6)");
sheet1.getRange("$G$5").getFont().setColor(Color.GetBlack());
sheet1.getRange("$G$5").getInterior().setColor(Color.GetWhite());
sheet1.getRange("$G$6").setFormula2("=BYROW(C6:E10,LAMBDA(row,SUM(row)))");
// 将 Eta LAMBDA 传递给 BYROW 函数。
sheet1.getRange("$G$12").setValue("Eta LAMBDA");
sheet1.getRange("$G$13").setFormula2("=FORMULATEXT(G14)");
sheet1.getRange("$G$13").getFont().setColor(Color.GetBlack());
sheet1.getRange("$G$13").getInterior().setColor(Color.GetWhite());
sheet1.getRange("$G$14").setFormula2("=BYROW(C6:E10,SUM)");
// 保存 Excel 文件。
workbook.save("EtaLambda.xlsx");输出结果如下图所示:

以下示例演示了如何通过定义的名称 AliasOfSUM 引用 SUM。
// 创建工作簿。
Workbook workbook = new Workbook();
IWorksheet sheet = workbook.getWorksheets().get(0);
sheet.getRange("A1").setValue(10);
sheet.getRange("A2").setValue(20);
sheet.getRange("A3").setValue(-5);
sheet.getRange("A4").setValue(0);
sheet.getRange("A5").setValue(20);
sheet.getRange("C4").setValue("公式文本:");
sheet.getRange("C5").setValue("公式结果:");
sheet.getRange("C4:C5").getFont().setBold(true);
sheet.getColumns().get(2).autoFit();
sheet.getRange("D5").getInterior().setColor(Color.GetYellow());
// 添加 FORMULATEXT 公式以在 D5 中显示公式文本。
sheet.getRange("D4").setFormula2("=FORMULATEXT(D5)");
// 添加定义名称 AliasOfSUM,其内容为 SUM。
workbook.getNames().add("AliasOfSUM", "=SUM");
// 在 D5 中使用定义名称 AliasOfSUM 作为公式,相当于计算 A1 到 A5 的总和。
sheet.getRange("D5").setFormula2("AliasOfSUM(A1:A5)");
// 保存 Excel 文件。
workbook.save("EtaLAMBDAasDefinedName.xlsx");输出结果如下图所示:

以下示例演示了如何将 SUM 作为参数传递给 LAMBDA 函数以对 A1:A5 区域求和。
// 创建工作簿。
Workbook workbook = new Workbook();
IWorksheet sheet = workbook.getWorksheets().get(0);
sheet.getRange("A1").setValue(10);
sheet.getRange("A2").setValue(20);
sheet.getRange("A3").setValue(-5);
sheet.getRange("A4").setValue(0);
sheet.getRange("A5").setValue(20);
sheet.getRange("C4").setValue("公式文本:");
sheet.getRange("C5").setValue("公式结果:");
sheet.getRange("C4:C5").getFont().setBold(true);
sheet.getColumns().get(2).autoFit();
sheet.getRange("D5").getInterior().setColor(Color.GetYellow());
// 在 D4 中添加 FORMULATEXT 公式以显示 D5 的公式文本。
sheet.getRange("D4").setFormula2("=FORMULATEXT(D5)");
// 定义一个 LAMBDA 函数,该函数接收 SUM 和 A1:A5 区域作为参数,
// 然后使用该 LAMBDA 函数通过 SUM(A1:A5) 对该区域求和。
sheet.getRange("D5").setFormula2("=LAMBDA(AliasOfSUM, range, AliasOfSUM(range))(SUM, A1:A5)");
// 保存 Excel 文件。
workbook.save("EtaLAMBDAasArguments.xlsx");输出结果如下图所示:

以下示例演示了将 SUM 用作 LET 函数的“name_value”参数来对 A1:A5 区域求和。
// 创建工作簿
Workbook workbook = new Workbook();
IWorksheet sheet = workbook.getWorksheets().get(0);
sheet.getRange("A1").setValue(10);
sheet.getRange("A2").setValue(20);
sheet.getRange("A3").setValue(-5);
sheet.getRange("A4").setValue(0);
sheet.getRange("A5").setValue(20);
sheet.getRange("C4").setValue("公式文本:");
sheet.getRange("C5").setValue("公式结果:");
sheet.getRange("C4:C5").getFont().setBold(true);
sheet.getColumns().get(2).autoFit();
sheet.getRange("D5").getInterior().setColor(Color.GetYellow());
// 添加 FORMULATEXT 公式以显示 D5 中的公式文本
sheet.getRange("D4").setFormula2("=FORMULATEXT(D5)");
// 将 SUM 作为 LET 函数的“name_value”参数传递,将其分配给变量 AliasOfSUM,
// 并使用 AliasOfSUM(A1:A5) 计算 A1 到 A5 的总和,这相当于
// “=LAMBDA(AliasOfSUM, range, AliasOfSUM(range))(SUM, A1:A5)”
sheet.getRange("D5").setFormula2("=LET(AliasOfSUM, SUM, AliasOfSUM(A1:A5))");
// 保存 Excel 文件
workbook.save("EtaLAMBDAforLET.xlsx");输出结果如下图所示:

以下示例演示了如何将自定义函数作为 Eta LAMBDA 参数传递给 MAP 函数。
public class IsNegativeFunction extends CustomFunction {
public IsNegativeFunction() {
super(
"ISNEGATIVE",
"如果值为负数,则返回 true",
FunctionValueType.Boolean,
new Parameter[] { new Parameter(FunctionValueType.Number) }
);
}
@Override
public Object evaluate(Object[] arguments, ICalcContext context) {
if (arguments != null && arguments.length > 0 && arguments[0] != null) {
try {
double value = Double.parseDouble(arguments[0].toString());
return value < 0;
} catch (Exception e) {
return false;
}
}
return false;
}
}// 创建工作簿
Workbook workbook = new Workbook();
IWorksheet sheet = workbook.getWorksheets().get(0);
workbook.AddCustomFunction(new IsNegativeFunction());
Object[][] values = new Object[][]{
{ 5, -3, 0 },
{ 23, -1, -4 },
{ -13, 0, -12 }
};
sheet.getRange("A2:C4").setValue(values);
sheet.getPageSetup().setPrintHeadings(true);
sheet.getPageSetup().setPrintGridlines(true);
sheet.getPageSetup().setOrientation(PageOrientation.Landscape);
sheet.getRange("A1").setValue("待检查是否为负值的数据:");
sheet.getRange("A11").setValue("公式文本(A7):");
sheet.getRange("A6").setValue("公式结果:");
sheet.getRange("A1").getFont().setBold(true);
sheet.getRange("A11").getFont().setBold(true);
sheet.getRange("A6").getFont().setBold(true);
sheet.getRange("A5:E5").merge();
sheet.getRange("A10:E10").merge();
// 添加 FORMULATEXT 公式以显示 A7 中的公式文本
sheet.getRange("C11").setFormula2("=FORMULATEXT(A7)");
// 将自定义函数 ISNEGATIVE 作为 Eta Lambda 函数传递给 MAP 函数
sheet.getRange("A7").setFormula2("=MAP(A2:C4, ISNEGATIVE)");
// 保存 Excel 文件
workbook.save("CustomFuncasEtaLAMBDA.pdf");输出结果如下图所示:

定义的名称可以与 Excel 内置函数同名(例如 workbook.Names.Add("SUM", "ABS");)。当发生此类名称冲突时:
内置函数的行为保持不变。例如,=SUM(-1) 仍会返回 -1。
如果 SUM 已被用作 Eta LAMBDA(例如 =BYROW(A1:A2, SUM)),然后又被定义为一个已定义名称(例如 workbook.Names.Add("SUM", "ABS");),则用作 Eta LAMBDA 的 SUM 将自动添加 _xleta. 前缀,即 =BYROW(A1:A2, _xleta.SUM)。
如果 SUM 已被定义为一个已定义名称,然后又被用作 Eta LAMBDA,则该 Eta LAMBDA 将被识别为已定义名称 SUM。此时,先定义的已定义名称优先于后出现的 Eta LAMBDA。
在 SUM 被添加为已定义名称后,如果要将 SUM 用作 Eta LAMBDA,则需要在 SUM 前加上 _xleta. 前缀(例如 =BYROW(A1:A2, _xleta.SUM))。
如果内置函数先在 Eta LAMBDA 中使用,然后被重新定义为已定义名称导致命名冲突,则 Eta LAMBDA 中对该内置函数的引用将自动添加 _xleta. 前缀,且 Eta LAMBDA 的计算结果保持不变。对于自定义函数,如果先在 Eta LAMBDA 中使用,之后又被定义为已定义名称,则 Eta LAMBDA 中的名称不会自动添加前缀,会直接被识别为已定义名称,这可能会改变公式的含义和计算结果。
LAMBDA 和 LET 函数本身不能用作 Eta LAMBDA,否则它们将被视为普通名称。
将单元格公式设置为 Eta LAMBDA(例如 =SUM)将返回 #CALC! 错误。
如果某个函数不支持将 LAMBDA 作为参数,但接收到了 Eta LAMBDA,则会返回 #VALUE! 错误。例如:=SUM(SUM)。