技術(shù) 點(diǎn)
- 技術(shù)
- 點(diǎn)
- V幣
- 點(diǎn)
- 積分
- 21536
|
本帖最后由 todaynew 于 2015-6-6 12:44 編輯
越俎代庖這個成語中有兩個角色,一個是神漢一個大廚,意思是說在祭祀活動中神漢和大廚是有分工的,神漢不應(yīng)直接代替大廚的工作。在Vba中實(shí)現(xiàn)一些功能,也有兩種東西,一個叫做子程序(Sub),一個叫做函數(shù)(Function)。子程序用來完成某些動作,函數(shù)用來返回需要的數(shù)據(jù),通常來說這樣理解沒什么大的問題。不過有時候我們需要用函數(shù)來越俎代庖,實(shí)現(xiàn)子程序完成某些動作的功能。
從道理上講,函數(shù)是可以替代子程序的。原因在于函數(shù)體和子程序體的構(gòu)成是沒有什么大的差別的,唯一不同的是函數(shù)體中可以存在一條返回?cái)?shù)據(jù)的語句。也就是說子程序能實(shí)現(xiàn)的功能,函數(shù)都是可以實(shí)現(xiàn)的。而函數(shù)能實(shí)現(xiàn)的功能,子程序并不一定都能實(shí)現(xiàn)。這樣說來,子程序的存在只是為了保留一種概念上的功能區(qū)分。
版友付謙同志昨日里問了一個關(guān)于家譜用TreeView呈現(xiàn)方面的問題。我們知道家譜是一個不定級的層次結(jié)構(gòu),最適于用遞歸的方法來得到一個樹形結(jié)構(gòu)。所以我們通?梢杂靡粋遞歸子程序來實(shí)現(xiàn)TreeView節(jié)點(diǎn)的加載。假如我們希望在每個節(jié)點(diǎn)上,反映出這個節(jié)點(diǎn)的所有后代成員的總數(shù),這就不是一個簡單的事情了。說它不簡單,是因?yàn)樗龅膭幼魇窍蚬?jié)點(diǎn)的Text屬性寫入一個統(tǒng)計(jì)出來的數(shù)據(jù),遞歸動作本身比較難以統(tǒng)計(jì)這個數(shù)據(jù)。在這個特定的情況下,遞歸子程序比較難以實(shí)現(xiàn)邊統(tǒng)計(jì)邊寫入的功能。
怎么辦呢?答案很簡單,將遞歸子程序改為遞歸函數(shù),這個問題就很簡單的可以解決了。函數(shù)是可以一邊做一些動作,一邊進(jìn)行計(jì)算并返回?cái)?shù)據(jù)的,這些返回的數(shù)據(jù)可以容易的參與遞歸運(yùn)算。我們可以將代碼大體寫成如下:
Private Function SetNodes(ByRef tree As TreeView, ByRef n As Node) As Long
Dim cn As Node
Dim rs As New ADODB.Recordset
Dim ssql As String
Dim i As Long
Dim cnt As Long
ssql = "select * from 族人信息 where " & n.Tag
rs.Open ssql, CurrentProject.Connection, adOpenKeyset, adLockOptimistic
cnt = rs.RecordCount
For i = 1 To rs.RecordCount
Set cn = tree.Nodes.Add(n.Key, 4, "b" & rs!族人代碼.Value, rs!姓名.Value)
cn.Tag = "nz(父代碼,0)=" & rs!族人代碼.Value
'遞歸運(yùn)算
cnt = cnt + SetNodes(tree, cn)
rs.MoveNext
Next
'寫入節(jié)點(diǎn)的Text屬性
n.Text = n.Text & " (" & n.Children & "/" & cnt & ")"
SetNodes = cnt
rs.Close: Set rs = Nothing
Set cn = Nothing
End Function
示例:
視圖:
|
本帖子中包含更多資源
您需要 登錄 才可以下載或查看,沒有帳號?注冊
x
|