• ベストアンサー

VB6でやると構造体の配列になる変数をVB2008では何で作ればいいか

VB6でプログラムを作っていたときは 値のセットが配列になるとき 構造体を動的配列で宣言してデータを足して作りました。 VB2008で開発をすることになり 同じようなことをしたいのですが もっと便利なやり方が登場したりするのでしょうか? クラスで挑戦したのですが動的配列はできないようでした。

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

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

#書き連ねてたらやたら長くなってしまったので必要と思うところだけ抜粋して読んでくださいませ。 > できれば下記のようにしたかったので > 同じようなことができないでしょうか? ■構造体+配列 Public Structure MainGroup   Public ID As Integer   Public SubGroups As SubGroup() End Structure Public Structure SubGroup   Public ID As Integer   Public Value1 As Integer   Public Value2 As Integer   Public Sub New(ByVal ID As Integer, ByVal Value1 As Integer, ByVal Value2 As Integer)     Me.ID = ID : Me.Value1 = Value1 : Me.Value2 = Value2   End Sub End Structure Public Class Program   Public Shared Sub Main()     Dim DataArray As MainGroup() = {}     Array.Resize(DataArray, 3)     With DataArray(0)       .ID = 1       Array.Resize(.SubGroups, 4)       .SubGroups(0) = New SubGroup(101, 123, 456)       .SubGroups(1) = New SubGroup(102, 234, 567)       ' (略)     End With     With DataArray(1)       ' (略)     End With   End Sub End Class ■クラス+コレクション Public Class MainGroup   Public ID As Integer   Public SubGroup As New System.Collections.Generic.List(Of SubGroup) End Class Public Class SubGroup   Public ID As Integer   Public Value1 As Integer   Public Value2 As Integer   Public Sub New(ByVal ID As Integer, ByVal Value1 As Integer, ByVal Value2 As Integer)     Me.ID = ID : Me.Value1 = Value1 : Me.Value2 = Value2   End Sub End Class Public Class Program   Public Shared Sub Main()     Dim DataList As New System.Collections.Generic.List(Of MainGroup)     Dim NewMain As MainGroup     NewMain = New MainGroup     NewMain.ID = 1     NewMain.SubGroup.Add(New SubGroup(101, 123, 456))     NewMain.SubGroup.Add(New SubGroup(102, 234, 567))     ' (略)     DataList.Add(NewMain)   End Sub End Class 配列+クラスはNULL参照を発生させる可能性がある点で相性がよくありません。コレクション+構造体は、#2で挙げたようにデータ書き換えの手間がかかり、やはり相性はよくありません。 配列は要素数の変動に対してパフォーマンスが悪く、細かく増減させるには不向きです。コレクションは増減することを前提としている点や、削除した箇所を詰めたり途中に挿入したりが容易な点で優れています。 クラス or 構造体、配列 or コレクション をどう組み合わせるかはこれらのほか、ユーザビリティ・保守性・整合性・パフォーマンスなどと共に天秤にかけることになるでしょう。状況にあわせてうまく使い分けてください。 > addでどんどん追加して全体をループさせずに小項目IDを取得する方法 小項目IDがユニークであれば、リストコレクションではなく辞書コレクションを使うことでIDからクラスを取得できるようになります。クラスが保持しているデータをキーに使う場合は、コレクションを継承したクラスを作り、AddをShadowsで置き換えたほうがコーディングミスを防ぐことが出来ます。 ■クラス+コレクションクラス 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

taku_pon
質問者

お礼

ありがとうございます。 ゴールが見えてきました。 クラス+コレクションクラスでいってみます。

その他の回答 (2)

回答No.2

構造体の場合でも配列の扱い方は一緒です。 Public Class Hoge を Public Structure Hoge に変えればOKです。 ※コレクションで構造体を扱う際の注意点 コレクションにおいてはクラス(参照型)と構造体(値型)でメンバーの書き換え方が異なります。 Dim HogeList As New System.Collections.Generic.List(Of Hoge) HogeList.Add(New Hoge()) HogeList.Item(0).Prop = xxx ' ←ここ Hogeがクラスであればこれで問題なく動作しますが、構造体の場合はこのような代入はできません。 Dim hogeItem As Hoge = HogeList.Item(0) hogeItem.Prop = xxx HogeList.Item(0) = hogeItem このように、一度構造体ごと取出し、構造体ごとコレクションに戻す必要があります。

