コントロールをまとめて操作。 への返答
投稿で使用できる特殊コードの説明。(別タブで開きます。)
以下の返答は逆順(新しい順)に並んでいます。
投稿者 コントロールをまとめて操作。  (社会人)
投稿日時
2018/5/15 21:08:40
>業務開発でしょうか。
他業種です。
最近、プログラミングに興味を持ち、始めたばかりです。
>Controls を For Each している最中に、その
>Controls を再列挙しているようですね。
>わざわざ二重に列挙しているのは何故ですか?
以前、教えていただいた、下記を参考にしました。
MsgBox(Controls.OfType(Of TextBox)().Count(Function(t) t.TextLength = 0) & "個空白です")
If TypeOf o Is TextBox Then
If o.Text = "" Then
empty =
emptyのところに空欄のテキストボックスの数が入るようにしたいです
>「テキストボックスの変数」というのは、どういう意味でしょうか。
下記のようにテキストボックスの値を変数に入れています。
Private a As Double
Private b As Double
Private c As Double
Private Sub txt()
a = Val(TextBox1.Text)
b = Val(TextBox2.Text)
end sub
他業種です。
最近、プログラミングに興味を持ち、始めたばかりです。
>Controls を For Each している最中に、その
>Controls を再列挙しているようですね。
>わざわざ二重に列挙しているのは何故ですか?
以前、教えていただいた、下記を参考にしました。
MsgBox(Controls.OfType(Of TextBox)().Count(Function(t) t.TextLength = 0) & "個空白です")
If TypeOf o Is TextBox Then
If o.Text = "" Then
empty =
emptyのところに空欄のテキストボックスの数が入るようにしたいです
>「テキストボックスの変数」というのは、どういう意味でしょうか。
下記のようにテキストボックスの値を変数に入れています。
Private a As Double
Private b As Double
Private c As Double
Private Sub txt()
a = Val(TextBox1.Text)
b = Val(TextBox2.Text)
end sub
投稿者 魔界の仮面弁士  (社会人)
投稿日時
2018/5/15 20:26:04
> 社会人
業務開発でしょうか。
常に『データ型』を意識してコーディングする癖をつけましょう。
> For Each o As Control In Me.Controls
> If TypeOf o Is TextBox Then
先の例のように、OfType で絞り込んだ方が手っ取り早いかと。
> empty = (Controls.OfType(Of TextBox)().Count(Function(t) t.TextLength = 0))
Controls を For Each している最中に、その
Controls を再列挙しているようですね。
わざわざ二重に列挙しているのは何故ですか?
> ElseIf o.Text <= 0 Then
Text プロパティは String 型で、
0 というリテラルは Integer 型ですよね。
「<=」の左右で、データ型が違っていますので、これだと
Double 型の比較式として処理されてしまいます。
(なので、Text の内容が Double として解釈できない時にエラーになるわけで)
数値入力に特化させたいのなら、TextBox1.Text ではなく、
NumericUpDown1.Value の利用をお奨めします。(Value は Decimal 型です)
NumericUpDown なら、小数部の桁数や最大値、最小値などを、
デザイン時に決めておくことができますし、数値以外の入力も防げます。
どうしても TextBox が必要なら、数値として変換できることを保証するために、
TryParse メソッドを併用すべきです。
> Dim empty As Integer
> If empty Then
ここは 『If empty > 0 Then』 なのでは?
> テキストボックスの変数はDoubleで宣言しています
「テキストボックスの変数」というのは、どういう意味でしょうか。
たとえば、
Dim t As TextBox = TextBox1
Dim s As String = TextBox1.Text
とは書けても、
Dim d As Double = TextBox1
とは書けないですよね。
もしかして、
Dim d As Double = TextBox1.Text
ということでしょうか?
だとしたらそれは間違いです。(代入式の左辺が Double 型で、右辺が String 型なので)
こういう場合には、TryParse メソッドを使いましょう。
業務開発でしょうか。
常に『データ型』を意識してコーディングする癖をつけましょう。
> For Each o As Control In Me.Controls
> If TypeOf o Is TextBox Then
先の例のように、OfType で絞り込んだ方が手っ取り早いかと。
> empty = (Controls.OfType(Of TextBox)().Count(Function(t) t.TextLength = 0))
Controls を For Each している最中に、その
Controls を再列挙しているようですね。
わざわざ二重に列挙しているのは何故ですか?
> ElseIf o.Text <= 0 Then
Text プロパティは String 型で、
0 というリテラルは Integer 型ですよね。
「<=」の左右で、データ型が違っていますので、これだと
Double 型の比較式として処理されてしまいます。
(なので、Text の内容が Double として解釈できない時にエラーになるわけで)
数値入力に特化させたいのなら、TextBox1.Text ではなく、
NumericUpDown1.Value の利用をお奨めします。(Value は Decimal 型です)
NumericUpDown なら、小数部の桁数や最大値、最小値などを、
デザイン時に決めておくことができますし、数値以外の入力も防げます。
どうしても TextBox が必要なら、数値として変換できることを保証するために、
TryParse メソッドを併用すべきです。
> Dim empty As Integer
> If empty Then
ここは 『If empty > 0 Then』 なのでは?
> テキストボックスの変数はDoubleで宣言しています
「テキストボックスの変数」というのは、どういう意味でしょうか。
たとえば、
Dim t As TextBox = TextBox1
Dim s As String = TextBox1.Text
とは書けても、
Dim d As Double = TextBox1
とは書けないですよね。
もしかして、
Dim d As Double = TextBox1.Text
ということでしょうか?
だとしたらそれは間違いです。(代入式の左辺が Double 型で、右辺が String 型なので)
こういう場合には、TryParse メソッドを使いましょう。
Dim d As Double = 0.0
If Double.TryParse(TextBox1.Text, d) Then
投稿者 (削除されました)  ()
投稿日時
2018/5/15 19:54:42
(削除されました)
投稿者 コントロールをまとめて操作。  (社会人)
投稿日時
2018/5/15 19:54:41
Dim m As Integer
Dim empty As Integer
For Each o As Control In Me.Controls
If TypeOf o Is TextBox Then
If o.Text = "" Then
empty = (Controls.OfType(Of TextBox)().Count(Function(t) t.TextLength = 0))
ElseIf o.Text <= 0 Then
m = (Controls.OfType(Of TextBox).Count(Function(t) t.Text <= 0))
End If
End If
Next
If empty Then
empty = MsgBox(empty & "個空白です")
ElseIf m Then
m = MsgBox(m & "個正しく入力してください")
End If
End Sub
1つめのテキストボックスにマイナスの値を入れて、ボタンを押すと
m = (Controls.OfType(Of TextBox).Count(Function(t) t.Text <= 0))
のところで下記エラーが出ます
System.InvalidCastException: 'String "" から型 'Double' への変換は無効です。'
エラーがでなくなる方法を教えてください(テキストボックスの変数はDoubleで宣言しています)
Dim empty As Integer
For Each o As Control In Me.Controls
If TypeOf o Is TextBox Then
If o.Text = "" Then
empty = (Controls.OfType(Of TextBox)().Count(Function(t) t.TextLength = 0))
ElseIf o.Text <= 0 Then
m = (Controls.OfType(Of TextBox).Count(Function(t) t.Text <= 0))
End If
End If
Next
If empty Then
empty = MsgBox(empty & "個空白です")
ElseIf m Then
m = MsgBox(m & "個正しく入力してください")
End If
End Sub
1つめのテキストボックスにマイナスの値を入れて、ボタンを押すと
m = (Controls.OfType(Of TextBox).Count(Function(t) t.Text <= 0))
のところで下記エラーが出ます
System.InvalidCastException: 'String "" から型 'Double' への変換は無効です。'
エラーがでなくなる方法を教えてください(テキストボックスの変数はDoubleで宣言しています)
投稿者 コントロールをまとめて操作。  (社会人)
投稿日時
2018/5/13 21:24:01
魔界の仮面弁士様
ありがとうございました。
解決しました
ありがとうございました。
解決しました
投稿者 魔界の仮面弁士  (社会人)
投稿日時
2018/5/11 18:45:23
とりあえず、こんな感じですかね。
> For Each o In Me.Controls
対象とするのは、フォーム上に置かれたコントロールだけで構いませんか?
上記の構文の場合、Panel や GruopBox の上に置かれたコントロールは拾われません。
もしも Panel 上のコントロールを列挙する場合は、Me.Controls ではなく Panel1.Controls を使います。
> Dim o As Control
> For Each o In Me.Controls
これは、.NET Framework 1.0 (VB.NET 2002)世代の書き方ですね。
VB.NET 2003 以降では
> If o.GetType Is GetType(TextBox) Then
こういう場合には
『o が TextBox クラス』だった場合、どちらの構文も True を返しますが、
『o が TextBox を継承したクラス』が相手の場合、
「o.GetType Is GetType(TextBox)」は False を返し、
「TypeOf o Is TextBox」は True を返す仕様です。
ちなみに、TextBox だけでなく RichTextBox も含めたいような場合には、
If TypeOf o Is TextBoxBase Then
と書けます。(TextBox も RichTextBox も、TextBoxBase を継承しています)
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
MsgBox(Controls.OfType(Of TextBox)().Count(Function(t) t.TextLength = 0) & "個空白です")
End Sub
> For Each o In Me.Controls
対象とするのは、フォーム上に置かれたコントロールだけで構いませんか?
上記の構文の場合、Panel や GruopBox の上に置かれたコントロールは拾われません。
もしも Panel 上のコントロールを列挙する場合は、Me.Controls ではなく Panel1.Controls を使います。
> Dim o As Control
> For Each o In Me.Controls
これは、.NET Framework 1.0 (VB.NET 2002)世代の書き方ですね。
VB.NET 2003 以降では
For Each o As Control In Me.Controls
にした方が良いですよ。> If o.GetType Is GetType(TextBox) Then
こういう場合には
If TypeOf o Is TextBox Then
にした方がスマートでは無いでしょうか。『o が TextBox クラス』だった場合、どちらの構文も True を返しますが、
『o が TextBox を継承したクラス』が相手の場合、
「o.GetType Is GetType(TextBox)」は False を返し、
「TypeOf o Is TextBox」は True を返す仕様です。
ちなみに、TextBox だけでなく RichTextBox も含めたいような場合には、
If TypeOf o Is TextBoxBase Then
と書けます。(TextBox も RichTextBox も、TextBoxBase を継承しています)
投稿者 (削除されました)  ()
投稿日時
2018/5/11 17:11:31
(削除されました)
投稿者 ゆうさく  (社会人)
投稿日時
2018/5/10 21:24:49
前提・実現したいこと
ボタンとテキストボックスを9つ用意しています
ボタンを押した際に、テキストボックスに空欄があれば
空欄のテキストボックスの数をメッセージボックスに表示させたいです。
コード
Dim o As Control
For Each o In Me.Controls
If o.GetType Is GetType(TextBox) Then
if o.text = "" then
End If
End If
Next
msgbox(_&"個空白です")
アンダーバーのところに空欄のテキストボックスの数が入るようにしたいです
補足情報(FW/ツールのバージョンなど)
vb.net 2012
ボタンとテキストボックスを9つ用意しています
ボタンを押した際に、テキストボックスに空欄があれば
空欄のテキストボックスの数をメッセージボックスに表示させたいです。
コード
Dim o As Control
For Each o In Me.Controls
If o.GetType Is GetType(TextBox) Then
if o.text = "" then
End If
End If
Next
msgbox(_&"個空白です")
アンダーバーのところに空欄のテキストボックスの数が入るようにしたいです
補足情報(FW/ツールのバージョンなど)
vb.net 2012
> a = Val(TextBox1.Text)
この書き方だとエラーになりえますので、これも先の回答と同じ理由により NG です。
TryParse を使うとか、NumericUpDown に切り替えるなどするのが安全かと思います。
Val を使った変換は、一見うまくいくかのようにも見えますが、たとえば
TextBox1.Text = "1.2%"
a = Val(TextBox1.Text)
などのように、変換できずに InvalidCastException となるパターンがあります。
> emptyのところに空欄のテキストボックスの数が入るようにしたいです
その代入操作を、For Each のループ処理で、繰り返し行っている理由が分からなかったのです。
前回のコード例にて、ループ処理せずに使わずにカウントする方法を提示していますよね。
>> For Each o As Control In Me.Controls
>> If TypeOf o Is TextBox Then
>> If o.Text = "" Then
> 先の例のように、OfType で絞り込んだ方が手っ取り早いかと。
これは要するに、For Each をするにしても、わざわざ TypeOf や .GetType() で型判定せずとも、
最初の回答に載せた OfType を用いてやれば良いのではないか、という意味です。