用递归函数生成会计科目目录树
一般用户可以忽略本节内容。
本节内容可以参考CaseStudy目录下的文件:会计科目.Table
假定有下图所示会计科目表:
科目代码为四位数的是一级科目,六位数的是二级科目,八位数的是三级科目,要求根据科目代码生成下图所示的目录树:
设计步骤:
1、在内部函数中新建一个函数,名为AddChildren,代码为:
Dim
nd As
WinForm.TreeNode
= args(0)
Dim
dt As
DataTable = args(1)
For
Each dr
As DataRow
In
dt.Select("","科目代码")
Dim km
As String =
dr("科目代码")
If km.StartsWith(nd.name)
AndAlso km.Length
= nd.Name.Length
+ 2 Then
Dim
cd As Winform.TreeNode
= nd.Nodes.Add(km,km
& " "
& dr("科目名称"))
Functions.Execute("AddChildren",cd,dt)
End
If
Next
上述代码中,出现了调用AddChildren函数自身的代码(第8行):
Functions.Execute("AddChildren",cd,dt)
这种在函数自己调用自己的情况,就是常说的递归调用。
2、新建一窗口,在窗口中加入一个目录树控件。
3、将窗口的AfterLoad事件代码设置为:
Dim
tr As
WinForm.TreeView
= e.Form.Controls("TreeView1")
Dim
nd As
WinForm.TreeNode
Dim
dt As
DataTable =
DataTables("会计科目")
tr.StopRedraw()
tr.Nodes.Clear
tr.Nodes.Add("全部")
For
Each dr
As DataRow
In
dt.Select("","科目代码")
If dr.IsNull("科目代码")
= False AndAlso
dr("科目代码").Length
= 4 Then
nd =
tr.Nodes.Add(dr("科目代码"),dr("科目代码")
& " "
& dr("科目名称"))
Functions.Execute("AddChildren",nd,dt)
End
If
Next
tr.ResumeRedraw()
这样打开此窗口,即可根据科目代码自动生成目录树。
4、最后将目录树的NodeMouseDoubleClick事件代码设置为:
Dim
trv As
WinForm.TreeView
= e.Form.Controls("TreeView1")
If
e.Node.Name
= "全部"
Then
Tables("会计科目").Filter
= ""
Else
Tables("会计科目").Filter
= "科目代码 Like '" &
e.Node.Name
&
"%'"
End
If
这样要求双击某个节点,即可将此节点及其子节点对应的行全部筛选出来。
再进一步
下面的内容,可以参考项目文件“会计科目.Table”的“窗口2”。
同样以上面的表为例,科目代码首字符1表示资产,2表示负债,3表示权益,4表示成本,5表示损益。
要求生成下图所示的目录树:
设计步骤:
1、在内部函数中新建一个函数,名为AddChildren,代码为:
Dim
nd As
WinForm.TreeNode
= args(0)
Dim
dt As
DataTable = args(1)
For
Each dr
As DataRow
In
dt.Select("","科目代码")
Dim km
As String =
dr("科目代码")
If km.StartsWith(nd.name)
AndAlso km.Length
= nd.Name.Length
+ 2 Then
Dim
cd As Winform.TreeNode
= nd.Nodes.Add(km,km
& " "
& dr("科目名称"))
Functions.Execute("AddChildren",cd,dt)
End
If
Next
2、新建一窗口,在窗口中加入一个目录树控件。
3、将窗口的AfterLoad事件代码设置为:
Dim
tr
As
WinForm.TreeView
=
e.Form.Controls("TreeView1")
Dim
rts()
As
String
=
{"全部","资产","负债","权益","成本","损益"}
Dim
nd
As
WinForm.TreeNode
Dim
dt
As
DataTable
=
DataTables("会计科目")
tr.StopRedraw()
tr.Nodes.Clear
For Each
rt
As
String
In
rts
tr.Nodes.Add(rt)
Next
For Each
dr
As
DataRow
In
dt.Select("","科目代码")
If
dr.IsNull("科目代码")
= False AndAlso
dr("科目代码").Length
=
4
Then
Dim
i
As
Integer
=
CInt(dr("科目代码").Substring(0,1))
nd
=
tr.Nodes(i).Nodes.Add(dr("科目代码"),dr("科目代码")
&
" "
&
dr("科目名称"))
Functions.Execute("AddChildren",nd,dt)
End
If
Next
tr.ResumeRedraw()
需要特别注意一点,定义数组的时候,顺序不能错乱:
Dim
rts()
As
String
=
{"全部","资产","负债","权益","成本","损益"}
这样才能保证目录树编号为1的根节点是资产,编号为2的根节点是负债...,以简化后续代码的设计。
4、最后将目录树的NodeMouseDoubleClick事件代码设置为:
Dim
trv As
WinForm.TreeView
= e.Form.Controls("TreeView1")
If
e.Node.Level
= 0
If e.Node.Name
= "全部"
Then
Tables("会计科目").Filter
= ""
Else
Tables("会计科目").Filter
= "科目代码
Like '"
& e.Node.Index
& "%'"
End
If
Else
Tables("会计科目").Filter
= "科目代码
Like '"
& e.Node.Name
&
"%'"
End
If