Visual Basic 中学校 掲示板 投稿内容
タグのない投稿を抽出 統計 RSS

Visual Basic 中学校 > 投稿一覧 >

テキストボックスの値を配列に格納したい 解決済み

タグの編集...

投稿者   (学生)   投稿日時 2022/5/9 10:47:55
 初の質問失礼します、VB初心者です。

 フォーム上にテキストボックスが10つ、ボタンが1つ、リストボックスが1つあります。

 テキストボックスに入力された値は配列に格納しなければならないという条件のもと、ボタンを押すと10つのテキストボックスに入力された文字をリストボックスに表示するプログラムを書いています。

 テキストボックスの値を配列に格納することはできたのですが、テキストボックスに空欄がある場合、リストボックスに空の行ができてしまうことを避けたいです。(例えばテキストボックス1と9だけに値を入力した場合、空の行ができずにリストボックスに2行だけ表示されるようにしたい)

 どのようなプログラムを書けばよいか手が止まってしまったので質問させていただきました、よろしくお願いいたします!


投稿者 魔界の仮面弁士   (社会人)   投稿日時 2022/5/9 11:06:43
> テキストボックスに入力された値は配列に格納しなければならないという条件のもと

「テキストボックスの配列」ではなく、
Dim textBoxes As TextBox() = {TextBox1, TextBox2, TextBox3}
「テキストボックスに入力された値の配列」なのですね?
Dim values As String() = {TextBox1.Text, TextBox2.Text, TextBox3.Text}


> 空の行ができずにリストボックスに2行だけ表示されるようにしたい
ListBox1.DataSource = values.Where(Function(s) s <> "").ToArray()

投稿者 (削除されました)   ()   投稿日時 2022/5/9 11:23:07
(削除されました)

投稿者   (学生)   投稿日時 2022/5/9 11:49:17
「テキストボックスに入力された値の配列」で間違いありません。

ありがとうございました!問題解決いたしました。Function(s)sの部分がどのような仕組みになっているカ疑問なので調べてみることにいたします!

このようなことをやるときに追加の質問がございまして、
たくさんのテキストボックスを配列に格納する場合、Textbox1,TextBox2~と毎回書くのではなく、ループなどを使った方がテキストボックスの数が増えた時に便利かなと考えたのですが、そのやり方もできれば教えていただきたいです。


例えば次のような感じです。
新たにボタンを配置して、ボタン2押すと全てのテキストボックスが空になるといった時に、何回もTextbox1.Text = "" 
Textbox2.Text = "" と記載すると長くなってしまうので短くなる方法ないかなと思い質問させていただきました。

投稿者 魔界の仮面弁士   (社会人)   投稿日時 2022/5/9 16:25:27
コントロールの「名前」を使ってアクセスすることができます。
方法としては、
 Dim ctrl As Control = Me.Controls("TextBox1")
 ctrl.Text = ""
または、
 Dim ctrl As Control = Me.Controls.Find("TextBox1", True)(0)
 ctrl.Text = ""
です。TextBox 型が必要な場合は、DirectCast します。


Dim n As Integer
Dim txtName As String = "TextBox" & CStr(n)

Dim txtBox As TextBox = DirectCast(Me.Controls.Find(txtName, True)(0), TextBox)
txtBox.BackColor = Color.Red
MsgBox(txtBox.Text)



記述としては Controls(name) と Controls.Find(name, True)(0) のどちらでも良いですが、
前者の方法では、Panel や GourpBox の下に TextBox がある場合は、
 Me.Controls("TextBox1")
ではなく
 Panel1.Controls("TextBox1")
のように書かねばならない点に注意が必要です。

一方 Controls.Find の場合は、第二引数を True とすることで、階層下のコントロールも
すべて調べることができます。Controls.Find は、同じ名前のコントロールが
複数あった場合に備えて、結果を配列として返すように実装されているため、
上記では (0) を指定して、先頭要素を取り出してアクセスしています。


しかし、毎回名前を使って検索するのは効率が悪いので、
何度も使いまわされるコントロール群に関しては、
あらかじめ Form の Load 時などで設定しておいた方が良いでしょう。

Private TextGroup1 As TextBox()
Private Sub Form1_Load(……
    TextGroup1 = { TextBox1, TextBox2, TextBox 3 }
End Sub

Private Sub Button1_Click(……
    For Each txt In TextGroup1
        txt.Text = ""
    Next
End Sub



コントロール数が多い場合は、初回のみ Controls.Find で探索し、
それをキャッシュすると良いですね。


Private TextGroup2 As New List(Of TextBox)()
Private Sub Form1_Load(……
    For n = 1 To 20
        For Each txt As TextBox In Me.Controls.Find("TextBox" & CStr(n), True)
            TextGroup2.Add(txt)
        Next
    Next
End Sub

Private Sub Button1_Click(……
    ListBox1.Items.Clear()
    For Each txt In TextGroup2
        If txt.Text <> "" Then
            ListBox1.Items.Add(txt.Text)
        End If
    Next
End Sub


投稿者   (学生)   投稿日時 2022/5/9 18:00:02
とても情報量の多い丁寧なご回答ありがとうございます。

全て理解するには大変ですが、FormのLoad時に記載する方法で解決いたしました!

また悩み事があればよろしくお願いいたします!