kbnet.toolkit.formulas
前言
2024年3月份马上就要结束,困扰我近2个月的感冒总算要痊愈了,为此特别发布本篇文章以示安慰。
kbnet.toolkit.formulas是一个.net/c#类库,提供类似Excel一样的公式用于计算数据,当然没有excel公式那么多、那么全,但是应该足够使用了。
用它来做什么?难道用它来自己实现一个excel软件么?如果有此需求是可以的,其实我设计实现它的主要目的是为了数据检查和消息预警,尤其是物联网场景。下位机采集各个传感器的数据,然后提交到服务器,此时接收到数据的服务器第一步应该做什么,也许是存起来,好吧,除此之外,是不是应该根据传感器的数值做判断,从而验证传感器现场的环境状态,比如温度、压力、流速、风力等等,然后对超出数值范围的传感器发出消息预警,使得运维人员即时了解情况,从而避免各类生产事故的发生。
当然,你可能会说用其他办法一样可以实现,为什么要用kbnet.toolkit.formulas这个类库,比如sql数据库、时序数据库、或者让程序员写个程序,没错,实现类似需求的方式方案有多种,只是我想说相比较于其他方案,使用这个类库也有好处的,第一它不会给sql数据库造成巨大的检索压力,第二它可以任意配置正确的公式,不仅可以检测一个点的数据,还可以几个点同时作为条件运算,第三它不需要程序员等技术人员参与,只要是会编写excel公式的工作人员,就能设置和使用,更加不需要算法工程师瞎捣鼓算法,那么你现在认识到它的价值了么?也许你还会发现其他更多好处。
废话不多说了,直接上类库地址:
https://www.alipan.com/s/bZmX8KkdpV9
提取码: 2b4w
.net4x:表示.net framework 4.8.1
.net6:表示.net 6
.net8:表示.net 8
测试代码
1 public static void Test() 2 { 3 Formula.Init(); 4 5 var dList = new List<DataModel>(); 6 7 Console.WriteLine("1.程序支持的运算符与函数:"); 8 Console.WriteLine("1.1.基础函数"); 9 Console.WriteLine("1.1.1.算术运算符:+、-、*、/、%"); 10 Console.WriteLine(" 1)加法:+、Add(参数1,参数2),如 1+1=2 或 Add(1,1)=2"); 11 Console.WriteLine(" 2)减法:-、Sub(被减数,减数),如 2-1=1 或 Sub(2,1)=1"); 12 Console.WriteLine(" 3)乘法:*、Mul(参数1,参数2),如 2*3=6 或 Mul(2,3)=6"); 13 Console.WriteLine(" 4)除法:/、Div(被除数,除数),如 6/2=3 或 Div(6,2)=3"); 14 Console.WriteLine(" 5)取余:%、Mod(被除数,除数),如 7%3=1 或 Mod(7,3)=1"); 15 Console.WriteLine("1.1.2.比较运算符:=、!=、<>、>、>=、<、<="); 16 Console.WriteLine(" 1)等于:=、Equals(参数1,参数2),如 1=1 或 Equals(1,1)"); 17 Console.WriteLine(" 2)不等于:!=、<>、NotEquals(参数1,参数2),如 1!=1 或 1<>1 或 NotEquals(1,1)"); 18 Console.WriteLine(" 3)大于:>、Greater(参数1,参数2),如 1>1 或 Greater(1,1)"); 19 Console.WriteLine(" 4)大于等于:>=、NotLess(参数1,参数2),如 1>=1 或 NotLess(1,1)"); 20 Console.WriteLine(" 5)小于:<、Less(参数1,参数2),如 1<1 或 Less(1,1)"); 21 Console.WriteLine(" 6)小于等于:<=、NotGreater(参数1,参数2),如 1<=1 或 NotGreater(1,1)"); 22 Console.WriteLine("1.1.3.逻辑运算符:^、&&、||、!"); 23 Console.WriteLine(" 1)异或:^、Xor,如 1^1=0,1^0=1,Xor(1,0)=1"); 24 Console.WriteLine(" 2)并且:&&、And(条件1,条件2),如 ({\"S\":\"Test\",\"C\":\"C1\",\"R\":\"R1\"}>80)&&({\"S\":\"Test\",\"C\":\"C1\",\"R\":\"R1\"}<120)"); 25 Console.WriteLine(" 3)或者:||、Or(条件1,条件2),如 ({\"S\":\"Test\",\"C\":\"C1\",\"R\":\"R1\"}>80)||(({\"S\":\"Test\",\"C\":\"C1\",\"R\":\"R1\"}+30)<120)"); 26 Console.WriteLine(" 4)非:!、Not(条件),如 !({\"S\":\"Test\",\"C\":\"C1\",\"R\":\"R1\"}>80) 或 Not({\"S\":\"Test\",\"C\":\"C1\",\"R\":\"R1\"}>80)"); 27 Console.WriteLine("1.2.统计函数:Max, MaxIf, Min, MinIf, Sum, SumIf, Count, CountIf, Avg, AvgIf"); 28 Console.WriteLine(" 1)取最大值:Max(表格列),如 Max({\"S\":\"Test\",\"C\":\"C1\"})"); 29 Console.WriteLine(" 2)按条件取最大值:MaxIf(条件,表格列),如 MaxIf({\"FC\":\"CV\"}>100,{\"S\":\"Test\",\"C\":\"C1\"}"); 30 Console.WriteLine(" 3)取最小值:Min(表格列),如 Min({\"S\":\"Test\",\"C\":\"C1\"})"); 31 Console.WriteLine(" 4)按条件取最小值:MinIf(条件,表格列),如 MinIf({\"FC\":\"CV\"}<100,{\"S\":\"Test\",\"C\":\"C1\"}"); 32 Console.WriteLine(" 5)求和:Sum(表格列),如 Sum({\"S\":\"Test\",\"C\":\"C1\"})"); 33 Console.WriteLine(" 6)按条件求和:SumIf(条件,表格列),如 SumIf({\"FC\":\"CV\"}>100,{\"S\":\"Test\",\"C\":\"C1\"}"); 34 Console.WriteLine(" 7)求数量:Count(表格列),如 Count({\"S\":\"Test\",\"C\":\"C1\"})"); 35 Console.WriteLine(" 8)按条件求数量:CountIf(条件,表格列),如 CountIf({\"FC\":\"CV\"}>100,{\"S\":\"Test\",\"C\":\"C1\"}"); 36 Console.WriteLine(" 9)求平均数:Avg(表格列),如 Avg({\"S\":\"Test\",\"C\":\"C1\"})"); 37 Console.WriteLine(" 10)按条件求平均数:AvgIf(条件,表格列),如 AvgIf({\"FC\":\"CV\"}>100,{\"S\":\"Test\",\"C\":\"C1\"}"); 38 Console.WriteLine("1.3.时间函数:GetDate, DateTimeAdd, DateTimeFormat"); 39 Console.WriteLine(" 1)获取当前时间:GetDate(),如 GetDate()"); 40 Console.WriteLine(" 2)获取当前时间:GetDateF(格式字符串),如 GetDateF('yyyy-MM-dd HH:mm:ss')"); 41 Console.WriteLine(" 3)修改时间:DateTimeAdd(时间,YYYY|MM|DD|HH|mm|ss,数值),如 DateTimeAdd(GetDate(),DD,-1)"); 42 Console.WriteLine(" 4)格式化时间:DateTimeFormat(时间,格式字符串),如 DateTimeFormat(GetDate(),'yyyy-MM-dd HH:mm:ss')"); 43 Console.WriteLine("1.4.其他函数:Abs, Round"); 44 Console.WriteLine(" 1)绝对值:Abs(数值),如 Abs(-1)"); 45 Console.WriteLine(" 2)取整数,小数的第一位四舍五入:Round(数值),如 Round(1.567)=2"); 46 Console.WriteLine(""); 47 Console.WriteLine("2.表格操作说明:"); 48 Console.WriteLine(" 1)SheetName=Sheet=S,表示表格名称。"); 49 Console.WriteLine(" 2)ColumnName=Column=C,表示表格的列名称。"); 50 Console.WriteLine(" 3)RowName=Row=R,表示表格的行名称。"); 51 Console.WriteLine(" 4)FlagCode=FC,表示占位符,仅用于条件式函数使用,如{\"FC\":\"CV\"},计算时CV会被CellValue值替换,RT会被RecordTime值替换。"); 52 Console.WriteLine("\r\n\r\n"); 53 54 Console.WriteLine("以下内容是在测试随机数据和定义的公式是否正确运行。"); 55 Random rd = new Random(); 56 int testCount = 0; 57 while (true) 58 { 59 testCount++; 60 dList.Clear(); 61 62 Console.WriteLine("**************************************"); 63 var colmunNo = 2; 64 var rowNo = 5; 65 for (int column = 0; column < colmunNo; column++) 66 { 67 for (int row = 0; row < rowNo; row++) 68 { 69 dList.Add(new DataModel { SheetName = "Test", ColumnName = "Test" + (column + 1).ToString(), RowName = (row + 1).ToString(), CellValue = rd.Next(200), RecordTime = DateTime.Now }); 70 } 71 } 72 foreach (var item in dList) 73 { 74 Console.WriteLine($"SheetName:{item.SheetName},ColumnName:{item.ColumnName},RowName:{item.RowName},CellValue:{item.CellValue},RecordTime:{item.RecordTime}"); 75 } 76 var expression = "({\"S\":\"Test\",\"C\":\"Test1\",\"R\":\"1\"}>0)&&({\"S\":\"Test\",\"C\":\"Test2\",\"R\":\"2\"}<50)"; 77 Console.WriteLine($"公式:{expression}"); 78 var f = Formula.Parse(expression); 79 var r = f.Compute(dList); 80 if (r != null) 81 { 82 Console.WriteLine($"第 {testCount} 次,测试结果:" + r.Result.ToString()); 83 } 84 85 Console.WriteLine("**************************************"); 86 Console.WriteLine("是否继续测试?(y/n)"); 87 var ckey = Console.ReadLine(); 88 if (ckey.ToLower() != "y") 89 { 90 break; 91 } 92 } 93 94 Console.WriteLine(""); 95 Console.WriteLine("**************************************"); 96 Console.WriteLine("是否想继续测试数学运算?比如想计算表达式 \"(-1*(1+2+3+4+5)/2*-1+0.5)%3\" 的运算结果,如果想知道请输入计算公式:"); 97 testCount = 0; 98 while (true) 99 { 100 testCount++; 101 102 var cFunc = Console.ReadLine();//"1+1+(10/2*5-10)-50"; 103 if (!string.IsNullOrEmpty(cFunc) && !string.IsNullOrWhiteSpace(cFunc)) 104 { 105 var f = Formula.Parse(cFunc); 106 var r = f.Compute(dList); 107 if (r != null) 108 { 109 Console.WriteLine($"第 {testCount} 次,测试结果:" + r.Result.ToString()); 110 } 111 Console.WriteLine("#######################################"); 112 Console.WriteLine("是否继续测试?(y/n)"); 113 var ckey = Console.ReadLine(); 114 if (ckey.ToLower() != "y") 115 { 116 break; 117 } 118 else 119 { 120 Console.WriteLine("请输入公式:"); 121 } 122 } 123 else 124 { 125 Console.WriteLine("您输入的公式有误,请输入正确的公式"); 126 } 127 } 128 129 130 Console.WriteLine(""); 131 Console.WriteLine("感谢使用程序,功能运行结束,按任意键退出..."); 132 Console.ReadLine(); 133 }
总结
一直以来都在研究架构和平台方面的技术,这是第一篇功能类库的文章,希望可以对您有助。
1.类库于2024-04-09日更新,增加函数Round,Max,MaxIf,Min,MinIf,Sum,SumIf,Count,CountIf,Avg,AvgIf;GetDate,GetDateF,DateTimeFormat,DateTimeAdd等。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
2019-04-09 【以前技术归档】分布式架构(八卦篇)