プロが教える店舗&オフィスのセキュリティ対策術

Excel2002Sp3を使用しています。
(WindowsはXpSp3です)

ユーザー定義型の各メンバーに対して、property get/let/set
を使用してデーターの受け渡しを行いたいのですが、うまくいきません。
以下に作成したプログラムを載せてみます。

main1()とmain2()がありますが、
main2()だとうまくいきます。
しかし、メンバー個別のやりとりにはなっていません。

main1()のようにメンバー個別でやりとりできるようにする方法がわかりません。

property get/let/setの書き方でできるようになるのでしょうか。
それとも、メンバー個別でのやり取りは仕様上できないのでしょうか。

もしできるのであれば、サンプルコードを教えていただけると助かります。
よろしくお願いします。

-------------------
Class1
-------------------
Option Explicit

Private m_xx As X

Public Property Get xx() As X
xx = m_xx
End Property

Public Property Let xx(p As X)
m_xx = p
End Property

-------------------
Module1
-------------------
Option Explicit

Type X
a As Long
b As Long
End Type


Sub main1()
'個別にやり取り
Dim cc As New Class1

Dim p As Long
Dim q As Long

cc.xx.a = 5
cc.xx.b = 2

p = cc.xx.a
q = cc.xx.b

MsgBox p & "," & q

End Sub


Sub main2()
'yyを用意してまとめてやり取り
Dim cc As New Class1

Dim p As Long
Dim q As Long
Dim yy As X

yy.a = 5
yy.b = 2

cc.xx = yy

p = cc.xx.a
q = cc.xx.b

MsgBox p & "," & q

End Sub

----------------------------------------

A 回答 (3件)

#1 Wizard_Zeroです。



> これはVS2005等でもできないのでしょうか。

できません。そのようなコードを書いた時点でエラーが提示され、コンパイルできなくなります。


> Type XX・・・
> ごとにクラスを作るという理解でよろしいでしょうか。もしやるとなるとファイル数、すごく増えますね。

そうなりますね。
(クラス定義部分だけActiveX DLL化するという手もありますが・・・)


> 仮にそうした時、property get等の書き方はどのようになるでしょうか。

PropertyのLetとSetの違いは、扱う型が値型か参照型かです。クラスのような参照型を扱う際には、LetではなくSetを使います。

[ Class1 ]
Option Explicit

Private m_xx As New X '←クラスなのでNewでインスタンスを作成しておく

Public Property Get xx() As X
Set xx = m_xx '←戻り値の設定もSetで
End Property

Public Property Set xx(p As X)
Set m_xx = p '←ここも
End Property
    • good
    • 0
この回答へのお礼

毎回、詳しい説明をありがとうございます。
色々わかってきました。

ありがとうございました。

お礼日時:2009/07/22 17:12

class1のモジュールを個々のメンバでもlet,getできるようにしては?



[class1]
Option Explicit
Private m_xx As X
Public Property Get xx() As X
xx = m_xx
End Property
Public Property Let xx(p As X)
m_xx = p
End Property
Public Property Get a() As Long
a = m_xx.a
End Property
Public Property Let a(p As Long)
m_xx.a = p
End Property
Public Property Get b() As Long
b = m_xx.b
End Property
Public Property Let b(p As Long)
m_xx.b = p
End Property

[module1]
Option Explicit
Type X
a As Long
b As Long
End Type
Sub main1()
'個別にやり取り
Dim cc As New Class1
Dim p As Long
Dim q As Long
cc.a = 5
cc.b = 2
p = cc.a
q = cc.b
MsgBox p & "," & q
End Sub
Sub main2()
'yyを用意してまとめてやり取り
Dim cc As New Class1
Dim p As Long
Dim q As Long
Dim yy As X
yy.a = 5
yy.b = 2
cc.xx = yy
p = cc.xx.a
q = cc.xx.b
MsgBox p & "," & q
End Sub
    • good
    • 0
この回答へのお礼

個々のメンバーに対してget/letを定義するということですね。
それも考えたのですが、メンバー変数が多い時のことを考えると・・・
何か、まとめてget/letが定義できないものかと考えていました。
ありがとうございました。

お礼日時:2009/07/20 14:31

> それとも、メンバー個別でのやり取りは仕様上できないのでしょうか。



この場合は「仕様上できない」となります。
構造体をプロパティの型に利用する場合、取得する構造体の内部は暗黙的に読み取り専用と同義になります。

Sub main1()内で実行している
cc.xx.a = 5
を例に説明しますと・・・
cc.xx
の時点で、ccのxxプロパティ(Property Get)が実行されます。
Property Getの中身は
xx = m_xx
となっており、クラス内部のm_xxを戻り値として渡しているように見えますが、実際には値のみが渡されていて構造体の本体(つまりm_xx自体)が返されているわけではありません。つまり、
cc.xx
はm_xxの値をコピーしただけの「別物」ということになります。そこに値を設定してもm_xxには反映されません。

main2のほうが正しく動作するのは
cc.xx = yy
で、Property Setが呼び出されており、その中身は
m_xx = p
です。pには設定値が入りますから実質的には
m_xx = yy
となり、m_xxへyyの値をコピーしていることになります。


独自のデータ型の内部をプロパティの型として使い、さらにその内部も個別に変更できるようにするには、構造体ではなくクラスを使います。

この回答への補足

>この場合は「仕様上できない」となります。
やっぱりそうなのですか・・・
詳細な説明ありがとうございます。
これはVS2005等でもできないのでしょうか。

>独自のデータ型の内部をプロパティの型として使い、さらにその内部も個別に変更できるようにするには、構造体ではなくクラスを使います。
Type XX・・・
ごとにクラスを作るという理解でよろしいでしょうか。もしやるとなるとファイル数、すごく増えますね。
仮にそうした時、property get等の書き方はどのようになるでしょうか。

追加質問が多くてすみません。

補足日時:2009/07/20 04:04
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!