• 締切済み

VBAのインスタンス変数識別子

お世話になります。 ExcelVBAで次のようなクラスモジュールがあるとします。 Private lngX As Long Public Property Let setX(ByVal lngX As Long) Debug.Print lngX End Property ここで、3行目のlongXはローカル変数としてのlngXが参照されていますよね。このプロシージャの中で、ローカル変数と同名のインスタンス変数を参照するにはどのようにすればよいのでしょうか。 Javaでは this.lngX、VB.NETでは Me.lngX とすればよいと思うのですが、VBAにはこのような識別子は用意されていないのでしょうか。当方の環境はExcelVBAですが、VB6でもおなじだと思いますのでそちらではどうなっているかでもかまいません。 宜しくお願い致します。

  • pippy
  • お礼率82% (38/46)

みんなの回答

  • Wendy02
  • ベストアンサー率57% (3570/6232)
回答No.5

こんにちは。#4 です。 >lngX = myX >でも用は足りるのですが、もしも >Me.lngX = lngX >というコードが許されるのであれば、 >その方が(少なくとも私にとっては)可読性が高くなりますので、そのようなコードにしようかな、と。 釈迦に説法かもしれませんが、それは、外部から内容を読めないように隠してあるのですね。 わざわざ、 Private lngX As Long としている所以です。そうでなければ、Public にします。しかし、こういうのって、VBAに関してのみに限定すると、私は使ってはいますが、何か形だけの話のような気がします。

  • Wendy02
  • ベストアンサー率57% (3570/6232)
回答No.4

こんばんは。 たとえば、VB6/VBA とVB.Net では、Class の扱い方がまったく違いますから、Me.lngX などという使い方は皆無に近いというよりも、出来るけれども、意味がありません。 VBAでは、通常、以下のような書き方をします。ただし、クラスモジュール内変数-lngX は、Private にするのが正しい使い方です。ただ、VBAで、具体的にどのような仕事をさせるか分かると、また別の方向に話がいくと思いますが、VBAでは、こうした使い方は、めったに出てきません。 ------------------------------------------ 'Class1 モジュール Private lngX As Long Public Property Let X(ByVal myX As Long)    lngX = myX    Debug.Print lngX End Property ------------------------------------------ '標準モジュール Dim myClass As Class1 Sub Test1() Set myClass = New Class1  myClass.X = 10 End Sub

pippy
質問者

補足

どうもありがとうございます。 > 具体的にどのような仕事をさせるか分かると、また別の方向に話がいくと思いますが、 JavaBeanのようなデータモデルを表すクラスのセッタ、ゲッタ内での利用を想定しています。 引用していらっしゃるクラスモジュールのように、これまでインスタンス変数とローカル変数のプレフィックスを変えることで対応してきましたが、ひょっとしたらVBAにも識別子があるのでは・・・と思って質問致しました。 lngX = myX でも用は足りるのですが、もしも Me.lngX = lngX というコードが許されるのであれば、その方が(少なくとも私にとっては)可読性が高くなりますので、そのようなコードにしようかな、と。

  • nidoking
  • ベストアンサー率69% (18/26)
回答No.3

色々やってみたら、 lngXのClass内での宣言を、publicとすると、 Property内からMe.lngXでインスタンス変数を参照できました。 この場合、Moduleからも、obj.lngXで参照可能となってしまいますが・・・ 仕様なんでしょうが、Meの参照範囲のバグっぽいですね

  • nidoking
  • ベストアンサー率69% (18/26)
回答No.2

module名.lngX と指定すると、moduleスコープの変数にアクセスできます。

pippy
質問者

補足

ありがとうございます。 標準モジュールではたしかにうまく行きました。しかしクラスモジュールではモジュール名を指定しても「変数が定義されていません」と表示されてコンパイルが通りません。VB6だと違った結果になるのでしょうか。

  • dsuekichi
  • ベストアンサー率64% (171/265)
回答No.1

多分できないと思いますよ。 ExcelVBAやVB6での「Private」の扱いが、VB.NETとかとは違いますから・・・ VB.NETとかでは、同一クラスなら、別のインスタンスのPrivate属性の変数を参照可能ですよね? しかし、VBAやVB6では、クラスが同一かどうかに関らず別のインスタンスのPrivate属性の変数は参照できません。 #Private属性は、「自分自身のインスタンスからしか参照できない」と言う制限になっています。 その制限を実現するために、「インスタンスを指定してPrivate変数を参照する」事自体できなくなってしまっています。 別の名前にするしかないと思います。

