第07章-公式与计算引擎

第七章:公式与计算引擎

7.1 公式基础

7.1.1 公式概述

ReoGrid支持类似Excel的公式计算功能,可以使用内置函数和自定义函数。

using unvell.ReoGrid;

public class FormulaBasics
{
    private Worksheet sheet;
    
    /// <summary>
    /// 基本公式使用
    /// </summary>
    public void BasicFormulas()
    {
        // 简单算术
        sheet["A1"] = 10;
        sheet["A2"] = 20;
        sheet["A3"] = "=A1+A2";  // 结果: 30
        
        // 使用函数
        sheet["B1"] = "=SUM(A1:A2)";  // 结果: 30
        sheet["B2"] = "=AVERAGE(A1:A2)";  // 结果: 15
        sheet["B3"] = "=MAX(A1:A2)";  // 结果: 20
    }
}

7.1.2 公式语法

public class FormulaSyntax
{
    public void DemonstrateSyntax(Worksheet sheet)
    {
        // 单元格引用
        sheet["C1"] = "=A1";  // 相对引用
        sheet["C2"] = "=$A$1";  // 绝对引用
        sheet["C3"] = "=$A1";  // 混合引用(列绝对)
        sheet["C4"] = "=A$1";  // 混合引用(行绝对)
        
        // 区域引用
        sheet["D1"] = "=SUM(A1:A10)";  // 区域求和
        sheet["D2"] = "=AVERAGE(B:B)";  // 整列平均
        sheet["D3"] = "=MAX(1:1)";  // 整行最大值
        
        // 多区域
        sheet["E1"] = "=SUM(A1:A5,B1:B5)";  // 多个区域
    }
}

7.2 内置函数

7.2.1 数学函数

public class MathFunctions
{
    public void UseMathFunctions(Worksheet sheet)
    {
        // SUM - 求和
        sheet["A10"] = "=SUM(A1:A9)";
        
        // AVERAGE - 平均值
        sheet["B10"] = "=AVERAGE(B1:B9)";
        
        // MIN - 最小值
        sheet["C10"] = "=MIN(C1:C9)";
        
        // MAX - 最大值
        sheet["D10"] = "=MAX(D1:D9)";
        
        // COUNT - 计数
        sheet["E10"] = "=COUNT(E1:E9)";
        
        // ABS - 绝对值
        sheet["F1"] = "=ABS(-10)";  // 结果: 10
        
        // ROUND - 四舍五入
        sheet["G1"] = "=ROUND(3.14159, 2)";  // 结果: 3.14
        
        // POWER - 幂运算
        sheet["H1"] = "=POWER(2, 3)";  // 结果: 8
        
        // SQRT - 平方根
        sheet["I1"] = "=SQRT(16)";  // 结果: 4
    }
}

7.2.2 逻辑函数

public class LogicalFunctions
{
    public void UseLogicalFunctions(Worksheet sheet)
    {
        // IF - 条件判断
        sheet["A1"] = "=IF(B1>60, \"及格\", \"不及格\")";
        
        // AND - 与运算
        sheet["A2"] = "=AND(B2>0, B2<100)";
        
        // OR - 或运算
        sheet["A3"] = "=OR(B3<0, B3>100)";
        
        // NOT - 非运算
        sheet["A4"] = "=NOT(B4=0)";
        
        // 嵌套IF
        sheet["A5"] = "=IF(B5>=90, \"优秀\", IF(B5>=80, \"良好\", IF(B5>=60, \"及格\", \"不及格\")))";
    }
}

7.2.3 文本函数

public class TextFunctions
{
    public void UseTextFunctions(Worksheet sheet)
    {
        // CONCATENATE - 连接文本
        sheet["A1"] = "=CONCATENATE(B1, \" \", C1)";
        
        // LEFT - 左侧字符
        sheet["A2"] = "=LEFT(B2, 3)";
        
        // RIGHT - 右侧字符
        sheet["A3"] = "=RIGHT(B3, 3)";
        
        // MID - 中间字符
        sheet["A4"] = "=MID(B4, 2, 5)";
        
        // LEN - 长度
        sheet["A5"] = "=LEN(B5)";
        
        // UPPER - 大写
        sheet["A6"] = "=UPPER(B6)";
        
        // LOWER - 小写
        sheet["A7"] = "=LOWER(B7)";
    }
}

7.2.4 日期时间函数

