用递归函数生成会计科目目录树

一般用户可以忽略本节内容。

本节内容可以参考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


本页地址:http://www.foxtable.com/webhelp/topics/2502.htm