- ベストアンサー
EXCEL VBA でユーザー定義型データーをproperty get let を使って受け渡しをしたい
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 ----------------------------------------
- みんなの回答 (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
その他の回答 (2)
- hotosys
- ベストアンサー率67% (97/143)
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
お礼
個々のメンバーに対してget/letを定義するということですね。 それも考えたのですが、メンバー変数が多い時のことを考えると・・・ 何か、まとめてget/letが定義できないものかと考えていました。 ありがとうございました。
- うぃず(@Wizard_Zero)
- ベストアンサー率69% (344/495)
> それとも、メンバー個別でのやり取りは仕様上できないのでしょうか。 この場合は「仕様上できない」となります。 構造体をプロパティの型に利用する場合、取得する構造体の内部は暗黙的に読み取り専用と同義になります。 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等の書き方はどのようになるでしょうか。 追加質問が多くてすみません。
お礼
毎回、詳しい説明をありがとうございます。 色々わかってきました。 ありがとうございました。