コントロールへのインデックス付与について

解決


himizu  2012-02-16 23:53:36  No: 147492

>魔界の仮面弁士さま
ご指摘有難うございます。
質問掲示板を間違えておりましたのでこちらに移管します。

vb.netにて以下コントロールにアクセスしたいのですがうまくいきません。

フォームは以下構成になっております。
フォームに4つのグループボックスを配置し
各グループボックスの中にテキストボックスを2つ配置してます。

Form1
GroupBox1−TextBoxa1,TextBoxb1
GroupBox2−TextBoxa2,TextBoxb2
GroupBox3−TextBoxa3,TextBoxb3
GroupBox4−TextBoxa4,TextBoxb4

vb.netでは、コントロール配列がないということで以下処理にて、実行すると
「オブジェクト参照がオブジェクトインスタンスに設定されていません」とエラーが出てしまいます。

for i = 1 to 4
  Me.Controls("GroupBox" & i.ToString).Controls("TextBoxa" & i.ToString).Text = Status
  Me.Controls("GroupBox" & i.ToString).Controls("TextBoxb" & i.ToString).Text = name
next

>VB.NETで「コントロール配列」というと、互換ライブラリの
>Microsoft.VisualBasic.Compatibility.VB6.TextBoxArray クラスなどを
>指すことになりますが……本当にコントロール配列をお使いですか?

すみません言葉が間違っておりました。
コントロールを配列にみたててアクセスしたいということです。

>TextBoxa1 や TextBoxb1 は、Form1 ではなく GroupBox1 に属します。
こちらは、認識できております。

以下だとエラーがでずに、グループボックス内のテキストボックスa,bに値を入れることができるのですが
グループボックスも1〜4までインデックスで処理させたいのです。

Me.GroupBox1.Controls("TextBoxa" & i.ToString).Text = Status
Me.GroupBox1.Controls("TextBoxb" & i.ToString).Text = name

ご指摘のほどよろしくお願いいたします。


魔界の仮面弁士  2012-02-17 00:19:27  No: 147493

> 質問掲示板を間違えておりましたのでこちらに移管します。
当事者以外(検索で辿りついた人など)にとっては、何の話をしているのか
分からなくなってしまいますので、移動時には、元の記事へのリンクも
貼っていただけると助かります。
また、元記事側にもこちらへのリンクを貼っておいてください。

> 「オブジェクト参照がオブジェクトインスタンスに設定されていません」とエラーが出てしまいます。
コードそのものは正しいですよ。
そのままコピー&ペーストしたところ、当方で問題なく処理されました。

単純に、コントロール名をスペルミスしているとか、もしくは
デザイン時の配置ミスだったりはしませんか?
テキストボックスが、位置は GroupBox の上に見えて、実はフォームの上に
載っているとか、あるいは GroupBox がフォーム以外の上にあったとか。

> Me.Controls("GroupBox" & i.ToString).Controls("TextBoxb" & i.ToString).Text = name
> Me.Controls("GroupBox" & i.ToString).Controls("TextBoxa" & i.ToString).Text = Status
name という変数名をお使いなのですか?
実行には影響ありませんが、そのままだと Me.Name と混同しそうですね。

> ご指摘のほどよろしくお願いいたします。
まずは、原因箇所をもう少し切り分けてみてください。

エラーになるのは i が幾つの時なのでしょうか?
また、Nothing が返しているのは、具体的にはどのプロパティでしょうか?

・Me
・Me.Controls
・Me.Controls("GroupBox1")
・Me.Controls("GroupBox1").Controls
・Me.Controls("GroupBox1").Controls("TextBoxa1")
・Me.Controls("GroupBox1").Controls("TextBoxa1").Text

最初の投稿のように、一つずつ変数に入れるなどしてチェックしてみてください。
> Dim gbaCtl As Control = CType(Me.Controls("GroupBox" & i.ToString), GroupBox)
なお、折角 CType/DirectCast するのであれば、As Control ではなく、
As GroupBox などの固有型で受けた方が都合が良いかと思います。


とくま  2012-02-17 00:33:51  No: 147494

> コントロールを配列にみたててアクセスしたいということです。
言いたい事は分かりますが、実体はかなり違うと思います。。。
配列は完全にインデックスで同じ型が並んでる場合になりますが、
今回の場合、Controls の Key となるのは文字列で、しかも Control
なら何でもありです。
その中から Key に紐付く特定のオブジェクトを取り出すわけで、
完全に Key & Value のコレクションの形です。これを配列のように
扱ってると言われるとかなり違和感があります。

で、質問は、結局のところ、
Me.Controls("GroupBox1")
としたところの GroupBox が取れてこないという事だと思います。
↑質問を突き詰めれば2行で終わるのでは?

こちらの環境では取れましたよ。
        For i = 1 To 2
            Me.Controls("GroupBox" & i.ToString).Controls("TextBoxa" & i.ToString).Text = "あ" & i.ToString
            Me.Controls("GroupBox" & i.ToString).Controls("TextBoxb" & i.ToString).Text = "い" & i.ToString
        Next
こんなコードでも正常動作を確認できました。

単純にケアレスミスなんじゃないでしょうか?
コントロールの名前のスペルミスとか。
実はテキストボックスがグループボックスの上に乗っていないものが1個あったりとか。


himizu  2012-02-17 04:47:29  No: 147495

>魔界の仮面弁士さま
>とくまさま

ご返信ありがとうございます。
お二人のご指摘通りケアレスミスでした。。
以下のフォーム構成にしているのを失念していました。。
本当に情けないです。

各グループボックスをまとめるグループボックスの配置をしていました。

Form1
    GroupBox0★
          GroupBox1−TextBoxa1,TextBoxb1
          GroupBox2−TextBoxa2,TextBoxb2
          GroupBox3−TextBoxa3,TextBoxb3
          GroupBox4−TextBoxa4,TextBoxb4

下記コードでエラーなく処理できました。

  Me.GroupBox0.Controls("GroupBox" & i.ToString).Controls("TextBoxa" & i.ToString).Text = Status
  Me.GroupBox0.Controls("GroupBox" & i.ToString).Controls("TextBoxb" & i.ToString).Text = name

質問に対して、ご検討してくださった方々はほんとに有難うございました。
また、ご指摘以外にも参考になる情報を頂いたので今後のスキルアップへつなげたいと思います。


himizu  2012-02-17 04:48:00  No: 147496

解決しました


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加