
私は Excel でプロセス マップを作成し、それを Visio で視覚化しました。プロセスと決定があります。プロセスには時間がかかり、決定の結果は確率で重み付けされます。私の数字が正しいと仮定すると (おそらく正しくないと思いますが ;))、これによりプロセス全体の平均実行時間を計算できるはずです。
ここで、平均実行時間を取得するには、重みを考慮してパスに沿って要約する必要があります。これ自体は難しい作業ではありませんが、マップの現在の状態に固有ではなく、プロセスと決定を追加した場合に自動的に更新できるフォーラムが望ましいです。パスは Excel シートで定義されているため、原理的には何らかの再帰関数でこれが可能になるはずです。ただし、Excel で再帰関数を実装する方法については、可能かどうかわかりません。
これをやったことがある人はいますか? または、これがどのように機能するかについてのヒントを持っていますか? それとも、外部ツールに頼る必要がありますか?
したがって、「プロセス ステップ」と「次のステップ ID」を組み合わせると、「開始」から「終了」までの複数のパスが定義されます。決定には、特定の重み (パーセントで表されます) を持つ結果があり、これは 2 つの「次のステップ ID」のうち最初の ID が実行される確率です。
この場合は、次のように始まります: 1 + 0.4*(2 ...) + 0.6*(2 ...) ... ご覧のとおり、Excel を変更しない場合でも、手動で正しく行うことは非常に困難です。ここで、いくつかの手順を追加すると想像してください...
これでタスクが明確になれば幸いです。現在、VBA でこの問題を解決しようとしていますが、VBA を使用したことがないので、ヒントがあれば幸いです。
答え1
さて、私は最終的に再帰 VBA 関数を使用してこれを自分で解決しました。
Function ProcessTime(row, time) As Double
Application.Volatile
' Define Columns
ProcessStepCol = 2
NextStepIDCol = 4
ShapeTypeCol = 6
TimeCol = 7
PyesCol = 8
' Do actual calculation
ShapeType = Worksheets("Process").Cells(row, ShapeTypeCol).Value
' Exit at the End
If ShapeType = "End" Then
ProcessTime = time
Exit Function
End If
' Simply add current time if we have a Process
If ShapeType = "Process" Then
NextStepRow = GetNextStepRows(row, 0)
TimeOfThisRow = Worksheets("Process").Cells(row, TimeCol).Value
ProcessTime = time + ProcessTime(NextStepRow, TimeOfThisRow)
Exit Function
End If
' Add wheights to branches if we have a Decision
If ShapeType = "Decision" Then
NextStepRowYes = GetNextStepRows(row, 0)
NextStepRowNo = GetNextStepRows(row, 1)
P_yes = Worksheets("AlertProcess").Cells(row, PyesCol).Value / 100
P_no = 1 - P_yes
ProcessTime = time + (P_yes * ProcessTime(NextStepRowYes, 0)) + (P_no * ProcessTime(NextStepRowNo, 0))
Exit Function
End If
End Function
' Find the row of the next step
Function GetNextStepRows(row, stepNo) As Long
Application.Volatile
' Define Columns
ProcessStepCol = 2
NextStepIDCol = 4
' Do actual calculation
NextStepIDs = Worksheets("AlertProcess").Cells(row, NextStepIDCol).Value
NextStepIDsSplit = Split(NextStepIDs, ",")
NextStepID = NextStepIDsSplit(stepNo)
GetNextStepRows = Worksheets("AlertProcess").Range("B:B").Find(What:=NextStepID).row
End Function
はい、これが最もエレガントなコードではないことは承知しています ;)