VB6構造体をVB2008クラスで行う場合のポイントとは?

このQ&Aのポイント
  • 「VB6構造体をVB2008クラスで行う場合」について、初心者の方向けにポイントを解説します。
  • Sharedキーワードの使い方や、メソッドの分け方についてご説明します。
  • また、クラスとコレクションクラスを組み合わせる際の注意点についても触れます。
回答を見る
  • ベストアンサー

VB6構造体をVB2008クラスで行う場合

何方かの質問「VB6構造体をVB2008クラスで行う場合」 の回答プログラムにて参考とさせて頂きましたが 申し訳ありません、初心者しにて・・・・・教えてください。 値を「登録、参照部分」のクラス(抜粋) Public Class Program   Public Shared Sub Main()    (省略)   End Sub End Class 上記部分なのですが (1)Sharedを使用する訳はなんでしょうか?(省いても問題ありませんか?) (2)登録、参照部分のクラスPublic Shared Sub Main()を「登録のメソッド」と「参照のメソッド」に   分けたいのですがどうしてもうまくいきません。   何方か御教授願えないでしょうか? よろしくお願いします。 「以下何方かの質問の回答プログラム」 ■クラス+コレクションクラス Public Class Group   Public MainID As Integer   Public SubID As Integer   Public Value1 As Integer   Public Value2 As Integer End Class Public Class GroupCollection : Inherits System.Collections.Generic.Dictionary(Of Integer, Group)   Public Shadows Sub Add(ByVal Item As Group)     MyBase.Add(Item.SubID, Item)   End Sub End Class Public Class Program   Public Shared Sub Main()     Dim DataDict As New GroupCollection     Dim NewGroup As New Group     NewGroup.MainID = 1     NewGroup.SubID = 101     NewGroup.Value1 = 123     NewGroup.Value2 = 234     DataDict.Add(NewGroup)     Console.WriteLine(DataDict.Item(101).Value2) ' 出力 234   End Sub End Class

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

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

何が言いたいのか、日本語はあいかわらずよくわからないのですが、バグっているところは分かったので。 NG箇所: newtag メソッドの1行目 ADDTAG を呼び出すたびに Me.DataDict (NewGroupの入れ物)を作成しなすことになっていませんか? よく考えてみましょう。

kakedasi_pg
質問者

お礼

修正点は(御指摘通り)  Me.DataDict = New CLS_TagGroupCollection ←これを 自クラス内 Sub New()へ移動し問題解決致しました。 私の理解力不足かと思われますがうまく説明できず申し訳ありません。 尚且つ読みづらいコードを読んで頂いた物かと思われます。 御指摘にて修正&TESTを行い無事思い通りに動かすことができました。 もっと精進したいと思います・・・・・。 誠にありがとうございました。

その他の回答 (1)

noname#259269
noname#259269
回答No.1

(1) Shared を付けると、Class 名+.+メソッド名で呼び出せるようになります。この例だと呼出し元からは     Program.Main() という形で呼び出せます。Shared を付けないと、クラスのインスタンスを作成しないと呼べません(下記)。     Dim p As New Program()     p.Main() (2)どうやった結果どううまくいかないのか、自分の試した結果を書きましょう。

kakedasi_pg
質問者

お礼