taku_pon
質問者

補足

ありがとうございます。 コレクションでクラスを使っていけそうな気がしてきました。 できれば下記のようにしたかったので 同じようなことができないでしょうか? 配列1() as 大項目構造体 大項目構造体  大項目ID  小項目() 小項目構造体  小項目ID  小項目値1  小項目値2 こうすると大項目ごとにDBの検索テーブルが違うときに 小項目IDを条件に含めることが楽だと思っていました。 クラスを  大項目ID  小項目ID  小項目値1  小項目値2 で定義しました。 addでどんどん追加して全体をループさせずに小項目IDを取得する方法は ないでしょうか?

回答No.1

動的配列は若干扱いが変わっています。 ReDimでも配列数の変更はできますが、私はArray.Resizeを使うようにしています。 要素数がちょくちょく変わるのであれば、コレクションを使うほうがスマートかもしれません。暗黙の型変換を回避するために、ジェネリックを使うことをお勧めします。 Public Class Hoge End Class Public Class Program Public Shared Sub Main() Dim HogeArray As Hoge() = {} Array.Resize(HogeArray, 3) ' 要素数を変更 HogeArray(0) = New Hoge() HogeArray(1) = New Hoge() HogeArray(2) = New Hoge() 'HogeArray(3) = New Hoge() ' これはエラーになる Array.Resize(HogeArray, 4) ' 配列数を変えても既存のデータは残る 'ReDim Preserve clsHoge(3) ' VB6.0の書き方でも可 HogeArray(3) = New Hoge() ' Array.Resizeでは要素数、ReDimではインデックスの最大値 ' 配列の大きさを指定する値が異なるので注意 ' リストコレクションを使えば配列数を気にしなくてよい Dim HogeList As New System.Collections.Generic.List(Of Hoge) HogeList.Add(New Hoge()) HogeList.Add(New Hoge()) HogeList.Add(New Hoge()) HogeList.Add(New Hoge()) For Each Item As Hoge In HogeList ' コレクションの一覧を列挙 Next End Sub End Class

taku_pon
質問者

補足

ありがとうございます。 動的配列はできそうな気がしてきました。 配列にしたいものが構造体の場合は どうすればいいのか分かりません。

