web-dev-qa-db-ja.com

VBAクラスモジュールのプロパティを許可-複数の引数を持つことは可能ですか?

これまでのクラスモジュールでのLetプロパティの使用に関する私の理解は、次のようにクラスモジュールで設定することです。

Dim pName as String
Public Property Let Name(Value As String)
    pName = Value
End Property

そして、このクラスのオブジェクトを作成した後、このプロパティを次のように設定できます。

MyObject.Name = "Larry"



質問:どういうわけか、クラスプロパティに複数の引数を入力することは可能ですか?例えば:

Dim pFirstName as String, pLastName as String
Public Property Let Name(FirstName As String, LastName As String)
    pFirstName = FirstName
    pLastName = LastName
End Property

次に、このプロパティをクラス外で設定するにはどうしますか?

MyObject.Name = ??

それとも、これは単純に不可能ですか?

11
mattboy

コメントに従って、このロジックをカプセル化したい場合は、以下のようなものを使用できます。

以下は、サブと関数を含みます。この関数はPersonオブジェクトを返します。

Public Sub testing()

    Dim t As Person

    Set t = PersonData("John", "Smith")

End Sub


Public Function PersonData(firstName As String, lastName As String) As Person

    Dim p As New Person

    p.firstName = firstName
    p.lastName = lastName

    Set PersonData = p

End Function

個人クラス:

Dim pFirstName As String, pLastName As String

Public Property Let FirstName(FirstName As String)
    pFirstName = FirstName
End Property

Public Property Get FirstName() As String
    FirstName = pFirstName
End Property

Public Property Let LastName(LastName As String)
    pLastName = LastName
End Property

Public Property Get LastName() As String
    LastName = pLastName
End Property
8
InContext

すでに2つの回避策があることは承知していますが、元の質問に回答することは、この質問が受けている意見の数が多いため、試してみる価値があると思いました。

への答え

VBAのLetプロパティで複数の引数を持つことは可能ですか?

です

はい!それが可能だ。

まず、GETプロパティについて説明します。これが_Class1_であると考えてください

_Private firstName as String
Private lastName as String

Public Property Get Name() As String
    Name = firstName & " " & lastName
End Property
_

Nameプロパティはフルネームを返します。これは素晴らしいことですが、-Letプロパティを使用してfirstNamelastNameを一度に割り当てる方法は?

サイドノート:特殊文字で区切られた単一の文字列を渡して、Letの本体内で分割し、firstlastの名前を割り当てることができますただし忘れてください、それを適切に実行しましょう...

OK、VBAでは、現在の設定のデフォルトのLetプロパティは1つのパラメーターを取り、姓または名のいずれかに割り当てます...

何かのようなもの:

_Public Property Let Name(value As String)
    firstName = value
End Property
_

ルール:Getはパラメーターを取らず、Letはパラメーターを取ります。 Getは基礎となる値を返しますが、Letは、それが表すデータに割り当てるためにsomewhereから値を取得する必要があるため、これは非常に論理的です。この時点で、Letプロパティは_=_記号を介して割り当てられることを思い出してください。 _myObject.Name = "IdOnKnuu"_

上記ルールと一貫性を保つ場合、理論的には Getに1つのパラメーターを追加 および 1つ以上Let に変更します。

Letを忘れてみましょう-今のところコメントアウト-パラメータをGetプロパティに追加します。

_Private firstName As String
Private lastName As String

Public Property Get Name(first As String) As String
    Name = firstName & " " & lastName
End Property

'Public Property Let Name(value As String)
'    firstName = value
'End Property
_