public class DateTimeFunctions
{
    public void UseDateTimeFunctions(Worksheet sheet)
    {
        // NOW - 当前日期时间
        sheet["A1"] = "=NOW()";
        
        // TODAY - 今天日期
        sheet["A2"] = "=TODAY()";
        
        // YEAR - 年份
        sheet["A3"] = "=YEAR(B3)";
        
        // MONTH - 月份
        sheet["A4"] = "=MONTH(B4)";
        
        // DAY - 日
        sheet["A5"] = "=DAY(B5)";
        
        // DATE - 构造日期
        sheet["A6"] = "=DATE(2024, 12, 31)";
        
        // DATEDIF - 日期差
        sheet["A7"] = "=DATEDIF(B7, C7, \"d\")";  // 天数差
    }
}

7.3 自定义函数

7.3.1 创建自定义函数

using unvell.ReoGrid.Formula;

[CustomFunction]
public class MyCustomFunction : NamedFunction
{
    public override string Name => "MYCALC";
    
    public override object Invoke(object[] args)
    {
        if (args.Length < 2) return 0;
        
        double a = Convert.ToDouble(args[0]);
        double b = Convert.ToDouble(args[1]);
        
        return a * b + 10;
    }
}

// 注册使用
public class RegisterCustomFunction
{
    public void Register(ReoGridControl grid)
    {
        // 注册自定义函数
        grid.RegisterFunction(new MyCustomFunction());
        
        // 使用自定义函数
        var sheet = grid.CurrentWorksheet;
        sheet["A1"] = 5;
        sheet["A2"] = 3;
        sheet["A3"] = "=MYCALC(A1, A2)";  // 结果: 25
    }
}

7.3.2 多参数自定义函数

[CustomFunction]
public class WeightedAverage : NamedFunction
{
    public override string Name => "WAVG";
    
    public override object Invoke(object[] args)
    {
        if (args.Length % 2 != 0) return 0;
        
        double sum = 0;
        double weightSum = 0;
        
        for (int i = 0; i < args.Length; i += 2)
        {
            double value = Convert.ToDouble(args[i]);
            double weight = Convert.ToDouble(args[i + 1]);
            
            sum += value * weight;
            weightSum += weight;
        }
        
        return weightSum == 0 ? 0 : sum / weightSum;
    }
}

7.4 公式计算控制

7.4.1 自动计算设置

public class FormulaCalculation
{
    public void ConfigureCalculation(ReoGridControl grid)
    {
        // 启用自动计算
        grid.SetSettings(WorkbookSettings.Formula_AutoCalculate, true);
        
        // 禁用自动计算
        grid.SetSettings(WorkbookSettings.Formula_AutoCalculate, false);
    }
    
    /// <summary>
    /// 手动触发计算
    /// </summary>
    public void ManualCalculate(Worksheet sheet)
    {
        sheet.RecalculateAll();
    }
}

7.4.2 循环引用处理

public class CircularReference
{
    public void HandleCircular(Worksheet sheet)
    {
        // ReoGrid会自动检测循环引用
        // 循环引用会导致 #REF! 错误
        
        // 检查单元格是否有错误
        var cell = sheet.GetCell("A1");
        if (cell != null && cell.HasFormula)
        {
            // 检查计算错误
            if (cell.FormulaStatus == FormulaStatus.CircularReference)
            {
                Console.WriteLine("检测到循环引用");
            }
        }
    }
}

7.5 公式错误处理

7.5.1 常见公式错误

public class FormulaErrors
{
    public void HandleErrors(Worksheet sheet)
    {
        // #DIV/0! - 除以零
        sheet["A1"] = "=10/0";
        
        // #NAME? - 未识别的函数名
        sheet["A2"] = "=UNKNOWNFUNC()";
        
        // #REF! - 无效引用
        sheet["A3"] = "=A100000";
        
        // #VALUE! - 值错误
        sheet["A4"] = "=SUM(\"text\")";
        
        // #NUM! - 数字错误
        sheet["A5"] = "=SQRT(-1)";
    }
    
    /// <summary>
    /// 使用IFERROR处理错误
    /// </summary>
    public void UseIFERROR(Worksheet sheet)
    {
        sheet["B1"] = "=IFERROR(A1/B1, 0)";  // 如果出错返回0
        sheet["B2"] = "=IFERROR(A2, \"错误\")";  // 如果出错返回文本
    }
}

7.6 本章小结

本章介绍了ReoGrid的公式与计算引擎,包括内置函数的使用和自定义函数的创建。

📚 下一章预告

第八章将学习数据验证与条件格式,了解如何控制数据输入和动态格式化。


继续学习第八章:数据验证与条件格式!

posted @ 2025-12-31 14:07  我才是银古  阅读(6)  评论(0)    收藏  举报