2

次の方法でVBAに継承を実装しようとしています-

clsRange以下に示すように、1つのクラスモジュールがあります

Private strRngName as String

Public Property Let RangeName(ByVal thisRangeName As String)
    strRngName = thisRangeName
End Property

Public Property Get RangeName() As String
    RangeName= strRngName
End Property

別のクラス モジュールclsChildRange

private rngHolder as New clsRange

Public Property Get RangeName() As String
   Set RangeName = rngHolder.RangeName
End Property

Public Property Let RangeName(ByVal thisRangeName As String)
    rngHolder.RangeName = thisRangeName
End Property

私はモジュールを持っています.clsChildRangeのオブジェクトを作成し、次の方法でclsRangeのプロパティを設定しようとしています.

Dim objCRng  as New clsChildRange

objCRng.RangeName= "Range1"

しかし、エラーが発生します-オブジェクト変数またはブロック変数が設定されていません。

4

2 に答える 2

6

Uri が言ったように、rngHolder はインスタンス化されていないため、問題が発生しています。Null をテストしないで、Is Nothing をテストします。達成しようとしていることに応じて、これを行う 2 つの方法を次に示します。

範囲を明示的に設定する

CRangeで

Private msRngName As String

Public Property Let RngName(ByVal sRngName As String): msRngName = sRngName: End Property
Public Property Get RngName() As String: RngName = msRngName: End Property

CChildRange で

Private mclsRange As CRange

Public Property Set Range(ByVal clsRange As CRange): Set mclsRange = clsRange: End Property
Public Property Get Range() As CRange: Set Range = mclsRange: End Property

Public Property Get RngName() As String

    If Not Me.Range Is Nothing Then
        RngName = Me.Range.RngName
    End If

End Property

Public Property Let RngName(sName As String)

    If Not Me.Range Is Nothing Then
        Me.Range.RngName = sName
    End If

End Property

次に、標準モジュールで

Sub test()

    Dim clsRange As CRange
    Dim clsChildRange As CChildRange

    'Create a new CRange instance
    Set clsRange = New CRange

    'Create a new CChildRange instance
    Set clsChildRange = New CChildRange

    'Set the Range property to the CRange instance
    Set clsChildRange.Range = clsRange

    'Set the RngName property of the chile
    clsChildRange.RngName = "Range1"

    'Test that the parent has the property set
    Debug.Assert clsRange.RngName = "Range1"

End Sub

Range を暗黙的に設定する

CRangeも同じです。

CChildRange で

Private mclsRange As CRange

Public Property Set Range(ByVal clsRange As CRange): Set mclsRange = clsRange: End Property
Public Property Get Range() As CRange: Set Range = mclsRange: End Property

Public Property Get RngName() As String

    RngName = Me.Range.RngName

End Property

Public Property Let RngName(sName As String)

    Me.Range.RngName = sName

End Property

Private Sub Class_Initialize()

    Set mclsRange = New CRange

End Sub

Private Sub Class_Terminate()

    Set mclsRange = Nothing

End Sub

次に、標準モジュールで

Sub test()

    Dim clsChildRange As CChildRange

    'Create a new CChildRange instance
    'Range object created when class is created
    Set clsChildRange = New CChildRange

    'Set the RngName property of the chile
    clsChildRange.RngName = "Range1"

    'Test that the parent has the property set
    Debug.Assert clsChildRange.Range.RngName = "Range1"


End Sub
于 2012-08-07T16:20:11.063 に答える
1

この問題で rngHolder メンバーが初期化されていないと思われます。このコードを試してください

private rngHolder as clsRange

Public Property Get RangeName() As String
   If rngHolder=Null Then Set rngHolder=New clsRange
   Set RangeName = rngHolder.RangeName
End Property

Public Property Let RangeName(ByVal thisRangeName As String)
    If rngHolder=Null Then Set rngHolder=New clsRange
    rngHolder.RangeName = thisRangeName
End Property
于 2012-08-07T11:56:21.713 に答える