- PR -

.NETでのコントロール配列の使用法

投稿者投稿内容
エイジ
常連さん
会議室デビュー日: 2007/11/14
投稿数: 38
お住まい・勤務地: 兵庫
投稿日時: 2007-11-15 14:17
たびたび申し訳ありません

VB6.0で使えていたコントロール配列と同じような処理をさせたいです
自分で調べて居てコントロールの変数を用意して、それを同じように利用すると言う感じで理解したつもりでしたが
モジュール変数を利用しようとすると結果が上手く動きません


コード---------------------------

Public Class F01_Menu
  Private cboH() As ComboBox = {cboHimoku1, cboHimoku2, cboHimoku3・・・・}

  Private Sub F01_Menu_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

    Dim i As Integer
    Dim n As Integer

    Me.cboHimoku1.Items.Clear()

    'gHimoku構造体からデータの取得
    For i = 1 To gHimoku.Length - 1
      For n = 0 To cboH.Length - 1
        'gHimoku構造体のstrNameをコンボボックスへセットする
        cboH(n).Items.Add(gHimoku(i).strName)
      Next
    Next
  End Sub
End Class

---------------------------------

参考にしたのは
http://bbs.wankuma.com/index.cgi?mode=al2&namber=9176&KLOG=9

こちらの書込みで

Dim boxes() As TextBox = {TextBox1, TextBox2, TextBox3, TextBox4 }
の辺りを参考にコードを組みました

上記コードで
Private cboH() As ComboBox = {cboHimoku1, cboHimoku2, cboHimoku3・・・・}
のモジュール変数の宣言の所をF01_Menu_Loadのイベント内で
Dim cboH() As ・・・・・
と宣言すると上手く動作したのですが

cboH()を使いまわすためモジュールレベルで宣言したく
上記コードに変更すると

cboH(n).Items.Add(gHimoku(i).strName)
の部分で
「オブジェクト参照がオブジェクト インスタンスに設定されていません。」
というエラーが出て動作ができなくなりました

インスタンスを作成せねばと思い
cboH(n) = New ComboBox
cboH(n).Items.Add(gHimoku(i).strName)
でインスタンスを作成するとエラーは無くなるもののフォーム上のコントロールに結果が反映されなくなり

それならと思い
Private cboH() As New ComboBox = {cboHimoku1, cboHimoku2, cboHimoku3・・・・}

と、モジュール変数の宣言のしかたを変えると
「配列をNewで宣言することは出来ません」
と言うエラーになり

その他にも
cboH(n) = New cboHimoku1
cboH(n).Items.Add(gHimoku(i).strName)
とか変なコードを色々試した挙句理解できずにこちらで質問させていただきました


オブジェクトやインスタンスと言った所を曖昧にしか理解しないまま
開発を行っているのがそもそもの問題なのだとは思いますが

モジュールレベルでの宣言を行う方法を教えていただけると助かります
連日で申し訳ないですがよろしくお願いいたします

[ メッセージ編集済み 編集者: エイジ 編集日時 2007-11-15 14:40 ]

[ メッセージ編集済み 編集者: エイジ 編集日時 2007-11-15 14:42 ]
ぽぴ王子
ぬし
会議室デビュー日: 2006/03/24
投稿数: 475
お住まい・勤務地: お住まい:城・勤務地:城
投稿日時: 2007-11-15 14:48
引用:

エイジさんの書き込み (2007-11-15 14:17) より:

オブジェクトやインスタンスと言った所を曖昧にしか理解しないまま
開発を行っているのがそもそもの問題なのだとは思いますが


端的に言うとそうかもしれません。基礎をないがしろにしたままに突き進むと
いざというときに応用が利かなくて困ったりします。
(関係ないですが、リンク先で僕も偉そうなこと書いてますね。恥ずかしい orz)

コード自体は特に問題になりそうな部分はないと思います。そのまま検証できる
ような「ミニマムコード」であればもっと調べることは可能だったと思いますが
とりあえず目で見た限りでは問題はなさそうです。
# クリアするのが cboHimoku1 だけでいいの?という疑問はありますけど

引用:

「オブジェクト参照がオブジェクト インスタンスに設定されていません。」
というエラーが出て動作ができなくなりました

インスタンスを作成せねばと思い
cboH(n) = New ComboBox
cboH(n).Items.Add(gHimoku(i).strName)
でインスタンスを作成するとエラーは無くなるもののフォーム上のコントロールに結果が反映されなくなり
(snip)


