• ベストアンサー

クラスの設定について

変数をクラスに設定するときのコードの書き方ですが、 sub プロシージャー名() dim m as クラス名 set m = new クラス名 ・・・・ end sub と sub プロシージャー名() dim m as new クラス名 ・・・・ end sub とかいても(簡単なプログラムでは)同じ働きをするのですが 違いはあるのでしょうか。

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

  • ベストアンサー
回答No.2

[Aタイプ] As New Class1 [Bタイプ] As Class1 = New Class1 .NETであれば、どちらでもよいと思います。 .NETではないVBや、VBAでは、私個人としてはBタイプはお勧めしません。 あるメーリングリストの請負いなのですが、As New撲滅推進キャンペーンをしておりました。 (.NETがまだない時代からのメーリングリストです) Bタイプの Dim 変数 As New Class1 で Set 変数 = Nothing としても変数がNothingされず、再度「New Class1」がセットされるようです。 その結果、無駄にメモリを消費し続けるという状態になるようです。 しかし.NETからは、Nothingはされるので、どちらでもよいと思います。

tk516ncb
質問者

お礼

ありがとうございます。 .NETであれば変わらないがVBの場合 最後にSet=Nothingで初期化?しますが、それができてなくメモリを食ってしまうのですね。

その他の回答 (3)

回答No.4

#2です。 メーリングリストの内容を一部引用します。 Dim rs As New ADODB.Recordset の場合,rs が参照されるところではつねに If rs Is Nothing Then   Set rs = New ADODB.Recordset End If というコードが暗黙のうちに挿入されているということになります。 結果毎回判定を行い、小規模のプロジェクトであれば気にする必要のレベルではないかも知れないけど、処理速度が遅くなってしまうという欠点があるそうです。 私の環境にVB6のMSDNがインストールされていないのですが、、、 上記のような発言をされた方は、MSDNの以下の項を読むように、言っておりました。 [Visual Studio 6.0 ドキュメント] └[Visual Basic ドキュメント]  └[Visual Basic の使用方法]   └[プログラミング ガイド]    └[Visual Basic を使ってできること]     └[各種のコンポーネントを利用したプログラミング]      └[オブジェクトへの参照の作成方法]       ├       :       :       └

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

その変数に対するオブジェクトの生成を1回しかやらない(明示的にNothingを代入しない)なら、違いはほとんどありません。 「As New」を指定しない場合、一旦、その変数にNothingを設定してオブジェクトを破棄した後に、 再度その変数でオブジェクトを使用しようとした場合、もう一度 明示的に「= New」 を実行しなければなりません。 #そうしないとエラーになる。 「As New」を指定した場合、オブジェクトを破棄した後、 再度その変数でオブジェクトを使用しようとした場合、自動的に「New」が実行されます。 #その変数を再度アクセスしない限りNewは実行されません。 #便利な反面、オブジェクトの生成・破棄のタイミングが分かりにくくなります。

tk516ncb
質問者

お礼

ありがとうございます。 クラスを複数回使う(通常は当たり前なのですが)この場合、As Newとすれば自動的に「New」が実行されるのなら dim m as new class1 の方がいいですね。 ただ、オブジェクトの生成・破棄のタイミングが分かりにくくなりますため一長一短があるということですね。

回答No.1

違いはないと考えてよいです。 Dim m As New クラス名 の場合、実際にインスタンスが生成されるのは、最初に m が参照されるときですが、違いができるとすれば、インスタンスが生成されるタイミングくらいではないでしょうか。

tk516ncb
質問者

お礼

ありがとうございます。setでインスタントを生成するか、dimでインスタントを生成するかの差なのですね。

