Excel VBA - вернуть управление вызывающему методу, когда вызываемый метод уже вызвал другой метод - PullRequest
0 голосов
/ 16 мая 2019

У меня есть модель симуляции, закодированная в 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. Однако я не могу найти правильный метод для этого.

1 Ответ

0 голосов
/ 16 мая 2019

Обработка ошибок в вызывающей функции работает для всех вызываемых функций. Тем не менее, команда «resume» необходима для вывода VBA из режима обработки ошибок. Согласно приведенному ниже коду, поток возвращается в нормальный режим с меткой endoffor в вызывающей функции.

errcatch:
Err.Clear

On Error GoTo errcatch
Resume endoffor '
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...