Shared承知いたしました 御回答ありがとうございます。 申し訳ありません以下、参考よりテストしているコードとなります。 データのクラス+コレクションクラスにて参考例  Public Class Program Public Shared Sub Main() (省略) をタグ(データ)の追加,参照用に  Public Class Cls_TagProgramへ改造し 使用するフォーム直下に(Public Class Form_*** ) Public OBJPLCPRG As New Cls_FolderProgram にて生成しておき、テスト的にPBなどにてOBJPLCPRGより登録、参照をはしらせましたが 生成時のみしか参照できません・・・・・。 クラス(インスタンス生成)について理解不足と認識してはいるのですが 同一インスタンスを参照できていない?か、インスタンスが消失している? (そもそも手法の間違えなのでしょうか・・・・) 初心者ながら四苦八苦している所ですので御教示頂けると幸いです。 よろしくお願い致します。 Tab表示されず? 見づらくて申し訳ありません・・・。 '=========================================================== 'タグのクラス Public Class Cls_TagGroup Private intTagID As Integer 'タグの番号(ID) Private strTagName As String 'タグの名称 Private strTagCome As String 'タグのコメント 'タグの番号(ID) Public Property PLC_TagID() As Integer Get Return Me.intTagID End Get Set(ByVal value As Integer) Me.intTagID = value End Set End Property 'タグの名称 Public Property PLC_TagName() As String Get Return Me.strTagName End Get Set(ByVal value As String) Me.strTagName = value End Set End Property 'タグの名称 Public Property PLC_TagCome() As String Get Return Me.strTagCome End Get Set(ByVal value As String) Me.strTagCome = value End Set End Property End Class '=========================================================== 'タグのコレクションクラス(辞書コレクションンを使用) Public Class Cls_TagGroupCollection : Inherits System.Collections.Generic.Dictionary(Of Integer, Cls_TagGroup) Public Shadows Sub Add(ByVal Item As Cls_TagGroup) MyBase.Add(Item.PLC_TagID, Item) End Sub End Class '=========================================================== 'タグのクラス+コレクションクラス 'タグの追加,参照用にアプリよりこのクラスを使用 Public Class Cls_TagProgram Private DataDict As CLS_TagGroupCollection Private NewGroup As CLS_TagGroup Private intTagNo As Integer 'タグの番号 'インスタンス初回生成時実行 Public Sub New() intTagNo = -1 '開始番号を0とする為-1とする。 End Sub 'タグの追加 Public Sub ADDTAG(ByVal strName As String, ByVal strCome As String) intTagNo = intTagNo + 1 'タグID番号は0からオートNO newtag(intTagNo, strName, strCome) End Sub Private Sub newtag(ByVal intNO As Integer, ByVal strName As String, ByVal strCome As String) Me.DataDict = New CLS_TagGroupCollection Me.NewGroup = New CLS_TagGroup NewGroup.PLC_TagID = intNO NewGroup.PLC_TagName = strName NewGroup.PLC_TagCome = strCome DataDict.Add(NewGroup) End Sub 'タグの参照 TagID Public Function VIEW_IntTagID(ByVal intNO As Integer) As Integer If intNO <= intTagNo Then 'ID登録済みか? Return Me.DataDict.Item(intNO).PLC_TagID ' 'Console.WriteLine(Me.DataDict.Item(intNO).PLC_TagNO) 'デバック用 Else End If End Function 'タグの参照 TagName Public Function VIEW_StrTagName(ByVal intNO As Integer) As String If intNO <= intTagNo Then 'ID登録済みか? Return Me.DataDict.Item(intNO).PLC_TagName ' 'Console.WriteLine(Me.DataDict.Item(intNO).PLC_TagName) 'デバック用 Else Return "" End If End Function 'タグの参照 TagCome Public Function VIEW_StrTagCome(ByVal intNO As Integer) As String If intNO <= intTagNo Then 'ID登録済みか? Return Me.DataDict.Item(intNO).PLC_TagCome ' 'Console.WriteLine(Me.DataDict.Item(intNO).PLC_TagCome) 'デバック用 Else Return "" End If End Function End Class

