Posted on 2007-10-24 18:46
随心所欲 阅读(15859)
评论(25) 编辑 收藏
以前还真没想到DataTable.Compute
具有这么多的功能
1:聚合函数”Sum()”
2:自由计算表达式“20*30+1”
3:bool表达式“1=2”
4:IFF逻辑表达式” IIF(20>1000, 0, 1)” //还支持IsNull,Trim,SubString等
一个小应用:让DataTable模拟Excel的Formula功能。
Excel中的Formula功能强大,如果能让DataTable有类似的功能就好了。大部分事件DataTable只是用作数据载体,其实很少用它做计算。DataTable提供的函数Compute就提供了功能强大的计算功能。
Compute函数的参数就两个:Expression,和Filter。
Expresstion是计算表达式,关于Expression的详细内容请看这里“http://msdn2.microsoft.com/zh-cn/library/system.data.datacolumn.expression(VS.80).aspx”。而Filter则是条件过滤器,类似sql的Where条件。
1: 这里详细介绍的就是Expresstion。
先看最简单的用法,使用聚合函数。这个聚合函数就是报表或者Excel中常用的函数,比如Sum,Avg等等。对于数据列,Datatable可以方便的进行计算,比如DataTable.Cumpute(“Sum(列1)”,”列1>0”); 对于简单的统计功能,这些函数就足够用了。(其他提供的函数有min,max,count,求方差,标准偏差等等)。这个功能常用,倒也不奇怪。
再看“自由表达式”计算。把数学计算表达式写成字符串,然后直接投入Compute函数计算,就可以得到计算结果。这样,动态生成的计算表达式就可以计算出来了。比方说要计算“列1×30+20+2”或者是纯粹的数学计算。
出了计算出具体的结果,Compute函数还能进行逻辑计算。比方说这个表达式就能返回false:Compute(“1=2”,”true”); 这个的用法可能想上边的情形差不多,在自由组装一些条件的时候可以得到结果。
在Excel中,还经常用到的就是LogicTest功能了,可以指定一些逻辑表达式,比如这样的:“IF(20>1000, 0, 1)”。而这个功能要是放到DataTable中该如何实现呢?也是用Compute,这样写就可以了:“IIF(20>1000, 0, 1)”。
在DataTable里面如果实现“IF(C102=0,0,C105/C102*30)”就用上边的这些技术点就可以了。
2:至于第二个参数Filter,就是一个简单的查询条件。比如,”true”, “Id>4”, “Name like ’%nd’ and sex=’male’”.
条件不可能很复杂,这些已经比较够用了。
以前用过的Marge什么的也不错,还可以作内连接,在数据量小,需要简单计算的情况下,这些功能很有用。
当然,如果逻辑极其复杂,DT的这点功能就不够了,还是得自己写逻辑(即使要实现“IF(C102=0,0,C105/C102*30)”,也是要自己写一点处理逻辑的,不过比较通用,写一次就好了)。
通过Compute方法加上行列条件定义,可以实现一个方便易用且通用动态的统计引擎。
@怀念家驹
不错.
我就是用这个功能来模拟Excel公式计算.相当成功.
所以俺才觉得DT的这个不起眼的函数这么令人惊喜
--引用--------------------------------------------------
随心所欲: @怀念家驹
不错.
我就是用这个功能来模拟Excel公式计算.相当成功.
所以俺才觉得DT的这个不起眼的函数这么令人惊喜
--------------------------------------------------------
我的做法是这样的,产生一张统计条件定义表。
含统计数据的行放置类似“ORGCODE = '1000'(条件)”这样的条件。
含统计数据的列放置类似“[SUM(MALCOUNT((数据源列名))):MALSTATCOUNT(数据源表名):CATCODE = '01'(条件)]”这样的条件,然后行列交叉循环,从计算数据源产生的DataTable中取数生成统计表。目前除了交叉表,列固定的统计都能实现。
不知阁下有何更好的办法实现统计。
有好想法可以交流一下,EMAIL:boyxia@tom.com
很不错 就喜欢这样平时一直被大家用却不怎么发现的DD
@怀念家驹
我专门写了一个类,用来解析自己写的条件.
比如,我这样写:
IF({0}=0,0,{1}/{2}*30); C1='xxx';C2='ccc';c3='xxx'
自己处理类似的公式.只要split后边的条件,分别计算出来,然后在给根据Iff的表达式再做一次计算就好了.
这个配置比较通用,所以处理也很通用.
@赤裸小绵羊
@Clark Zheng
手误,已修改.谢谢指出.
@kevin_198111111
对,这就叫"惊喜".
下次写一个WebBrowser的惊喜应用.也是不错.
这玩意一直就有。只能说明你不喜欢看MSDN。
如果统计用这个玩意是不是效率有点那个?数据量大一点就会撑不住地。
@Kain
不好意思,从没看过MSDN.
总是在需要的时候再查什么样的技术.
做简单统计.如果复杂统计不会用这个.
呵呵,用了DataTable这么久了,现在才知有这个方法可用.
而且新项目要用到这个功能,到时还可多多向博主学习!
一个字,强!
只能说明楼主不爱请看MSDN
跟许多初学者一样 遇到问题还不知道到哪儿以及怎样找到解决的办法
嘿嘿,感谢楼主。正好 要写一个 DataTable的合计出来,现在不用傻傻的用循环累加了。。。。。。。
我就感觉有这样的功能嘛``````
不行 忍不住拉~~~ 我也要在我的里面发表这个功能说明。
呵呵,终于写完这个公式解释器了!
先来一点简单的测试用例:
OR(J134<=0,F134='',J42='',F42='')
OR(J134<=0,F134='',J42='',SUM(F1:F2,5)='')
and(J134<=0,F134='',J42='',SUM(F1:F2,5)='')
OR(J134<=0,F134='',J42='',F42='',IIF(2>3,2+3,2-3)=125)
OR(J134<=0,F134='',J42='',F42='',IIF(2>3,2+3,2-3)=125,AND(1>3,2<5)=FALSE)
OR(J134<=0,F134='',J42='',F42='',IIF(2>3,2+3,2-3)=125,AND(1>3,2<5)=FALSE,NOT(FALSE)=TRUE)
SUM(N85:N89,N100:N101)
SUM(N85:N89,N100:N101,SUM(1,2))
sum(,sum(2+3))
sum(1+3)
sum((1+2),(f3+f4))
sum(sum(1+2),sum(f3+f4))
再来一点复杂点的:
sum((1+2),(f3+f4))
sum((2+3),sum(F2+4))
SUM(85:89,LF(N100):LF(N111))
SUM(85:89,LF(SUM(N100:N150)):LF(N111))
以上四个看似简单,其实复杂,主要是参数解释问题和自定义函数 LF() 的实现.
个人觉得,如果公式解释得好,真的可以完全实现excel的公式部分功能!
文章收藏..
因为做统计的时候忽然发现这么一个东西,有点惊艳的感觉