- ベストアンサー
ExcelのVBA。Staticな変数について
あるプロシージャやfunctionで定義したstaticな変数は、その定義したsubやfunctionで有効です。今回、例えば、static a as integer とSub AAA 内で、定義し、その AAA が呼び出す BBB という ユーザーフォームの中でも staticな変数である a に値を代入したり、変更したりし、その後 sub AAAにまた入ったとき、BBBで変更した内容を保持することができるのでしょうか。
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
Public 変数側の回答をしてこちら側にも、少し触れておきます。 たぶん、Static 変数と、Public 変数と同じことです。 具体例のない質問なので、お互いがお互いのイメージの中で語られることになって、実体のない応答になるのは仕方がないのですが、まず、スタイルにこだわる前に、エラーのないコードを作ることが第一番ですね。エラーの可能性がみえているのに、それを無視したコードは、いくら格好をつけても、ダメだということです。 >例えばほんの3つとか5つだけ……共通のデータがあった場合、その間で限定的に使える変数などの定義方法があったら便利……。 その共有データの内容にもよりますね。以前も、Function使用する共有変数という質問をみましたが、正直なところ、その回答群は、どれも満足したものがありません。せっかくだから、私は、滅多に使いませんが、三種類用意しておきますが、どれも中級以上のテクニックです。Classも構造体も、エラーが発生すると、変数は飛んでしまいます。実務では、CustomDocumentPropertyのみです。 'CustomDocumentProperty を利用する方法 '標準モジュール Sub Auto_Open() '起動時に設定 Dim ret As Variant Dim dum As Variant On Error GoTo ErrHandler With ActiveWorkbook ret = Application.InputBox("数値を入れてください。", "Input", Type:=1) dum = .CustomDocumentProperties("MyData") If VarType(ret) = vbBoolean Then Exit Sub .CustomDocumentProperties("MyData").Value = ret End With Exit Sub ErrHandler: With ActiveWorkbook.CustomDocumentProperties .Add Name:="MyData", _ LinkToContent:=False, _ Type:=msoPropertyTypeNumber, _ Value:=0 '数値型 End With Resume Next End Sub Sub Test1() MsgBox TestFunc(5) End Sub Function TestFunc(arg As Variant) Dim var1 As Variant var1 = ActiveWorkbook.CustomDocumentProperties("MyData") If arg <> "" Then TestFunc = var1 + arg End If End Function '****** 'Class のプロパティを使う方法 '***** '標準モジュール Public myClass As New Class1 '(実務では、プロシージャ内でオブジェクトを生成してください) Sub Auto_Open() myClass.myVal = 12 End Sub Sub Test2() MsgBox myClass.myVal End Sub '---- 'Class1 Private propertyVal As Variant Public Property Get myVal() As Variant myVal = propertyVal End Property Public Property Let myVal(ByVal NewValue As Variant) propertyVal = NewValue End Property '****** '構造体を使う方法 '****** Type strctPerson Name As String Family As String AGE As Integer Birth As Date End Type Dim psn As strctPerson Sub TestStructure() psn.AGE = 31 psn.Birth = #2/18/1980# psn.Family = "Helten" psn.Name = "London" End Sub Sub Test3() MsgBox psn.Family & " " & psn.Name & " 年齢:" & psn.AGE End Sub
その他の回答 (2)
- いけだ ひろし(@ike-2000)
- ベストアンサー率53% (69/129)
残念ながら私は、Excel VBAでpublicな変数(別プロシジャーからアクセスできる)を定義する方法を知りません。 あきらめて、非表示シートを作成してセル渡しにすることにしました。 引数渡しが素直な解だと思いますが往々にして渡す情報が増えてしまうので(まじめに設計していないのが悪いのですが)、共有メモリのようなイメージでセルを使うようにしました。 セルは確実な方法だと思います。
補足
ありがとうございます。 私もシートを非表示にしてセルに値を入れてマクロを組みました。ただ、どうも、これが悔しいんですよね。エレガントではなく。そう思って質問しました。でも、できないのは私の力不足でなく、そういうものだと分かっただけでも納得できます。ありがとうございます。
- waterline123
- ベストアンサー率43% (51/116)
>その定義したsubやfunctionで有効です。 これが回答のすべてです。 フォームを呼び出しているということは、AAAというプロシージャを超えています。 もし、BBBでaという変数を使いたい場合は、パラメータとして渡すしかありません。 または、Staticではなく、Private変数またはPublic変数として使うかですね。 ちなみにパラメータで渡せば、質問されている内容はクリアできますよ。
補足
ありがとうございます。確かに、定義した範囲内がスコープですよね。 パラメータとして渡す場合、それが少数なら苦ではないのですが、たくさんあると、めんどくさくなってしまいます。そこで、例えばほんの3つとか5つだけのsubとかfunctionだけに使う共通のデータがあった場合、その間で限定的に使える変数などの定義方法があったら便利だなあ、と思って質問しました。やっぱりないんですよね。パラメーターで渡します。ユーザー定義の型を使うと渡すのもかなり楽になりますよね。ありがとうございました。
お礼
ありがとうございます。とっても参考になりました。 >Classも構造体も、エラーが発生すると、変数は飛んでしまいます。実務では、CustomDocumentPropertyのみです。 何よりもこれが参考になりました。実務では、classも構造体も私の意図するような点では使わないということが分かりました。しかし、うまく使うと、これらには便利な点も多いですよね。使い分けが大切なんですね。ありがとうございました。これからも勉強したいと思います。