Foxtable(狐表)用户栏目专家坐堂 → 有谁能做个字段间的计算关系由用户自定义公式的例子?


  共有45801人关注过本帖树形打印复制链接

主题:有谁能做个字段间的计算关系由用户自定义公式的例子?

帅哥哟,离线,有人找我吗?
cpayinyuan
  11楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信 一级勋章
等级:六尾狐 帖子:1412 积分:8937 威望:0 精华:0 注册:2008/9/1 8:57:00
  发帖心情 Post By:2009/3/31 12:53:00 [只看该作者]

   还是希望谁做个自定义公式的例子.

   总感觉在目前的狐表系统中做这个太复杂,一个表中,可能有几十个列都有自定义公式,虽然每个公式的结果都是影响一列,但可能有另外的很多列的变化都会导致这个结果列重算。
   例如,在工资软件中,若用户自定义:应发工资=基本工资+提成+补助+奖金+加班费,则基本工资、提成、补助、奖金、加班费中任一列发生变化,都要重算应发工资。如果是固定的公式用表事件很方便,右是自定义的公式,则需要判断每一个公式中都是由哪些列的变化影响的,感觉比较复杂。希望谁能提供一个好的思路。

 回到顶部
帅哥哟,离线,有人找我吗?
狐狸爸爸
  12楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:管理员 帖子:47448 积分:251048 威望:0 精华:91 注册:2008/6/17 17:14:00
  发帖心情 Post By:2009/3/31 12:59:00 [只看该作者]

你想得多了,你在往更复杂的路上走。
首先,你这样的计算,用表达式就行了,应发工资的表达式设为:

[基本工资]+[提成]+[补助]+[奖金]+[加班费]

还能比这更简单吗?

即使用代码,也没有多复杂,将应发工资改为数据列,DatacolChanged的代码为:

Dim dr  as DataRow = e.DataRow
Select Case e.Datacol.Name 
    Case "基本工资","提成","补助","奖金","加班费"
        dr("基本工资") = dr("基本工资")  + dr("提成") + dr("补助")  + dr("奖金") + dr("加班费")
End Select


即使你有几十个计算关系,也只是不停地Case下去即可,条理清楚得很:
 
Dim dr As DataRow = e.DataRow
Select Case e.DataCol.Name
    Case "A","B"
        dr("C") = dr("A") + dr("B")
    Case "D","E"
        dr("F") = dr("D") + dr("E")
End Select
[此贴子已经被作者于2009-3-31 13:05:14编辑过]

 回到顶部
帅哥哟,离线,有人找我吗?
mr725
  13楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信 一级勋章
等级:MVP荣誉狐 帖子:5154 积分:31434 威望:0 精华:8 注册:2008/9/8 12:27:00
  发帖心情 Post By:2009/3/31 13:03:00 [只看该作者]

如果用‘临时表’能动态的(或根据用户需求)增加列的话。。。。。  一种思路~ 见笑了~ 

 回到顶部
帅哥哟,离线,有人找我吗?
mr725
  14楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信 一级勋章
等级:MVP荣誉狐 帖子:5154 积分:31434 威望:0 精华:8 注册:2008/9/8 12:27:00
  发帖心情 Post By:2009/3/31 13:13:00 [只看该作者]

以下是引用狐狸爸爸在2009-3-31 12:59:00的发言:
你想得多了,你在往更复杂的路上走。
首先,你这样的计算,用表达式就行了,应发工资的表达式设为:
[基本工资]+[提成]+[补助]+[奖金]+[加班费]
还能比这更简单吗?....................................
我想,楼主不是简单的需要 [基本工资]+[提成]+[补助]+[奖金]+[加班费] 。而是[基本工资]+[提成]+[补助]+[奖金]+[加班费]+[x]+[y]+[z]..........所有[ ]都是可选的吧?~ 未选中的不参与计算。。。。

[此贴子已经被作者于2009-3-31 13:14:52编辑过]

 回到顶部
帅哥哟,离线,有人找我吗?
cpayinyuan
  15楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信 一级勋章
等级:六尾狐 帖子:1412 积分:8937 威望:0 精华:0 注册:2008/9/1 8:57:00
  发帖心情 Post By:2009/3/31 13:46:00 [只看该作者]

以下是引用狐狸爸爸在2009-3-31 12:59:00的发言:
你想得多了,你在往更复杂的路上走。
首先,你这样的计算,用表达式就行了,应发工资的表达式设为:

[基本工资]+[提成]+[补助]+[奖金]+[加班费]

还能比这更简单吗?

