У меня есть модель симуляции, закодированная в Excel VBA. Он построен внутри модуля класса с именем «ChemicalRelease». Есть еще один модуль Class с именем «UniversalSolver», который работает для оптимизации параметров ChemicalRelease.
При выполнении различных симуляций universalSolver иногда использует комбинацию параметров, выходящую за пределы моделирования приложения. Трудно определить истинные границы моделирования, поскольку оно основано на множестве комбинаций параметров.
Экземпляр UniversalSolver создаст набор входных параметров и создаст экземпляр ChemicalRelease для запуска модели, как указано. Внутри ChemicalRelease поток работает в нескольких методах, таких как "setden", которые могут вызывать другие методы для выполнения своих вычислений. Например, «setden» может вызывать «tprop» для определения термодинамических свойств, а «tprop», в свою очередь, может вызывать функцию для итеративного решения для значения.
В любой точке любого из этих методов модель может определить, что комбинация входных параметров не может быть решена. Текущая конфигурация уведомляет меня о проблеме через msgbox и останавливает программу, переводя ее в режим отладки.
Я хотел бы использовать обработчик событий, который установит значение экземпляра обработчика, который остановит вычисления в "ChemicalRelease", установит экземпляр в "Nothing" и вернет управление в "UniversalSolver" сразу после линия, в которой был создан экземпляр «ChemicalRelease» и вызван для моделирования.
несколько поисковых запросов в Google, и ни один из них не указывает на способ вернуть управление в "UniversalSolver".
'Код обработчика события: кредит Изменение в переменной вызывает событие
Класс 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
"УниверсалСольвер" класс
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
Класс "Химический выпуск"
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, как если бы я указывал «exit sub» из ChemicalRelease.initialize. Однако я не могу найти правильный метод для этого.