Visual Basic 中学校 掲示板
投稿内容
タグのない投稿を抽出
統計
RSS
Visual Basic 中学校
>
投稿一覧
>
配列とコントロールの繰り返しについて
タグの編集...
投稿者
緑
 (学生)   投稿日時
2022/5/12 15:29:24
何度も質問申し訳ございません。
二次元配列(i,j)というものを宣言し、フォーム上にテキストボックスが表の様に並んでいるものとします。
そしてこのテキストボックスの名前は、i,
TextBox0_0 TextBox0_1 ~TextBox0_3 TextBox1_0 TextBox1_1 ~
の様に、配列の添え字とTextBoxの後ろの数字が一致しています。
ここで疑問なのですが、Forを使って二次元配列にセットするプログラムを調べたところ、
For i As Integer = 0 To 4
For j As Integer = 0 To 4
配列名(i, j) = i + j
Next
Next
の様に、二重でループをするという方法があるのは知っていますが、(例では足し算とさせていただきました)、上記の様にテキストボックスの数字をFor を使ってループし、代入することはできないのでしょうか?
今までは、
配列名(0,0) = TextBox0_0.Text
のようにすべて入力して代入をしていたので、もっといい方法がないかと思い質問させていただきました。
お手数ですがご回答よろしくお願いいたします。
投稿者
魔界の仮面弁士
 (社会人)   投稿日時
2022/5/12 15:37:36
> 上記の様にテキストボックスの数字をFor を使ってループし、代入することはできないのでしょうか?
そのための手段(コントロールの名前を使ってアクセスする方法)は、
今週月曜日にお伝えしたばかりですよね???
http://rucio.cloudapp.net/ThreadDetail.aspx?ThreadId=30726
> フォーム上にテキストボックスが表の様に並んでいるものとします。
ちなみに、TableLayoutPanel って使ってますか?
行・列に揃えてコントロールを配置する時に便利な代物です。
基本的には 1 つのセルにつき一つのコントールしか配置できないのですが、
複数セルにまたがるように配置することもできます。
列番号と行番号を指定して、コントロールにアクセスすることや、
TableLayoutPanel1.GetControlFromPosition(2, 3).Text = "あいうえお"
その逆に、コントロールがどの位置にあるかを確認することもできます。
Dim pos = TableLayoutPanel1.GetCellPosition(TextBox1)
MsgBox(pos.Column & "," & pos.Row)
投稿者
緑
 (学生)   投稿日時
2022/5/12 16:10:52
二つ数字があるので、もう一度質問してしまいました、申し訳ございません。
もう一度そちらを見てやってみたいと思います。
今まさにTableLayoutPanelというものにテキストボックスを配置しているので、魔界の仮面弁士さんが仰っているコントロールへのアクセス方法が使えると思うのでやってみたいと思います。
投稿者
緑
 (学生)   投稿日時
2022/5/13 10:38:53
連投申し訳ございません。
自分でやっては見たのですが力不足でできませんでした、、
お気を煩わせてしまうかもしれませんがご回答のほどよろしくお願いいたします。
投稿者
魔界の仮面弁士
 (社会人)   投稿日時
2022/5/13 13:31:35
'案1:TableLayoutPanel 上にあるすべてのテキストボックスに同じ値を入れたい
Dim
s
As
String
=
"example1"
For
Each
txt
In
TableLayoutPanel1.Controls.OfType(
Of
TextBox)()
txt.Text = s
'txt.Text = txt.Name
Next
'案2:TableLayoutPanel のインデックスを使って代入したい(コントロールの名前は考慮しない)
Dim
s
As
String
=
"example2"
For
x = 0
To
3
For
y = 0
To
1
Dim
txt =
TryCast
(TableLayoutPanel1.GetControlFromPosition(x, y), TextBox)
If
txt
IsNot
Nothing
Then
txt.Text = s
End
If
Next
Next
'案3:TableLayoutPanel に載せてある TextBoxY_X のみを対象にしたい
Dim
s
As
String
=
"example3"
For
Each
txt
In
TableLayoutPanel1.Controls.OfType(
Of
TextBox)()
If
txt.Name
Like
"TextBox#_#"
Then
txt.Text = s
End
If
Next
'案4:配置場所が TableLayoutPanel であるかどうかを問わず、TextBoxY_X という名を対象にしたい
Dim
s
As
String
=
"example4"
For
x = 0
To
3
For
y = 0
To
1
Dim
textBoxName = $
"TextBox{y}_{x}"
Me
.Controls.Find(textBoxName,
True
)(0).Text = s
Next
Next
※VB2005 以下のバージョンを対象とする場合は、上記それぞれ、もう少し手直しが必要です。
※案4 の『Dim textBoxName = $"TextBox{y}_{x}"』は VB2015 以降向けの構文です。
VB2008~2013 の場合には、『Dim textBoxName = String.Format("TextBox{1}_{0}", x, y)』
もしくは『Dim textBoxName = "TextBox" & CStr(y) & "_" & CStr(x)』のようにしてください。
投稿者
魔界の仮面弁士
 (社会人)   投稿日時