即使用代码,也没有多复杂,将应发工资改为数据列,DatacolChanged的代码为:

    可能是我没有把意思表达清楚,让贺老师误解了。
     在上面的例子中,如果已知应发工资等于什么,就不叫自定义公式了。经过这么多天的学习和大家的帮助,这个代码我可以不费劲的写出来。
    在实际中,这个公式是最终用户自定义的,在设计项目的时候并不是已知的。它的复杂性在于:
1、不知道应发工资等于什么,即不知道影响应发工资的有哪几列,可能是4个列,也可能是8列。也就是在DatacolChanged的代码中,不知道让e.Datacol.Name 等于什么。究竟有哪些列,需要系统根所用户自定义的这个公式地行解析、判断。
2、应发工资的公式并不一定只有加减乘除,如果只有加减乘除,要简单得多。可能有括号,甚至还有IIF函数或者其他函数。不是用表达式列就可以解决的。
3、在一个工资表中,并不是只有应发工资列的公式是自定义的。而是,可能有许多列的公式都是自定义的,需要对每个列的公式进行解析、判断。这里面可能还涉及到一个列顺序的问题,在实际的系统中,列顺序也允许最终用户进行调整,这可能会对公式的计算产生一定的影响。

不知我说明白了没有,还是希望贺老师或者其他老师提供一个好的事例,或者思路。

[此贴子已经被作者于2009-3-31 13:48:07编辑过]

 回到顶部
帅哥哟,离线,有人找我吗?
mr725
  16楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信 一级勋章
等级:MVP荣誉狐 帖子:5154 积分:31434 威望:0 精华:8 注册:2008/9/8 12:27:00
  发帖心情 Post By:2009/3/31 14:05:00 [只看该作者]

以下是引用cpayinyuan在2009-3-31 13:46:00的发言:

    可能是我没有把意思表达清楚,让贺老师误解了。
   如果已知应发工资等于什么,就不叫自定义公式了。经过这么多天的学习和大家的帮助,这个代码我可以不费劲的写出来。
    在实际中,这个公式是最终用户自定义的,并不是已知的。它的复杂性有:
1、不知道应发工资等于什么,即不知道影响应发工资的有哪几列,可能是4个列,也可能是8列。也就是在DatacolChanged的代码中,不知道让e.Datacol.Name 等于什么。究竟有哪些列,需要系统根所用户自定义的这个公式地行解析、判断。
2、应发工资的公式并不一定只有加减乘除,如果只有加减乘除,要简单得多。可能有括号,甚至还有IIF函数。不是用表达式列就可以解决的。
3、在一个工资表中,并不是只有应发工资列的公式是自定义的。而是,而是可能有许多列的公式都是自定义的,需要对每个列的公式进行解析、判断。这里面可能还涉及到一个计算顺序的问题。

不知我说明白了没有,还是希望贺老师或者其他老师提供一个好的事例,或者思路。

第3条不好理解? 如果我理解的没错的话,应该要建一个工资项目列表,对每个项目用另一列来做公式,每个公式用替换的方法来解决自定义的问题,不知思路可行???


 回到顶部
帅哥哟,离线,有人找我吗?
czy
  17楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信 一级勋章 三级勋章 二级勋章
等级:超级版主 帖子:6318 积分:33945 威望:0 精华:10 注册:2008/8/31 20:56:00
  发帖心情 Post By:2009/3/31 14:09:00 [只看该作者]

看楼上说的有些复杂。

建议还是楼主建个示例文件,让大家一起来想想办法。

 回到顶部
帅哥哟,离线,有人找我吗?
cpayinyuan
  18楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信 一级勋章
等级:六尾狐 帖子:1412 积分:8937 威望:0 精华:0 注册:2008/9/1 8:57:00
  发帖心情 Post By:2009/3/31 14:18:00 [只看该作者]

以下是引用czy在2009-3-31 14:09:00的发言:
看楼上说的有些复杂。

建议还是楼主建个示例文件,让大家一起来想想办法。

   因为我只知道最终的结果是什么样子,如何实现没有很好的思路,所以不好建示例文件。如果一定要建一个示例文件,那我只能建一个没有任何公式、没有任何事件的表了。因为列之间所有的公式都是最终用户自定义的,现在不知道最终用户要为哪一列定义公式,定义什么样的公式,所以DatacloChanged事件我不太清楚该怎样写。
   如果版主想要研究这个事,可以随便找一个主流的工资软件(例如用友),一看就知道是怎么回事了。


 回到顶部
帅哥哟,离线,有人找我吗?
程兴刚
  19楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信 一级勋章
