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

时间:2018-02-27 22:47:57

标签: excel-vba function oop user-defined-functions vba

我有一个名为“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. 执行其余的求解器算法,但考虑到满足其他两个要求,该部分应该可以正常工作。
  4. 我的问题是:

    1. 一旦初始化了“ChemicalRelease”的实例,并且调用了“varyMassRateForTargArea”方法,是否可以将对“实例化的”ChemicalRelease“对象的引用从”varyMassRateForTargArea“传递给”Module1“中的”solverSecant“ “?这相当于将“自我”作为我能想到的其他语言的论据。

    2. 有没有办法从“Module1”运行“ChemicalRelease.affectedArea”方法?我似乎无法使用“Application.Run”,但我可能没有正确的语法。

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

1 个答案:

答案 0 :(得分: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的参数