2022/5/13 13:43:48
なお、月曜日に回答した
> 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
にあたるのが上記の案4です。
『Dim textBoxName As String = "TextBox" & CStr(n)』の部分が、数値が 2 つになって
『Dim textBoxName As String = "TextBox" & CStr(y) & "_" & CStr(x)』に変わっただけで、
あとは「Me.Controls.Find(textBoxName, True)(0)」でアクセスできるという点は変わりません。
なお、案4 の名前での全探索は、あまり多用しないようが望ましいです。
何度も使う場合には、前回も回答しましたように Form1_Load で Controls.Find を呼び出して、
その検索した結果を、適当なフィールド変数(たとえば Private Tables(2, 1) As TextBox など)に
キャッシュしておき、その他の処理(たとえば Button1_Click)ではその変数を
ループ処理のために用いた方が好ましいです。
投稿者
魔界の仮面弁士
 (社会人)   投稿日時
2022/5/13 17:52:46
>> コントロール数が多い場合は、初回のみ Controls.Find で探索し、
>> それをキャッシュすると良いですね。
蛇足とは思いますが、二次元配列にキャッシュしてみる例。
TextBox0_0 TextBox0_1 TextBox0_2 TextBox0_3
TextBox1_0 TextBox1_1 TextBox1_2 TextBox1_3
の 8 つのテキストボックスが貼ってある想定です。
Private
二次元配列(0
To
1, 0
To
3)
As
TextBox
Private
Sub
Form1_Load(sender
As
Object
, e
As
EventArgs)
Handles
MyBase
.Load
'Controls.Find で探したテキストボックスを、二次元配列にキャッシュしておく
For
i = 0
To
1
For
j = 0
To
3
Dim
controlName
As
String
= $
"TextBox{i}_{j}"
二次元配列(i, j) =
DirectCast
(
Me
.Controls.Find(controlName,
True
)(0), TextBox)
Next
Next
End
Sub
'その後は二次元配列を使って、テキストボックスをループ処理できる
Private
Sub
Button1_Click(sender
As
Object
, e
As
EventArgs)
Handles
Button1.Click
For
i = 0
To
1
For
j = 0
To
3
二次元配列(i, j).Text = $
"{i}-{j}"
Next
Next
End
Sub
Private
Sub
Button2_Click(sender
As
Object
, e
As
EventArgs)
Handles
Button2.Click
For
Each
txt
In
二次元配列
txt.Text =
""
Next
End
Sub
投稿者
緑
 (学生)   投稿日時
2022/5/16 10:24:58
ご回答ありがとうございます、初心者なのでたくさんのことを記述していただき大変うれしく思います。
まだプログラムは完成していませんが参考にして進めたいと思います。
初心者の質問で誠に申し訳ないのですが、
Dim controlName As String = $"TextBox{i}_{j}"
のように書かれている、$の部分、記号は何を表しているのでしょうか?
変数を定義するときに昔は使っていたという記述をWebサイトで見ましたが、気になったので聞いてみました。
投稿者
魔界の仮面弁士
 (社会人)   投稿日時
2022/5/16 11:29:21
「$」という記号キーワードは、Google などでも検索しにくいので厄介ですよね…。
> Dim controlName As String = $"TextBox{i}_{j}"
> のように書かれている、$の部分、記号は何を表しているのでしょうか?
> 変数を定義するときに昔は使っていたという記述をWebサイトで見ましたが、気になったので聞いてみました。
変数定義に使う「$」と、今回使っている「$」は、実は全く別のものなのです。
$"TextBox{i}_{j}" のように、先頭に $ を付与した記述は、
専門用語で 『文字列補間機能』や『補完文字列』などと呼ばれます。
また、その中の { } で囲まれた部分のことは『挿入文字列』と呼ばれます。
これは VB では 2015 から(C# では 2013 から)追加された、比較的「新しい文法」です。
下記の説明を読んでみてください。
VB → http://rucio.o.oo7.jp/VBNyumon/BEGIN6.htm
C# → https://www.umayadia.com/CSNyumon/BEGIN6.htm
一方、昔使われていたという変数定義の方は、
Dim controlName As String
という記述を
Dim controlName$
と書けるという物であり、こちらは『型文字』もしくは『型宣言文字』と呼ばれます。
(VB.NET では型文字、VBA でも型宣言文字と呼ばれることが多いです)
文字列型以外にも、幾つかの数値型に対しても型文字(型宣言文字)が用意されています。
今見ているサイト(VB中学校)でも紹介されていますね。
https://www.umayadia.com/VBStandard2/Standard03.htm
https://www.umayadia.com/Note/Note049VBDataType.htm
ただし、数値型の型文字(型宣言文字)は今でもしばしば使われることがありますが、
文字列型のための $ の型宣言文字は、今ではあまり使われていません。
一方、文字列補間機能の方の $ は便利なので、今ではよく使われるようになってきましたが、
比較的新しい文法なので、古い書籍などには記載されていないことが多いです。
投稿者
緑
 (学生)   投稿日時
2022/5/16 13:55:59
文字列補完機能を使う合図なんですね!
中々出てこず、URLの方も過去に読んではいたのですが、忘れておりました、、
しっかりメモとして残しておきたいと思います、回答ありがとうございました。