• ベストアンサー

ExcelのVBA。Staticな変数について

あるプロシージャやfunctionで定義したstaticな変数は、その定義したsubやfunctionで有効です。今回、例えば、static a as integer とSub AAA 内で、定義し、その AAA が呼び出す BBB という ユーザーフォームの中でも staticな変数である a に値を代入したり、変更したりし、その後 sub AAAにまた入ったとき、BBBで変更した内容を保持することができるのでしょうか。

質問者が選んだベストアンサー

  • ベストアンサー
  • Wendy02
  • ベストアンサー率57% (3570/6232)
回答No.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

qso
質問者

お礼

ありがとうございます。とっても参考になりました。 >Classも構造体も、エラーが発生すると、変数は飛んでしまいます。実務では、CustomDocumentPropertyのみです。 何よりもこれが参考になりました。実務では、classも構造体も私の意図するような点では使わないということが分かりました。しかし、うまく使うと、これらには便利な点も多いですよね。使い分けが大切なんですね。ありがとうございました。これからも勉強したいと思います。

その他の回答 (2)

回答No.2

残念ながら私は、Excel VBAでpublicな変数(別プロシジャーからアクセスできる)を定義する方法を知りません。 あきらめて、非表示シートを作成してセル渡しにすることにしました。 引数渡しが素直な解だと思いますが往々にして渡す情報が増えてしまうので(まじめに設計していないのが悪いのですが)、共有メモリのようなイメージでセルを使うようにしました。 セルは確実な方法だと思います。

qso
質問者

補足

ありがとうございます。 私もシートを非表示にしてセルに値を入れてマクロを組みました。ただ、どうも、これが悔しいんですよね。エレガントではなく。そう思って質問しました。でも、できないのは私の力不足でなく、そういうものだと分かっただけでも納得できます。ありがとうございます。

回答No.1

>その定義したsubやfunctionで有効です。 これが回答のすべてです。 フォームを呼び出しているということは、AAAというプロシージャを超えています。 もし、BBBでaという変数を使いたい場合は、パラメータとして渡すしかありません。 または、Staticではなく、Private変数またはPublic変数として使うかですね。 ちなみにパラメータで渡せば、質問されている内容はクリアできますよ。

qso
質問者

補足

ありがとうございます。確かに、定義した範囲内がスコープですよね。 パラメータとして渡す場合、それが少数なら苦ではないのですが、たくさんあると、めんどくさくなってしまいます。そこで、例えばほんの3つとか5つだけのsubとかfunctionだけに使う共通のデータがあった場合、その間で限定的に使える変数などの定義方法があったら便利だなあ、と思って質問しました。やっぱりないんですよね。パラメーターで渡します。ユーザー定義の型を使うと渡すのもかなり楽になりますよね。ありがとうございました。

関連するQ&A