_Module1_に戻り、_Class1_のインスタンスを作成し、_c.Name(_と入力します。

enter image description here

ああ、何かを期待するインテリセンス?驚くばかり!

この時点で、Getプロパティが_first + last_ 現時点では両方とも空を返すことを理解する価値があります。したがって、c.Name()に何を渡すかは問題ではありません。空の文字列を返します。

では、コメントを外して、Letプロパティを調整しましょう...

サイドノード:_Module1_に戻って_c._と入力し、インテリセンスを取得しない場合、これは_Class1_の何かが壊れていることを意味します。 ..私たちはすでに知っています-それを引き起こしているのはLetプロパティです

Getプロパティにパラメーターを追加しました。Letプロパティで同じことをしましょう...

_Public Property Let Name(first As String, value As String)
    firstName = value
End Property
_

_Module1_に戻り、Letプロパティを使用してみましょう。

以前にLetプロパティをどのように使用したかを覚えていますか?あなたはそれに値を割り当てる必要がありました

_c.Name = "John"
_

しかし、現在、Letプロパティには、追加のパラメーター_first as String_が必要です。

これを試してみませんか:

_c.Name("John") = "Smith"
_

おい!コンパイルして実行する(簡単な F5

結果を確認しましょう。

_Debug.print c.Name("John")
_

ええと...イミディエイトウィンドウにSmithのみを表示します(Ctrl+G)...正確に私たちが探していたものではありません...

Letプロパティに戻ると、引数を介して2つの値を取得していることに気付きましたが、そのうちの1つだけを使用していますか?関数には2つの異なる値がありますよね?最初のものをfirstNameとして扱い、2番目のものをlastNameとして扱いましょう

_Public Property Let Name(first As String, last As String)
    firstName = first
    lastName = last
End Property
_

_Module1_に戻る

_Sub Main()

    Dim c As New Class1

    c.Name("John") = "Smith"

    Debug.Print c.Name("John")

End Sub
_

現在のコードを再実行すると、必要なものが得られます... John Smithと出力されますがwait !!!フルネームを取得するためになぜ名を渡す必要があるのですか

ハ!これの秘訣は、両方のプロパティの最初のパラメーターを作成することです Optional

要約すると、コード:

Class1.cls

_Private firstName As String
Private lastName As String

Public Property Get Name(Optional first As String) As String
    Name = firstName & " " & lastName
End Property

Public Property Let Name(Optional first As String, last As String)
    firstName = first
    lastName = last
End Property
_

Module1.bas

_Sub Main()

    Dim c As New Class1

    c.Name("John") = "Smith"

    Debug.Print c.Name ' prints John Smith

End Sub
_

したがって、基本的にLetプロパティによる2つの(以上)値の割り当ては、VBAで可能です。少し気を悪くするかもしれませんが、その構文ですが、この回答での私の説明が、どこから来たのか、なぜそうなのかを理解するのに役立つことを願っています。

Getプロパティはオプションのパラメーターを受け取ります-それは実際には単なるダミーパラメーターです... Getプロパティ内では使用されませんが、これにより、目的のLetシグネチャを取得し、2つのパラメータを渡すことができます。また、覚えやすい_c.Name_構文も使用できます。

呼び出し

_Debug.Print c.Name("first")
_

それでも可能ですが、_"first"_パラメータはダミーのように機能し、実際の基になるデータには影響しません。これはダミーであり、実際のデータには影響しません-ダンプして使用します。

_Debug.print c.Name
_

間違いなくより便利です:)

17
user2140173

これを実行するには、クラス内でPublic Subプロシージャとして使用します。

Public Sub testing()
Dim myPerson As New Person
myPerson.SetName "KaciRee", "Software"

End Sub

個人クラス:

Dim pFirstName As String, pLastName As String

Public Property Let FirstName(FirstName As String)
    pFirstName = FirstName
End Property

Public Property Get FirstName() As String
    FirstName = pFirstName
End Property

Public Property Let LastName(LastName As String)
    pLastName = LastName
End Property

Public Property Get LastName() As String
    LastName = pLastName
End Property

Public Sub SetName(FirstName As String, LastName As String)
pFirstName = FirstName
pLastName = LastName
End Sub
3
KacireeSoftware