関連するQ&A

  • データベースの値を構造体へ代入

    VB.NETにてWindowsMobileの開発を行っています。 データベースへのアクセスに時間がかかるので、 最初にデータベースの値を全て構造体配列へ代入しておき、 最後に保存とした時にまたデータベースへ代入させるといったプログラムを組もうと思います。 その際に全てのフォームから構造体配列へアクセスさせたいのですが、 構造体配列をグローバル化させる方法はありませんでしょうか? ご教授のほどよろしくお願い申し上げます。

  • VB .Netの構造体について

    構造体について教えて下さい。 クラスで構造体を作成しました。 クラスでIniファイルを読み込み、Formのボタンを押した処理の中で構造体を読み込みたいのですが、何をしても空白(Nothing)になります。 クラスの中では格納されたままなのに・・・。 違う場所で構造体を呼んだときは別の処理がいるのでしょうか? それともVB .Netの仕様なのでしょうか?

  • クラスのプロパティに構造体を使いたい。

    VB6+SP5にて開発しております。 「クラス名.構造体名.変数名 = 値」といった感じで構造体をプロパティとして使用できればと考えているのですが、単純に構造体を定義しただけでは駄目なようです。実現は無理なのでしょうか?よろしくお願いします。

  • 動的に作成した構造体配列の中に、さらに動的に構造体配列を作るには?

    はじめまして。 この度、ちょっとした計算プログラムを作ることになったのですが、 タイトルにもありますように、 『動的に作成した構造体配列の中に、さらに動的に構造体配列を作る』 方法がわからずに困っています。 実際には下記のようにプログラムしたいのですが... ------------------------------------------------- 'a'の構造体の中に作られる'b'の配列数は、下記のように 'a'の配列の番号により違い、また'a'の配列数も最初の段階では未定です。 構造体'a'←配列数未定 構造体'b'←配列数未定 a[0]-----b[0]  |    b[1]  |    b[2]  | a[1]-----b[0]  |    b[1]  | a[2]-----b[0]  |    b[1]  .    b[2]  .    b[3]  . ------------------------------------------------- new演算子で'a'の配列は作れたのですが、その中の'b'の数の分だけ 配列を動的に作成する方法がわかりませんでした。 最初は'b'の配列を多めに取って計算すればよいと思っていましたが、 計算過程で'b'の配列数が10000を越えてしまう場合があり、 また'b'の構造体のサイズも大きめなので、断念せざるをえませんでした。 どなたか、このように配列を作成する方法を知っている方がいましたら、 是非教えていただきたいです。 下手な説明ですいません。

  • 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との違い、クラスとの違いなど詳しく書かれている サイトなどご存じの方教えて下さい。

  • 構造体配列の並べ替え

    いつもお世話になっております。 VB6で構造体の配列をソートしたいと考えています。 具体的やりかたは調べたいと思うのですが、ヒントとしてひとつ教えてほしいことがありまして質問させていただきました。 たとえば 名前(string) 身長(integer) 体重(single) 何人分かを仮にprofileという名の構造体に入れて、普通の配列と同じ様に体重だけをソートしたとします。 すると体重だけがソートされてしまうのでしょうか? それとも構造体ごとソートされてくれるのでしょうか? 前者だとかなり悩むことになりそうなので、そこだけ教えていただきたく質問させていただきました。 よろしくお願いします。

  • VB6.0 ADOでbyte型配列を Insertしたい

    始めて投稿させて頂きます。よろしくお願いします。 さて当方、VB6.0とADOを使ってSQL Serverに接続してデータのやりとりをするプログラムを開発しているのですが byte型配列に入っている値をADOを使って、Char型のフィールドに入れたいんです。 このような処理は可能でしょうか? いろいろと探してみたのですが、どうしてもわからずにほとほと困っております。 何か可能な方法があれば、ぜひよろしくお願いします。

  • VB2005 コントロール配列について教えていただけませんか?

    現在VB2005を用いてプログラムを行なっている初心者です。 ここのサイトでVB2005ではコントロール配列は使用できないことを知りました。そこで、例えばフォーム上にTextBoxを5個配置して、各TextBoxに入力された値を配列に格納するのにはどのようにすれば良いでしょうか? data(0) = textbox1.text data(1) = textbox2.textと一つずつやるしかないでしょうか・・・ For文などを用いて簡単にできる方法を教えてください。 よろしくお願い致します。

  • C#の構造体に関して

    C#の構造体に関して C#で構造体で配列を持ちたいと思い、宣言の仕方や使い方を 勉強していますが、どうしてもコンパイルは通るもののエラーと なってしまいます。 《ソース》 単純に構造体で宣言した"a"という配列に、"ABC"という文字列を 代入したいだけですが。。。 namespace テスト環境 { struct test { public string []a; } class Program { static void Main(string[] args) { test aaa = new test(); aaa.a[0] = "ABC"; } } } 配列の初期化等は、ようやく理解したつもりではいますが、構造体 が絡むとどうしてもわかりません。 どこをどのように修正したら良いかを教えて下さい。 初歩的な質問で申し訳ありませんが、よろしくお願いします。

  • データ数の多い構造体配列について

    visual c++で配列をメンバーに持つ構造体配列を定義したいと思っています。 しかし、以下のように定義してもプログラムが実行されません。 配列の容量が大きいのかもしれませんが、 大量のデータを扱いたいので容量を小さくはしたくありません。 大量のデータを扱うのに何かいい方法はないでしょうか。 struct X { double A[1000]; }; : : : struct X B[10000];

専門家に質問してみよう