えーと、このあたりから道をあやまっている気がしています。
こういった場合にまずやることは「インスタンスを生成する」ことではなく
「どこがエラーの原因なのか」を究明することです。
オブジェクト参照が(略) は NullReferenceException ですから、インスタンスを
作成するという方法は解決策のひとつとしては正しいですが、今回の場合は
また違う原因で起きているような気がします。
というか、配列部分では無さそうな気が。

null 参照をしているオブジェクトが
 cboH(n) なのか
 gHimoku(i) なのか
 それとも gHimoku(i).strName なのか
あたりをウォッチ式などで調べてみることから始めてみてはどうでしょう。

あと、メッセージを修正したときはどこを修正したのかわかるように書いて
おくとよいです。
(返信を書いている途中で修正されたのでちょっと焦った)
_________________
ぽぴ王子@わんくま同盟
ぽぴ王子の人生プログラミング中 / ぽぴンち。
エイジ
常連さん
会議室デビュー日: 2007/11/14
投稿数: 38
お住まい・勤務地: 兵庫
投稿日時: 2007-11-15 15:32
コード----------------------------------

Public Class F01_Menu
  Private Structure mHimokuMaster
    Dim strName As String
  End Structure

  Private mHimoku() As mHimokuMaster
  Private cboH() As ComboBox = {Me.cboHimoku1, Me.cboHimoku2, Me.cboHimoku3}

  Private Sub F01_Menu_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

    Dim i As Integer
    Dim n As Integer

    ReDim mHimoku(2)

    mHimoku(1).strName = "外食"
    mHimoku(2).strName = "嗜好品"

    'gHimoku構造体からデータの取得
    For i = 1 To mHimoku.Length - 1
      For n = 0 To cboH.Length - 1
        'gHimoku構造体のstrNameをコンボボックスへセットする
        cboH(n).Items.Add(mHimoku(i).strName)
      Next
    Next
  End Sub
End Class

---------------------------------------

ぽぴ王子さんありがとうございます

おっしゃるとおり、応用が利かなくわき道へそれると行き詰るような事が多いです・・

ミニマムコードと言うのは、実行できる必要最小限のコードのことだと理解して
上記のコードを載せたのですがよろしかったでしょうか?

修正の部分はコードのインデントが上手く反映されていなかったので
それを修正したかっただけなのですが、おっしゃるように改めて考えると戸惑いますよね。
今後注意してまいります

それにしても、参考にしたBBSとは違う場所で同じ方にご返信頂けるとは思いもしませんでした^^


本題に戻りますが
やはりNullReferenceExceptionはcboH(n)がNothingで起こっていました
それ以外のオブジェクトは想定どおりの動きをしていました

上記コードに編集しなおしましたが
やはり結果同じエラーが発生します

クリアの部分は必要が無くなったコードを削除するのをわすれていました。

申し訳ないのですが再度よろしくお願いいたします
ぽぴ王子
ぬし
会議室デビュー日: 2006/03/24
投稿数: 475
お住まい・勤務地: お住まい:城・勤務地:城
投稿日時: 2007-11-15 16:07
引用:

エイジさんの書き込み (2007-11-15 15:32) より:

ミニマムコードと言うのは、実行できる必要最小限のコードのことだと理解して
上記のコードを載せたのですがよろしかったでしょうか?


それで結構です。どうもありがとうございます。
前回のコードでは gHimoku の型がわからなかったので、ちょっとその辺も怪しい
なと思っていました。

あらためて原因を調べていただいたところで、cboH(n) が Nothing なのが原因と
いうことだったので、私も少し調べてみました。

コード:

    Private FOO As Button() = {Me.Button1, Me.Button2}

    Private Sub Form1_Load( _
            ByVal sender As System.Object, _
            ByVal e As System.EventArgs) Handles MyBase.Load
        For n As Integer = 0 To FOO.Length - 1
            FOO(n).Text = "アッー!"
        Next
    End Sub


このようなコードでテストしてみたところ、確かに FOO(n) が Nothing になって
いるようですね。
もう少し調べてみたところによると、FOO の宣言(と初期化)のあとでフォームの
Initialize メソッドが実行されていますね。ということで FOO を初期化した段階
では Me.Button1 も Me.Button2 も宣言だけでインスタンスが作成されて
いない状態(つまり Nothing)になり、結果 FOO も Nothing な配列を作成
しているということになるようです。

…っと、ちょっと難しいでしょうか。

要するに Me.Button1 のインスタンスを生成する前に配列を作ってしまっている
ので、FOO は Button1 を配列に持っているつもりが実体のないヌケガラを配列
にしてしまっているため、ですね。
(ううむ、いまいちうまく説明できないや)

解決策としてはモジュール変数を止めてメソッド内の変数として持つのがスマート
じゃないかと思います。