関連するQ&A

  • 配列をプロシージャの変数としたい

    ExcelVBAです。 Sub Test(ByRef i as Long , BuVal j as Long) のように、SUBプロシージャのカッコ内に変数をおき、他のプロシージャから呼び出して使うような場合についてですが、その変数を配列にしたいのですが、書き方が分かりません。 Sub Test(ByRef MyArray()) というようにしたらできるかと思ったのですが、できません。 よろしくお願いいたします。

  • インスタンスとオブジェクト

    こんばんは。 変数について教えて下さい。 プログラム自体が初めてなので 「たのしい Ruby 第3版」を読んでいます。 ずっとインスタンスとオブジェクトの違いが曖昧なままです。 その本の「クラスとモジュール」という章にて クラスを定義する構文。 インスタンス変数とローカル変数の違いですが、 以下の説明で一部理解できずにつまずいています。 ―――――――――――― @ で始まる変数は インスタンス変数 といいます。 ローカル変数はメソッドごとに異なる変数として扱われますが、 インスタンス変数は同じインスタンス内であれば、 メソッド定義を超えてその値を参照したり、変更したりできます。 なお、初期化されていないインスタンス変数を参照すると nil が得られます。 インスタンス変数は、インスタンスごとに違う値を持つことができます。 またインスタンス変数は、 インスタンスがある間は値を保持しておいて 何度でも利用することができます。 一方、ローカル変数はメソッド呼び出しごとに新しく割り当てられるため、 メソッドから抜けると値を忘れてしまいます。 ―――――――――――― ここで分からないのは、 ・ローカル変数が "メソッドごと" に異なる変数として扱われる ・インスタンス変数は同じ "インスタンス内" であれば、 メソッド定義を超えてその値を参照したり、変更したりできます の部分です。 Webで検索してますが、 プログラミング経験ありを前提で書かれているような。 他の言語も知らないので分からない、そんなページが多いです。 人に聞くからには 自分でも頑張って理解できるように考えますので、 どうか回答よろしくお願いします。

    • ベストアンサー
    • Ruby
  • クラス変数/メソッドとインスタンス変数/メソッドの見え方について

    Javaの言語仕様(?)についてお教え下さい。 参照変数の型がインスタンスのスーパークラスの型の時、クラス変数/メソッドとインスタンス変数/メソッドの見え方が納得いかずに困っています。 以下のような条件の時です。   ・クラスが2つあり、1つはもう1つのクラスを継承しています。     それぞれを「スーパー」「サブ」と以下で呼びます。   ・インスタンスは"サブ"の型です。   ・上記インスタンスへの参照変数は"スーパー"のクラスの型です。   ・"スーパー"、"サブ"ともに【同名】の「クラス」変数/メソッド、「インスタンス」変数/メソッドがあります。 この場合に、"サブ"のインスタンスを参照している"スーパー"の型の変数を介し、それらにアクセスしたらどれが見えるか?という疑問です。 実験結果では以下のようになりました。           [フィールド]  [メソッド]   [1.static ]  スーパーの   スーパーの   [2.非static]  スーパーの   サブの 納得いかないのは「2.非static」で「フィールド」が、「スーパーの」になるところです。 これも「サブの」になると思っていました。 なぜサブクラスのが見えないのでしょうか? 同名の変数なのでスーパークラスのはサブクラスので隠れされ、サブクラスのが見えると思っていたのですが。 参考書には以下のように書いてありました。   フィールドの場合、参照変数の型のものが見える。   メソッドの場合、インスタンスの型のものが見える。 私には不自然に感じられるのですが、「こういう仕様だから。」と納得するしか無いのでしょうか? 「なぜこうなるか」について説明がある文献、サイトなどありましたらお教えください。 参考までに以下が実験したサンプルコードと結果です。長くて申し訳ありません。 「サンプルコード」 public class Super { static int staticField = 10; int instanceField = 100; static void staticMethod() { System.out.println( "staticField = " + staticField ); } void instanceMethod() { System.out.println( "instanceField = " + instanceField ); } } public class Sub extends Super { static int staticField = 90; int instanceField = 900; static void staticMethod() { System.out.println( "staticField = " + staticField ); } void instanceMethod() { System.out.println( "instanceField = " + instanceField ); } } public class TestStatic { public static void main(String[] args) { // インスタンスはSub、参照変数もSub、という状態。 Sub sub = new Sub(); System.out.println( "実験1" ); System.out.println( "1.クラス変数      " + sub.staticField ); System.out.print( "2.クラスメソッド    " ); sub.staticMethod(); System.out.println( "3.インスタンス変数   " + sub.instanceField ); System.out.print( "4.インスタンスメソッド " ); sub.instanceMethod(); // インスタンスはSub、参照変数はSuper、という状態。 Super sup = new Sub(); System.out.println( "実験2" ); System.out.println( "5.クラス変数      " + sup.staticField ); System.out.print( "6.クラスメソッド    " ); sup.staticMethod(); System.out.println( "7.インスタンス変数   " + sup.instanceField ); System.out.print( "8.インスタンスメソッド " ); sup.instanceMethod(); } } 「結果」 実験1 1.クラス変数      90 2.クラスメソッド    staticField = 90 3.インスタンス変数   900 4.インスタンスメソッド instanceField = 900 実験2 5.クラス変数      10 6.クラスメソッド    staticField = 10 7.インスタンス変数   100 8.インスタンスメソッド instanceField = 900 納得が行かないのは7のところです。 以上よろしくお願いいたします。

    • ベストアンサー
    • Java
  • インスタンス変数とローカル変数のスコープの違い

    Ruby言語を独学で勉強している者です。 現在たのしいRuby第3版という著書を参考にして勉強しています。 現在はクラスの継承、クラス文の定義の仕方を学んでいます。 そこで教えて欲しいのですが、 ローカル変数とはメソッドごとに異なる変数として扱われる。 インスタンス変数は同じインスタンスの中であればメソッドの定義を越えて その値を参照したり変更したりできるとあります。 そもそもインスタンスとは、オブジェクトとおほ同意義と捉えてるのですが この認識に間違いはないでしょうか。 ニュアンス的なものは理解したのですが、もう少しこの二つの変数の定義について 理屈を把握したいので、お手すきなお方がいらっしゃいましたら、具体的な例をあげて ご説明くださいませんか・・・。 この本すごく素人にもわかりやすい丁寧な解説で書いてあって、決して説明不足とは 思わないのですが、プログラマーさんの意見なども参考にしたくて投稿してみました。

    • ベストアンサー
    • Ruby
  • VBAのクラスのインスタンス化のタイミングについて

    こんにちはvbaのクラスのインスタンス化について質問があります。 私は普段使えないイベントを使用するときにクラスモジュールに WithEventsを使ってイベントを作成し それをプロシージャからインスタンス化して 作成したイベントを有効にするという手法をよく使います。 Excelのように最初からワークブックにイベントがある場合は、 ワークブックを開いたと同時にWorkbook_Openプロシージャから クラスをインスタンス化して作成したイベントを有効にするということが可能なのですが、 CATIAやInventorなど、一部のアプリケーションでは、 最初から使えるイベントが見つからず、 Subプロシージャでインスタンス化する方法しかみつかりません。 しかし、Subプロシージャを実行させるためには、 ボタンなどユーザー側に何らかのアクションとってもらうしかなく、 自動化するために作成したイベントなのに、そのイベントを有効にするために ユーザーにボタンを押してもらうという矛盾した構成になってしまいます。 クラスをインスタンス化する方法はSubプロシージャに記述するしかないのでしょうか? 自分がよく使っているコードを下に記述します。 下の例は、Excelで新しくブックを開いたときにメッセージを出すプログラムです。 アプリケーションレベルのイベントをクラスモジュールで作成しています。 これを有効にするためには標準モジュール内の Event_ONプロシージャを実行しなければなりません。 モジュールを実行する前まではいくら新しいブックを開いてもメッセージは出ません これをどのうようにしたらいいかご教授ください。 Excelの例 Classモジュール「Class1」に記述 -------------------------------------------------------------------- Private WithEvents APP As Application Private Sub APP_NewWorkbook(ByVal Wb As Workbook) MsgBox "新しいブックが開かれました" End Sub Private Sub Class_Initialize() Set APP = Application End Sub -------------------------------------------------------------------- 標準モジュール「Module1」に記述 -------------------------------------------------------------------- Dim CLS As class1 Public Sub Event_ON() Set CLS = New class1 End Sub --------------------------------------------------------------------

  • 変数の命名

    すみません...教えていただきたいのですが、 どんな言語でも良いのですが、(私は現在、vb2005とobjective-cを使用しています。) アクセッサ内などで同じものについての変数の命名にいつも悩んでしまいます。 皆さんは、外に見えない変数名には記号的な文字列を使っていますか? どんな感じで命名していますか? よろしくお願いします。 苦労してこんな感じでつけています。 Protected identifier As String Public Property nodeID() As String Get Return identifier End Get Set(ByVal id As String) identifier = id End Set End Property

  • Excel VBA onTime関数のプロシージャ引数に、引数(変数)つきのプロシージャを呼び出す方法を教えてください。

    現在ExcelVBAで一定時間ごとにメッセージを出すツールを作成しています。 その際にonTime関数を使っていますが、その引数のひとつである呼び出すプロシージャに「引数(変数)つきのプロシージャ」を設定しようとしています。 サイトを探してみたところ、引数にシングルクオーテーションで囲むなど書いてあったのですが、変数を引数としたプロシージャを設定すると、「プロシージャが見つかりません」のエラーがでます。 どなたかお力を貸してくれませんでしょうか。 ちなみに僕のコードは以下の通りです。(簡略化) ------フォーム Private Sub cmbOk_Click() Call メッセージ実行(txtTime.Text, txtContent.Text) End Sub ------ThisWorkbook Private Sub メッセージ実行(ByVal time As String, ByVal content As String) Dim starttime As Double MsgBox time & "毎に" & vbCr & content & vbCr & "を表示します。", vbInformation Unload frmSet starttime = Now + CDbl(TimeValue(time)) Application.OnTime starttime, "'expressContent" & time & content & "'" End Sub ------標準モジュール Dim starttime2 As Double Sub expressContent(ByVal time2 As String, ByVal content2 As String) MsgBox "content2", vbInformation starttime2 = Now + CDbl(TimeValue(time2)) Application.OnTime starttime2, "'expressContent" & time & content & "'" End Sub よろしくお願い致します。

  • VB.NETで変数の宣言が上手くできません

    VB.NETで変数の宣言が上手くできません プロパティを使用し、変数の内容を一括保存しようと考えています その為に以下のようなコードを書いたのですが他のフォームから宣言されていないとなってしまいます 修正点を教えて頂けると嬉しいです Setting.vb Pubic class Settings Public dbdirectry As String Public flistpass As String Public Property flist () As String Get Return flistpass End Get Set (Byval Value As String) flistpass = Value End Set End Property もう一つflist () をdbdic ()に flistpassをdbdirectryにしたもの End Class この変数2つに他のフォームMainForm1.vbとDefaultSetting.vbなどからflistpass = Newflistpassなどと記述するとアクセス出来ず宣言していない扱いになります Publicでの宣言で大丈夫だと思ったのですが間違えているのでしょうか?

  • 変数の参照でエラーが出てしまいます。(VB.NET)

    プロシージャの外に記した変数があるのですが、 (Dim IniFileName as string = "myapp.ini")など Public Shared Sub 内でIniFileNameを使おうとすると --------- クラスの明示的なインスタンスを指定しないで、共有メソッドまたは共有メンバ初期化子内からクラスのインスタンス メンバへ参照することはできません。 --------- というエラーが出てしまいます。 クラスの明示的なインスタンスを指定したいのですが、 意味がさっぱり分かりません。 class.IniFileNameとかForm1.IniFileNameなどとしてみたのですが違うようです。 一つ正解をご教示頂けたらと思います。 宜しくお願い致します。

  • 【Excell VBA】ユーザーフォーム上のスプレッドシートのセルを選択したときのイベント

    Excell VBA にて、 ユーザーフォーム(userForm1)に、スプレッドシートを 1)その他のコントロール 2)Microsoft Spreadsheetを追加 によって追加して、 そのspreadSheet1上のsheet1の任意のセル(D:*)をクリックしたとき、その行のD1:D5k一連の値を変数に代入したいのですが、 まず手始めとして、そのセルを選択したときにイベントを発生させたい。  該当のセルを選択してプロシージャを追加すると Private Sub Spreadsheet1_BeforeContextMenu( _ ByVal x As Long, _ ByVal y As Long, _ ByVal Menu As OWC11.ByRef, _ ByVal Cancel As OWC11.ByRef _ ) となります。 比較のため Private Sub Spreadsheet1_SelectionChange(ByVal Target As Range)   If Target.Address() = "$A$1" Then     MsgBox "このセルはA1です。"   End If End Sub だと、 Error・・・「コンパイル エラー: プロシージャの宣言が、イベントまたはプロシージャの定義と一致していません。」 ・・・どうすればよいのでしょう。 最終的には、「その行のいくつかの値を変数に代入したい」のですが

専門家に質問してみよう