我有一个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
答案 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