コード:

        mHimoku(1).strName = "外食"
        mHimoku(2).strName = "嗜好品"

        'gHimoku構造体からデータの取得 
        For i = 1 To mHimoku.Length - 1
            For n = 0 To cboH.Length - 1
                'gHimoku構造体のstrNameをコンボボックスへセットする
                cboH(n).Items.Add(mHimoku(i).strName)
            Next
        Next


ところで、これだと mHimoku が 1〜1 までしかループされない気がします
が、大丈夫でしょうか(写し間違いかな)。

あと、ReDim よりは List 型を使うといろいろと便利かもしれません。
一度調べてみるといいと思います。
_________________
ぽぴ王子@わんくま同盟
ぽぴ王子の人生プログラミング中 / ぽぴンち。
エイジ
常連さん
会議室デビュー日: 2007/11/14
投稿数: 38
お住まい・勤務地: 兵庫
投稿日時: 2007-11-15 16:11
コード----------------------------------

Public Class F01_Menu
  '追加行---
  Private mcboH As New ComboBox
  '---------

  Private Structure mHimokuMaster
    Dim strName As String
  End Structure

  Private mHimoku() As mHimokuMaster

  '編集削除------
  'Private cboH() As ComboBox = {Me.cboHimoku1, Me.cboHimoku2, Me.cboHimoku3}
  '--------------

  Private Sub F01_Menu_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

    Dim i As Integer
    Dim n As Integer
    '追加------
    Dim cboH() As ComboBox = {Me.cboHimoku1, Me.cboHimoku2, Me.cboHimoku3}
    '----------

    ReDim mHimoku(2)

    mHimoku(1).strName = "外食"
    mHimoku(2).strName = "嗜好品"

    'nとiのループを入れ替えました
    For n = 0 To cboH.Length - 1
      '追加行-------
      mcboH = cboH(n)
      '-------------
      For i = 1 To mHimoku.Length - 1
        'コード編集-------
        mcboH.Items.Add(gHimoku(i).strName)
        '-----------------
      Next
    Next
  End Sub
End Class

---------------------------------------

代替案のような形で

上記コードの様にモジュール変数でコンボボックスの変数を用意し
それにローカル変数で用意したコンボボックスの配列を入れる方法でモジュール変数にセットは出来たものの

作られたモジュールレベルの変数の区別の仕方が判らず結局躓いたままです。

引き続きアドバイスが有りましたらよろしくお願いいたします。
よねKEN
ぬし
会議室デビュー日: 2003/08/23
投稿数: 472
投稿日時: 2007-11-15 16:23

引用:

コード:
   Private cboH() As ComboBox = {cboHimoku1, cboHimoku2, cboHimoku3・・・・}





ここを以下のように宣言だけにします。

Private cboH() As ComboBox

引用:

コード:
  Private Sub F01_Menu_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        
    Dim i As Integer
    Dim n As Integer





この辺りに以下のように配列を初期化するコードを書きます。

cboH = New ComboBox(){cboHimoku1, cboHimoku2, cboHimoku3・・・・}

という感じでいかがでしょうか。
エイジ
常連さん
会議室デビュー日: 2007/11/14
投稿数: 38
お住まい・勤務地: 兵庫
投稿日時: 2007-11-15 16:32
ぽぴ王子さん
すみません、返信を頂いてる時に書き込んでました。

ご説明ありがとうございます
原因理解しました
Me.cboHimoku1自体が宣言前でNothingになっているので、それをコントロールの配列に入れてもそのNothingになるんですね。

ループは意味の無い事をしているので修正が必要かもしれませんが

ReDim mHimoku(2)で配列を3つ用意しているので
(mHimoku.Length - 1) = 2で
1〜2まで回るようにはなっています

mHimoku(0)が空なんですけどね^^;

List型については調べてみます

色々とお手数かけていただき、ご教授いただきまして
ありがとうございました
エイジ
常連さん
会議室デビュー日: 2007/11/14
投稿数: 38
お住まい・勤務地: 兵庫
投稿日時: 2007-11-15 16:44
よねKENさんありがとうございます

おっしゃる方法で成功しました

cboH() = New ComboBox {cboHimoku1, cboHimoku2, cboHimoku3・・・・}
では無く

cboH = New ComboBox(){cboHimoku1, cboHimoku2, cboHimoku3・・・・}
型の後に()を付けるのですね

まだまだ未熟でぽぴ王子さんにご指摘いただいたように
基礎が抜けていたりするので、ひとつひとつ理解しながら精進して行こうと思います

ありがとうございました

スキルアップ/キャリアアップ(JOB@IT)