如何在vba中find树进程的结尾

我有一个与每个操作相关的操作和时间的Excel工作表。 而这些行动是有联系的,有些有继任者,有些则没有。

我创build了一个macros来find一个操作的直接接class人,它运作良好。

但是我想要做的是find所有的操作接class人。 我是指继任者的继任者等,因为我想看看如果我取消或停止这个操作,会有多less时间受到影响。

下面是一个例子:

Lvl1 Lvl2 Lvl3 Lvl4 Lvl5 OP3---OP5----OP6 / / OP1 / \ / \ / OP4 OP0 \ \ \ OP2---OP7 

在这个例子中,要从一个层次到另一个层次,我必须运行我的macros(如果没有更多的后续操作,我的macros返回一个空的数组)。

所以,目的是把所有这些操作的时间加起来找出结果。

但是,我不知道如何让一个操作没有更多的后继,然后去下一个操作,使我的循环停止。

例如在这里,当我到达OP6时,我怎么知道我必须回到OP4

PS:这里是我的macros的一个简化版本(我没有在我的文件中的每个操作的inheritance者,但只有前辈,这就是为什么我要通过文件来查找我想要的操作是否在每个操作的前辈名单)

 OP_number = "ER345RET" For i = 2 To File_size Predecessors = Split(Worksheets(1).Range("S" & i).Value, ";") For j = 0 To UBound(Predecessors) If Predecessors(j) = OP_number Then Successors(q) = Worksheets(1).Range("F" & i).Value q = q + 1 End If Next j Next i 

recursion很可能是您完成此任务的最佳select。 recursion函数看起来像这样(伪代码):

 'Recursive function returns count of successors Function getSuccessor(predecessor As String) As Long 'Check if this predecessor has a successor 'If Yes then call self (getSuccessor) with new predecessor getSuccessor = getSuccessor(myNewSuccessor) 'If No set exit condition getSuccessor = 1 'one increases the count for this level End Function 

看来,你试图build立一个数组的每个继任者,你去。 您可以通过在recursion调用getSuccessor函数之前将新项添加到数组来完成此操作。 你可能需要一个全局数组来存储它。

 'If Yes then call self (getSuccessor) with new predecessor Successors(x) = myNewSuccessor getSuccessor = getSuccessor(myNewSuccessor) 

主函数看起来像这样:

 Sub recursion() Dim count As Integer OP_number = "ER345RET" For i = 2 To File_size 'set topLevelPredecessor count = getSuccessor(topLevelPredecessor) Next i MsgBox ("Total Levels of successors is: " & count) End Sub 

有了这样的数据:

 FS OP0 OP1 OP0 OP2 OP0 OP3 OP1 OP4 OP1 OP5 OP3 OP6 OP5 OP7 OP2 

然后,这段代码将把所有的后继放在一个数组中

 Sub Main() Dim vaPreds As Variant Dim aSuccs() As String Dim vaOps As Variant Dim lCnt As Long Dim i As Long 'Create a two-dimensional array of predecessors 'from column S vaPreds = Sheet1.Range("S2:S8").Value 'Create a two-dim array of operations from 'column F vaOps = Sheet1.Range("F1:F8").Value 'Call the function that will load the successors 'into the aSuccs() array variable FindPreds "OP0", vaPreds, aSuccs, vaOps, lCnt 'Loop through the final successors array and 'print them to the Immediate Window For i = LBound(aSuccs) To UBound(aSuccs) Debug.Print aSuccs(i) Next i End Sub Sub FindPreds(ByVal sOpStart As String, ByRef vaPreds As Variant, ByRef vaSuccs As Variant, ByRef vaOps As Variant, ByRef lCnt As Long) Dim vaSplit As Variant Dim i As Long, j As Long 'Loop through all the predecessors For i = LBound(vaPreds, 1) To UBound(vaPreds, 1) 'Split the predecessors on semi colon for cells 'where there are more than one. vaSplit = Split(vaPreds(i, 1), ";") 'Loop through the split predecessors For j = LBound(vaSplit) To UBound(vaSplit) 'If the predecessor is the operation I'm looking 'for, add the operation to the successors array If vaSplit(j) = sOpStart Then lCnt = lCnt + 1 ReDim Preserve vaSuccs(1 To lCnt) vaSuccs(lCnt) = vaOps(i + 1, 1) 'Go find any successors for the operation you just 'added to the successors array FindPreds vaOps(i + 1, 1), vaPreds, vaSuccs, vaOps, lCnt End If Next j Next i End Sub 

我终于find了如何调整这个问题。

我不是一个接一个地经过树的每一个分支,而是决定一次去过每一个分支。 当我没有任何继任者离开时停止迭代。

下面是我写的代码:

 q = 1 qstop = 1 Opdaughters(1, 0) = OP_number For i = 2 To Size If Worksheets("XXX").Range("J" & i) = OP Then Opfilles(2, 0) = Worksheets("XXX").Range("O" & i) End If Next i Call Macro(OP_number, q, Opdaugthers) Buffer() = Opdaughters() While q <> qstop retenue = q For i = qstop To q Call Macro(Buffer(1, i), q, Opdaughters) ReDim Preserve Buffer(2, UBound(Opdaughters, 2)) Next i qstop = retenue Buffer() = Opdaughters() Wend 

基本上,我通过在最后join接class人来让我的女儿们成长。 那么当没有更多的继任者被添加到我的表(即当q = qstop),这意味着我已经达到了我的过程结束。

下面是我的表OPdaughters通过迭代看起来像一个例子:

 Iteration0 Iteration1 Iteration2 OP0 OP0 OP0 OP1 OP1 OP2 OP2 OP3 OP3 OP11 OP12 OP21 OP31 OP32 OP33