関連するQ&A

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

    早速ですが、教えてください(開発環境は 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だけでもかまいません、よろしくお願いします)

  • 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変数になってますがこれを配列に変えたいのですがどうすればいいでしょうか?

  • VB.NETのメモリ領域について

    VB.NETのメモリ領域について 以下の(1)~(12)の変数のために、 スタック領域、静的領域、ヒープ領域のどこのメモリが使われるか教えてください。 Class Sample   Dim a As Integer '(1)   Dim b As String = "BBB" '(2)   Shared c As Integer '(3)   Shared d As String = "DDD" '(4)   Sub X()     Dim f As Integer '(5)     Dim g As String = "GGG" '(6)     Static h As Integer '(7)     Static i As String = "III" '(8)   End Sub   Shared Sub Y()     Dim k As Integer '(9)     Dim l As String = "LLL" '(10)     Static m As Integer '(11)     Static n As String = "NNN" '(12)   End Sub End Class それぞれこんな認識で合ってますか? スタック領域 (1)(5)(9) スタック領域にポインタ+ヒープ領域に実体 (2)(6)(10) 静的領域 (3)(7)(11) 静的領域にポインタ+ヒープ領域に実体 (4)(8)(12)

  • クラスをDictionaryにした時のValueでFor Each

    Public Class Group   Public MainID As Integer   Public Value1 As Integer   Public Value2 As Integer End Class これをDictionaryにしたとき Value1の種類を取り出したいです。 Dim clsGroup As New Group Dim valueColl As Dictionary(Of Integer, Group).ValueCollection = clsGroup.Values For Each s As clsGroup In valueColl Next これではValue1でまとまってくれないようです。

  • VB2008: 独自例外とは?

    独自例外の確認ための質問をします。 独自例外の発生をキャッチして表示する術がわからなくて苦肉の策でエラートラップを利用。 しかし、こういう事であれば何も独自例外を設定する必要がありません。 と思ったり、「スルーだからテストに<0除算>を選んだのが悪いのか?」と考えたり。 ともかく、判っているのか判っていないのかが判らない状態に陥っています。 そういうことで、独自例外について少し教えて頂ければ幸いです。 ' ============================== ' クラスプログラミング; 演習2 ' ============================== Module theClass   Sub Main()     On Error GoTo Error_Main     Dim T1 As New TEST1     Debug.Print(T1.MembersLengthAverage.ToString) Exit_Main:     Exit Sub Error_Main:     ErrorMsg(Err.Description & "(Main)")     Resume Exit_Main   End Sub End Module ' ================================================================== ' クラス TEST1 ' ================================================================== <Serializable()> Public Class TEST1   Private _MemberCount As Integer   Private _Member1 As String   Private _Member2 As String    ReadOnly Property MembersLengthAverage() As Integer     Get       If _MemberCount <> 0 Then         Return (_Member1.Length + _Member2.Length) \ _MemberCount       Else         Throw New System.Exception("TEST1: 除算エラーが発生しました。" )       End If     End Get   End Property   Public Sub New()     _Member1 = ""     _Member2 = ""   End Sub End Class

  • VB.NET クラス内でプログラムを終了するには?

    VBAでは、エラーでプログラムを終了する時には Endステートメントを記述していましたが、 このVBAをVB.NET(クラスライブラリ、DLL)に 書き換えていますが VB.NETでClass1クラスの中にtest()メソッドを作って この中にEndステートメントを記述すると 「クラスライブラリプロジェクトで  Endステートメントを使用することができません。」 というメッセージが表示されますが エラーでプログラムを終了するには どのように記述すればいいのでしょうか。 Public Class Class1  Public Sub test(ByVal a As String)   If a = "" Then    MsgBox("致命的なエラーです")    End <===エラー発生   End If  End Sub End Class よろしくお願いします。(WindowsXP,VS2010)

  • VB.NETで値や参照について ByRefなど

    VB.NETで値や参照について、まだ初学ですがよろしくお願いします。 VBは2008です。 以下のようなs文字列を参照引数にしたSetDataメソッドがあります。 ByRef s As Stringという引数は、SetData内でsを書き換えると、 呼び出したSetDataメソッド外でも中身が変わるので 私のByRefの認識ではポインタと解釈しています。間違っているでしょうか? SetData(1,1, buf)とすれば、DataGridViewの中は、「初期値」という文字が表示されます。 別のメソッド(KaKikae)でbufを"あ"という文字に変えた場合、SetDataメソッドを使わなくても 書き換わっていると思っていたのですが、実際実行してみると書き換わりません。 値や参照について理解が足りないからだと思いますがわかりません。 どのようにすれば、それが実現できるのでしょうか? Public Class HogeClass Private buf As String = "初期値" Private Sub SetData(ByVal x As Integer, ByVal y As Integer, ByRef s As String) As Boolean Dim dg As DataGridView dg = DataGridView1 dg.Item(x, y).value = s End Sub Private Sub KaKikae() buf = "あ" End Sub End Class

  • 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

  • 【vb.net】クラス化について

    大学で以下のような練習問題を頂きました。 ----- Public Sub test()  Dim a As b = New c  Dim i As Integer = 1  a.disp(i) End Sub 問:この時のbとcを実装せよ。 ----- Public Class c  Public Function disp(ByVal i As Integer) As String   return "iは" & i & "です"  End Function End Class までは書いてみたのですが、b の扱いがどうもわかりません。 どなたか教えていただけませんでしょうか。