【发布时间】:2019-05-16 18:40:31
【问题描述】:
我有一个用 Excel VBA 编码的模型模拟。它构建在名为“ChemicalRelease”的类模块中。还有另一个名为“UniversalSolver”的类模块,用于优化 ChemicalRelease 的参数。
在运行不同的模拟时,universalSolver 有时会使用超出应用程序建模范围的参数组合。很难确定真正的建模边界,因为它基于多个参数组合。
UniversalSolver 的一个实例将创建一组输入参数并实例化 ChemicalRelease 以按指定运行模型。在 ChemicalRelease 内部,流程在几种方法中工作,例如“setden”,这些方法可能会调用其他方法来执行它们的计算。例如,“setden”可以调用“tprop”来确定热力学性质,而“tprop”又可以调用一个函数来迭代求解一个值。
在任何这些方法中的任何时候,模型都可能确定输入参数的组合无法求解。当前配置通过 msgbox 通知我该问题并停止程序,使其进入调试模式。
我想使用一个事件处理程序,它将设置一个处理程序实例的值,该处理程序将停止“ChemicalRelease”中的计算,将实例设置为“Nothing”并将控制权返回给“UniversalSolver”,之后直接“ChemicalRelease”被实例化并要求建模的行。
几个谷歌搜索,没有一个指向将控制权返回给“UniversalSolver”的方法。
'事件处理程序代码:感谢Change in variable triggers an event
“ClassWithEvent”类
Public Event VariableChange(value As Integer)
Private p_int As Integer
Public Property Get value() As Integer
value = p_int
End Property
Public Property Let value(value As Integer)
If p_int <> value Then RaiseEvent VariableChange(value) 'Only raise on
actual change.
p_int = value
End Property
“ClassHandlesEvent”类
Private WithEvents SomeVar As ClassWithEvent
Private Sub SomeVar_VariableChange(value As Integer) 'This is the event
handler.
'line here to return control to "UniversalSolver" instance, out of
"ChemicalRelease" instance, regardless of how many methods have to be
returned out of within ChemicalRelease.
End Sub
Public Property Get EventVariable() As ClassWithEvent
Set EventVariable = SomeVar
End Property
Public Property Let EventVariable(value As ClassWithEvent)
Set SomeVar = value
End Property
“全局”模块 '为 ClassHandlesEvent 和 ClassWithEvent 全局设置实例
Global VAR As ClassHandlesEvent
Global TST As ClassWithEvent
“UniversalSolver”类
Public Sub initialize()
Set VAR = New ClassHandlesEvent
Set TST = New ClassWithEvent
VAR.EventVariable = TST
End Sub
Public Sub solve()
Do 'iterate through potential input parameters
Set m_chemRelease = New ChemicalRelease
m_chemRelease.initialize 'initializes and launches modeling
Loop until satisfied
End Sub
“ChemicalRelease”类
Public Sub initialize(modelParamsSheet As Worksheet)
Set m_modelParamsSheet = modelParamsSheet
Call readModelInputsAndSetProperties(0)
End Sub
Private Sub readModelInputsAndSetProperties(inNum As Integer)
'set all properties and launch modeling
Call setjet(0)
End Sub
Private Sub setjet(inInt As Integer)
'lots of math.
call tprop(tpropsInputDict)
'lots more math.
End Sub
Private Sub tprop(inDict as Scripting.Dictionary)
'more math.
'check for convergence
If check > 0.00001 Then
'failed convergence
'trigger event to exit ChemicalRelease Instance and return control
to UniversalSolver instance
TST.value = 2
End If
'more math.
Call limit()
End Sub
Private Sub limit()
'more math.
'check for sign
If fa * fb > 1 Then
'failed convergence
'trigger event to exit ChemicalRelease Instance and return control
to UniversalSolver instance
TST.value = 2
End If
'more math.
End Sub
预期的结果是有一个可以在项目内的任何位置触发的事件,它将控制权返回给 UniversalSolver,就像我在 ChemicalRelease.initialize 中声明“退出子”一样。但是,我找不到有效的方法。
【问题讨论】:
标签: excel vba oop error-handling event-handling