関連するQ&A

  • VBAでクラス設定

    (標準モジュール) Option Explicit Sub test() Dim Class As Class1 Set Class = New Class1 Class.Obj = 1000 Set Class = Nothing Set Class = New Class1 Range("a1").Value = Class.Obj Set Class = Nothing End Sub (クラスモジュールClass1) Option Explicit Private a As Integer Public Property Get Obj() As Integer Obj = 2000 End Property Public Property Let Obj(ByVal NewNumber As Integer) a = NewNumber End Property 上のマクロではやり取り1変数になってますがこれを配列に変えたいのですがどうすればいいでしょうか?

  • VBA クラスモジュールについて

    http://www.excellenceweb.net/vba/class/what_vba_class.html を見ながらクラスモジュールの勉強をしているのですが 躓きました。 新規にクラスモジュールを挿入し オブジェクト名に果物売上と名付けました。 そこに、 Sub TEST() Dim Apple As 果物売上 Set Apple = New 果物売上 End Sub と入力しました。 そして標準モジュールを挿入し、 そこに Sub TEST() Dim Apple As 果物売上 Set Apple = New 果物売上 With Apple .名前 = "リンゴ" .価格 = 100 .在庫 = 20 .仕入数 = 50 End With With Apple Debug.Print .名前 End With End Sub を入力しました。 そして、デバッグすると 「Apple As 果物売上」の部分が コンパイルエラーになってしまいます。 全然クラスモジュールの使い方がわからないのですが どこを直せばいいのでしょうか?

  • 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 --------------------------------------------------------------------

  • VB6.0のクラスで、自分自身のインスタンスを作成するメリット

    クラスのメソッドで、自分自身のインスタンスを作成している、コードをよく見かけます。 どんなメリットがるのでしょうか? 簡単に、クラスファイルのコードを書きました。 【A.cls】 Option Explicit Dim pstrID As Long Dim pstrName As String Public Function fncCreate() As Object     Set fncCreate = New clsA  '★自分自身のインスタンスを作成する End Function Public Function fncID() As Boolean     pstrName = "ID" End Function Public Function fncName() As Boolean     pstrName = "STRING" End Function Private Sub Class_Initialize()     pstrID = 0     pstrName = "" End Sub

  • Visual Basic 2005 クラスライブラリの使い方

    異なるクラス間で共通の変数aを使いたいのですが、うまくいきません。あるクラスForm1でaを宣言しても他のクラスClass1でも宣言しないとエラーが出てしまいます。 以下のクラスをデバイスアプリケーションとして作成し、 Public Class Form1 Public a As Integer = 100  Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Dim Test As New MyLibrary.Class1 Test.Plus1() MsgBox(a, MsgBoxStyle.Information, "実験") End Sub End Class 以下のクラスをクラスライブラリMyLibraryとして作成します。 Public Class Class1 Dim a As Integer = 0 Public Sub Plus1() a += 1 End Sub End Class Form1でボタンを押すと、メッセージボックスに100と表示されます。 (関数Plus1の効果なし) ちなみにClass1の「Dim a」を「Static a」にしてクラスライブラリ(DLL)を最初に呼び出したときだけ初期化すればよいと思ったのですが、そうすると「'Static' は、メンバ変数宣言では有効ではありません。」というエラーが出てしまいます。 解決方法をご存知の方、ご教授願います。 また、クラスライブラリ(DLL)を作成するとまとまりができてプログラムの変更がしやすいと思いますが、やはり処理速度が遅くなるなどの問題もあるのでしょうか?

  • クラスに配列を渡す方法

    こんにちは、VB.NET初心者です。 メインプログラムからクラスに配列を渡したいのですが、どうやって渡せばいいのかわかりません。 一応、いろいろなサイトやMSDNを覗いたのですが、よく分かりませんでした。 よろしければ、教えてください。環境はVB2005です。 下記のは現在書いているソースなのですが、この場合エラーがでます。 メインプログラム Private Sub button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles button1.Click  Dim abc() as integer  ’配列に何かを入れる処理を記述  ’何個の要素が入るかはわかりません。通るときによって変わります。  Dim 123 As New clsAAA  123.ABC = abc  123.処理1() End Sub clsAAA Private pABC() As Integer Public Property ABC() As Integer  Get   Return pABC  End Get   Set(ByVal value As Integer)   pABC = value  End Set End Property

  • クラスモジュールについて

    下記のコードは平均値を出すコードを作ったのですが、B列に文字列を含むとエラーになってしまいます。なのでB列に数字以外のものが入っている状態でも動くようにしたいのですが、お詳しい方アドバイスお願いします。 ' 標準モジュール Public Sub 平均値() Dim dct As Object Dim bot As Long Dim k As Variant Dim r As Long Dim itm As Class1 Set dct = CreateObject("Scripting.Dictionary") bot = Cells(Rows.Count, "A").End(xlUp).Row For r = 2 To bot k = CStr(Cells(r, "A").Value) If dct.Exists(k) Then Set itm = dct(k) Else Set itm = New Class1 dct.Add k, itm End If itm.Sum Cells(r, "B").Value Next For r = 2 To bot Cells(r, "C").Value = dct(CStr(Cells(r, "A").Value)).Avg() Next End Sub ' クラスモジュール(オブジェクト名「Class1」) Private total As Double Private cnt As Long Public Sub Sum(ByVal v As Double) total = total + v cnt = cnt + 1 End Sub Public Function Avg() As Double Avg = total / cnt End Function

  • クラスの初期値設定について

    早速ですが、教えてください(開発環境は WindowsXP,VisualBasic.NET2003 です) Public Class CCC Private Key As Integer Private Value As String End Class 上記のようなクラスを用意して Public Sub SSS() Dim III() As CCC = New CCC() {{1, "VALUE1"}, _ {2, "VALUE2"}} End Sub といった具合に初期値を設定したいのですが、 コンパイルエラー(配列初期化子の次元が多すぎます。)に なってしまいます。(ほかに思いついた記述パターンも試してみましたがだめでした) 仕方なく、CCCに下記のようなメソッドを作って Public Class CCC Private Key As Integer Private Value As String Public Sub SetValue(ByVal a As Integer, ByVal b As String) Key = a Value = b End Sub End Class このメソッドを利用し Public Sub SSS() Dim III() As CCC III(0).SetValue(1, "VALUE1") III(1).SetValue(2, "VALUE2") End Sub 上記のように初期値を設定するようにしています。 初期化子({})をつかって、C言語?風に初期値を設定することは できないのでしょうか? 上記の例では、顕著に現れてませんが、クラスの中のクラスにも 初期値を設定しようとする場合、どのような初期値が設定されて いるかが、ソース上、整然と並ばなくなってしまい、修正しにくい 、見た目が美しくない状態になってしまいます。 何かよい方法はないのでしょうか?ご教示願います。 (参考URLだけでもかまいません、よろしくお願いします)

  • VB2005の構造体で配列を含む構造体へアクセスするプロパティの記述方法

    VB2005の構造体で、以下のように Dantaiという配列を含む構造体があり、 プロパティを記述する方法で困っています。 Structure Person Dim namae As String Dim toshi As Integer end Structure Structure Dantai Dim m_DantaiMei As String Dim m_Hito() As Person Public Sub New(mei As String) m_DantaiMe = mei Redim m_Hito(100) End Sub '団体名 Public Property Dantai_Mei() As String Get Return m_DantaiMei End Get Set(ByVal value As String) m_DantaiMei = value End Set End Property '人 Public Property ???  '???????????? どのようにプロパティを設定したらよいのでしょうか? '???? '???? 配列で、しかも構造体です。 '???? '???? End Property End Structure Dim dantai As New Dantai("A") MessageBox(dantai.Dantai_Mei) MessageBox(人100人を表示させたい) '?????????????????????????? あと、構造体のDimはデフォルトで、PublicでしょうかPrivateでしょうか? VB2005の構造体について、VB6との違い、クラスとの違いなど詳しく書かれている サイトなどご存じの方教えて下さい。

  • ADO オブジェクトの渡し方

    こんにちは。ADOについてお教えください。 フォームをロード時に接続プロシージャと切断プロシージャを走らせたいと思います。 ConnectDatabaseを呼び出しは成功しますが、CloseDatabase呼び出しには失敗します。 スコープの問題で、rs、cnのオブジェクトが無い為だと思います。 ConnectDatabaseで作成されたcn、rsオブジェクトを別の関数で処理するにはどのようにコードをかけばよろしいでしょうか?宜しくお願い致します。 Private Sub Form_Load() Call ConnectDatabase Call CloseDatabase End Sub Module1 ------------------ sub ConnectDatabase() Dim cn As ADODB.Connection Dim rs As ADODB.Recordset Set cn = New ADODB.Connection Set rs = New ADODB.Recordset 処理~~~~ end sub sub CloseDatabase() rs.Close cn.Close Set rs = Nothing Set cn = Nothing end sub

専門家に質問してみよう