Foxtable(狐表)用户栏目专家坐堂 → 流水账设计的详细介绍


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

主题:流水账设计的详细介绍

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


加好友 发短信
等级:管理员 帖子:47449 积分:251065 威望:0 精华:91 注册:2008/6/17 17:14:00
流水账设计的详细介绍  发帖心情 Post By:2009/5/11 16:03:00 [显示全部帖子]

 

关于流水账

本示例可以参考CaseStudy目录下的文件:流水账.Table

假定有下面一个简单的流水帐式的表格,输入收入和支出,能够自动计算出余额。



此主题相关图片如下:1030.gif
按此在新窗口浏览图片


实现的代码不复杂,只需将DataColChanged事件设为:


Select
Case e.DataCol.Name
    Case
"日期","收入",
"支出"
   
If e.DataRow.Isnull("日期") = False Then
        For Each dr As DataRow In e.DataTable.Select("[日期] >= #" & e.DataRow("日期") & "#")
            Dim
Val1 As Double = e.DataTable.compute("Sum(收入)","[日期] <= #" & dr("日期") & "#"
)
            Dim
Val2 As Double = e.DataTable.compute("Sum(支出)","[日期] <= #" & dr("日期") & "#"
)
            dr(
"余额") = Val1 - Val2
        Next
   
End If
End
Select


这样输入某一天的收入和支出,自该天开始的所有日期的余额,即可自动计算得出。
 

假如一天会有多次收入和支出,而且都作为单独的一行输入,那么用上述的代码计算得出的余额会有一些问题,因为上面的代码是比较日期的,这样同一日期的所有行,其余额都是相同的,显然这不符合我们的习惯,为此,我们可以将DataColChanged事件的代码改为:


Select
Case e.DataCol.Name
    Case
"日期","收入","支出"
   
If e.DataRow.Isnull("日期") = False Then
        For
Each dr As DataRow In e.DataTable.Select("[_Identify] >= " & e.DataRow("_Identify"))
            Dim
Val1 As Double = e.DataTable.Compute("Sum(收入)","[_Identify] <= " & dr("_Identify"))
            Dim
Val2 As Double = e.DataTable.Compute("Sum(支出)","[_Identify] <= " & dr("_Identify"))
            dr(
"余额") = Val1 - Val2
        Next
    End
If
End
Select


我们知道_Identify列的值,每增加一行都会自动加1,所以其值代表着行的输入顺序,这样即使同一天输入多行数据,上面的代码也能正确计算出每一行的余额。

代码似乎已经很完美了,其实不然;因为上面的代码没有比较日期,只是比较输入顺序,所以你必须严格按照日期顺序输入数据,如果你输入完今天的收入和支出后,突然发现昨天漏输了一笔支出,那么麻烦来了,从这一笔开始,你再也没有办法得到正确的余额了,除非你删除今天的数据,输入这笔昨天的支出后,再重新输入今天的数据,显然,这是很“无理”的要求。

要解决上述问题,需要同时比较日期和输入顺序(_Identify),所以DataColChanged事件改为:


Select
Case e.DataCol.Name
    Case
"日期","收入",
"支出"
       
If e.DataRow.IsNull("日期") = False Then
       
    Dim drs As List(of DataRow)
            drs = e.DataTable.Select("[日期] >= #" & e.DataRow("日期") & "#","日期")
            For
Each dr As DataRow In drs
                Dim
Filter As String = "[日期] < #" & dr("日期") & "# Or ([日期] = #" & dr("日期") & "# And [_Identify] <= " & dr("_Identify") &
")"
           
    Dim Val1 As Double = e.DataTable.Compute("Sum(收入)",Filter)
                Dim
Val2 As Double = e.DataTable.Compute("Sum(支出)",Filter)
                dr(
"余额") = Val1 - Val2
            Next
       
End If
End
Select


现在的代码已经完美了,具备了实用的价值,唯一的缺点是_Identify是自动生成,对于日期相同的行,只能根据输入顺序计算,不过这对于实际的应用并没有多大的影响。
如果你很在意这个,你可以自己假如一个编号列,自己输入编号,这样就可以自行调整计算顺序,代码请自行编写,就当是一个小练习吧。

 下载信息  [文件大小:   下载次数: ]
点击浏览该文件:管理项目7.table


[本帖被加为精华]
 回到顶部
帅哥哟,离线,有人找我吗?
狐狸爸爸
  2楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:管理员 帖子:47449 积分:251065 威望:0 精华:91 注册:2008/6/17 17:14:00
  发帖心情 Post By:2009/5/11 16:25:00 [显示全部帖子]

一样的设计啊,只需在条件表达式中,加入名称的比较,也就是相同名称的就行了。

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


加好友 发短信
等级:管理员 帖子:47449 积分:251065 威望:0 精华:91 注册:2008/6/17 17:14:00
  发帖心情 Post By:2009/5/11 16:48:00 [显示全部帖子]

这个文件的例子二,就分产品计算流水账了:

 下载信息  [文件大小:   下载次数: ]
图片点击可在新窗口打开查看点击浏览该文件:管理项目7.table

[此贴子已经被作者于2009-5-11 16:48:40编辑过]

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


加好友 发短信
等级:管理员 帖子:47449 积分:251065 威望:0 精华:91 注册:2008/6/17 17:14:00
  发帖心情 Post By:2009/5/11 17:23:00 [显示全部帖子]

你得条件设置不正确,所以得不到正确的结果,看这个:

 下载信息  [文件大小:   下载次数: ]
图片点击可在新窗口打开查看点击浏览该文件:管理项目32.table


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


加好友 发短信
等级:管理员 帖子:47449 积分:251065 威望:0 精华:91 注册:2008/6/17 17:14:00
  发帖心情 Post By:2009/5/12 10:20:00 [显示全部帖子]

默认按日期排序即可。

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


加好友 发短信
等级:管理员 帖子:47449 积分:251065 威望:0 精华:91 注册:2008/6/17 17:14:00
  发帖心情 Post By:2009/5/12 13:22:00 [显示全部帖子]

以下是引用清风伴流水在2009-5-12 13:18:00的发言:

试了一下,如果删除中间行,那么余数不会自动改变???修改数据是可以的--列内容发生变化!但是删除行时没有影响列内容

再完善一下!看看怎么处理比较好!


可以在AfterDeleteDataRow事件中加入代码,重算余额列


 回到顶部