Excel VBA - 将类方法的名称传递给另一个子例程以调用该方法

问题描述 投票:0回答:1

我有一个名为“MyFunctions.xlam”的加载项文件。它包含几个辅助函数,包括自定义求解器等。

在MyFunctions中,我有一个名为“ChemicalRelease”的类。此类具有massRate属性和名为“affectedArea”的公共函数。 “affectedArea”方法通过几次计算和方法调用,根据提供的质量率和其他几个因素确定化学品释放的受影响区域大小。我有一个目标受影响的区域大小,我希望使用一个求解器来计算一个合适的质量率,这将导致目标受影响的区域大小。

在ChemicalRelease类模块内部,名为“varyMassRateForTargArea”的方法尝试使用割线求解器求解massRate,以指定受影响的区域为目标:

massRate = solverSecant(massRate,“ChemicalRelease.affectedArea”,targArea,0,False)

“solverSecant”位于“MyFunctions”的“Module1”中,并且具有足够的通用性,可供任何类方法使用。

以下是“solverSecant”的一些代码:

Function solverSecant(ByRef varyingProperty, methodToRun, Optional yTarget = 0#, Optional dx = 0, Optional dDebug As Boolean = False)

x0 = varyingProperty

If dx <= 0 Then dx = x0 / 1000

maxIter = 1000

currIter = 0

xTol = dx / 10

x1 = x0 + dx

x0 = varyingProperty
y0 = Application.Run(methodToRun) - yTarget
...

“solverSecant”方法需要执行以下操作:

  1. 在实例化的ChemicalRelease对象中更新massRate的属性值。
  2. 使用步骤#1中更新的属性值运行对象的“affectedArea”方法。
  3. 执行其余的求解器算法,但该部分应该可以正常工作,因为满足了其他两个要求。

我的问题是:

  1. 一旦初始化了一个“ChemicalRelease”实例,并且调用了“varyMassRateForTargArea”方法,是否可以将引用实例化的“ChemicalRelease”对象从“varyMassRateForTargArea”传递给“Module1”中的“solverSecant”?这相当于将“自我”作为我能想到的其他语言的论证。
  2. 有没有办法从“Module1”运行“ChemicalRelease.affectedArea”方法?我似乎无法使用“Application.Run”,但我可能没有正确的语法。

谢谢您的帮助。我知道我可以将解算器作为类对象中方法的一部分,但我宁愿在“MyFunctions”中开发一个求解器,它可以将它应用于其他类的任何其他方法/属性。

excel-vba function oop user-defined-functions vba
1个回答
1
投票

您可以将Me从该类传递给其他代码。并致电affectedArea使用ClassInstanceName.affectedArea(提供affectedArea是公开的)

为了展示,创建类ChemicalRelease

Option Explicit

Private pVar As Variant

Property Get affectedArea() As Variant
    affectedArea = pVar
End Property

Sub Init(v As Variant)
    pVar = v
End Sub

Sub varyMassRateForTargArea()
    Module1.solverSecant Me
End Sub

Sub Method1(v As Variant)
    Debug.Print "Method 1", v
End Sub

Sub Method2(v As Variant)
    Debug.Print "Method 2", v
End Sub

Module1代码这个

Option Explicit

Sub solverSecant(obj As ChemicalRelease)
    Dim NameOfMethod As String
    Debug.Print "solverSecant", obj.affectedArea

    NameOfMethod = "Method1"
    CallByName obj, NameOfMethod, VbMethod, "Parameter passed to Method 1"
    NameOfMethod = "Method2"
    CallByName obj, NameOfMethod, VbMethod, "Parameter passed to Method 2"
End Sub

运行此测试代码以演示操作

Sub Test()
    Dim Instance1OfClass As ChemicalRelease, Instance2OfClass As ChemicalRelease
    Dim v

    Set Instance1OfClass = New ChemicalRelease
    Set Instance2OfClass = New ChemicalRelease

    Instance1OfClass.Init "A"
    Instance2OfClass.Init "B"

    ' Get Property
    v = Instance1OfClass.affectedArea
    Debug.Print "Instance1OfClass", v

    v = Instance2OfClass.affectedArea
    Debug.Print "Instance2OfClass", v

    ' Call method
    Instance1OfClass.varyMassRateForTargArea
    Instance2OfClass.varyMassRateForTargArea
End Sub

立即窗口中的输出应该是

Instance1OfClass A. Instance2OfClass B. solverSecant A 方法1传递给方法1的参数 方法2传递给方法2的参数 solverSecant B 方法1传递给方法1的参数 方法2传递给方法2的参数

© www.soinside.com 2019 - 2024. All rights reserved.