等级:超级版主 帖子:7235 积分:40550 威望:0 精华:16 注册:2008/8/31 23:23:00
  发帖心情 Post By:2009/3/31 14:37:00 [只看该作者]

贴上这段代码,只希望大家对狐表多一份了解和爱戴,尽量避免过早定论,多一分努力和实践,灵活运用,狐表能做的东西,绝大部分功能都已经能够实现了,其实我也很菜,希望大家多指教,并对我的代码给予精简为盼:

Tables("明细数据").Current("钢筋代码") = Vars("钢筋代码")
Dim dr As DataRow = DataTables("计算规则").Find("[钢筋代码]= '" &  Vars("钢筋代码") & "'")
Tables("明细数据").Current("下料长度计算规则") = dr("下料长度计算规则")
dim r as row = Tables("明细数据").Current
Dim Multi As String = "A|B|C|D|E|F|G|H|JD1|JD2"
Dim Values() as String
Values = Multi.split("|")
For Index As Integer = 0 To Values.Length - 1
   if e.Form.ExistControl(Values(Index))  = true
         if e.Form.Controls(Values(Index)).Value = nothing
            MessageBox.Show("对不起,您输入的参数不全,请为本钢筋录入" & Values(Index) & "参数后再提料!", "提示")
            Return
         else
            Tables("明细数据").Current(Values(Index)) = e.Form.Controls(Values(Index)).Value
         end if
   else
       Tables("明细数据").Current(Values(Index)) = nothing
   end if
Next
Multi = "施工部位|构件名称|钢筋编号|钢号|直径|间距|构件根数|构件数"
Values = Multi.split("|")
For Index As Integer = 0 To Values.Length - 1
    if e.Form.Controls(Values(Index)).Value = nothing
       MessageBox.Show("您还没有输入" & Values(Index) & ",请您先输入" & Values(Index) & "再提料!", "提示")
       Return
    else
       Tables("明细数据").Current(Values(Index)) = e.Form.Controls(Values(Index)).Value
    end if
Next
r("下料长度计算式") = r("下料长度计算规则").Replace("直径",r("直径")).Replace("A",r("A")).Replace("B",r("B")).Replace("C",r("C")).Replace("D",r("D")).Replace("E",r("E")).Replace("F",r("F")).Replace("G",r("G")).Replace("H",r("H")).Replace("JD1",r("JD1")).Replace("JD2",r("JD2"))
r("总根数") = Eval(r("构件根数") & "*" & r("构件数"),r)
r("下料长度") = Eval(r("下料长度计算式"),r)
r("总长度") = Eval("(" & r("下料长度计算式") & ")*" & r("总根数") & "/1000",r)
r("总重量") = Eval(Math.Round(0.617*r("直径")*r("直径")/100,3) & "*(" & r("下料长度计算式") & ")*" & r("总根数") & "/1000",r)


     下料长度计算规则来自于计算规则表,A|B|C|D|E|F|G|H|JD1|JD2均为列名称,下料长度计算式根据下料长度计算规则列,替换对应的A|B|C|D|E|F|G|H|JD1|JD2列,再利用eval并参与与其他列的计算。
      可以只用定义任意复杂公式,比如:
        简单点的:A+B+C+D+2*6.25*直径+3.14*(E*2)/4-7*直径
        复杂一点的:A+Math.Sqrt((B-2*直径)* (B-2*直径)+ (C/2-50)*(C/2-50)) * 4 + 2*C      平方值的表达式暂时还没改过来,这里显得有点笨。

      
   优点,可由管理员用户灵活定制各列直接的计算关系(我这里叫计算规则,可以制定1~N个任意规则,支持函数),用户在操作中,根据不同的条件任意调用,得出计算结果,
         本系统是我以前的易表设计的商业版行业系统改版,程序我就不贴上来了,下面贴上改系统的主表界面,对照代码即可看出规律:

        
图片点击可在新窗口打开查看此主题相关图片如下:系统界面.jpg
图片点击可在新窗口打开查看


 回到顶部
帅哥哟,离线,有人找我吗?
狐狸爸爸
  20楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:管理员 帖子:47448 积分:251048 威望:0 精华:91 注册:2008/6/17 17:14:00
  发帖心情 Post By:2009/3/31 14:46:00 [只看该作者]

就用Eval函数,目前不支持流程语句,使用很简单,没有必要提供例子了。
下次更新后,支持流程语句,再考虑提供例子。

 回到顶部
总数 67 上一页 1 2 3 4 5 6 7 下一页