如何在vba中找到树进程的结束

时间:2014-05-23 12:06:32

标签: excel vba excel-vba

我有一个excel工作表,其中包含与每个操作相关的操作和时间。这些操作是相互关联的,有些是后继者,有些则不是。

我创建了一个宏来查找操作的直接后继,并且效果很好。

但我想要做的是找到一个操作的所有后继者。我的意思是计算继任者'继承人等等,因为如果我取消或停止此操作,我想看看有多少时间受到影响。

以下是它的外观示例:

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

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

因此,目的是增加所有这些操作的时间来查找结果。

但我无法想象如何在一个操作没有更多后继者然后转到下一个操作时停止循环。

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

PS:这是我的宏的简化版本(我没有在我的文件中有每个操作的后继,但只有前辈,这就是为什么我必须查看文件以查找是否我想要的操作是在每个操作的前辈列表中)

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

3 个答案:

答案 0 :(得分:1)

递归很可能是此任务的最佳选择。递归函数看起来像这样(伪代码):

'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

看起来你正试图建立一个每个继任者的阵列。您可以通过在递归调用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

答案 1 :(得分:1)

使用这样的数据:

F       S
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

答案 2 :(得分:0)

我终于找到了如何调整问题。

我没有逐个遍历树的每个分支,而是决定立刻浏览每个分支。当我没有任何继任者时,停止迭代。

以下是我写的代码:

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

基本上我通过在最后添加继承者来使我的表OPdaughters成长。然后,当我的表中没有添加更多后继时(即当q = qstop时),这意味着我到达了我的流程结束。

以下是我的表OPdaughters通过迭代看起来的样子:

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