コントロールをまとめて操作。
         
        投稿者 (削除されました)  ()
        
        投稿日時 
            2018/5/11 17:11:31
        
    
    
        (削除されました)
    
    
        投稿者 魔界の仮面弁士  (社会人)
        
        投稿日時 
            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/13 21:24:01
        
    
    
        魔界の仮面弁士様
ありがとうございました。
解決しました
    
ありがとうございました。
解決しました
        投稿者 コントロールをまとめて操作。  (社会人)
        
        投稿日時 
            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/15 19:54:42
        
    
    
        (削除されました)
    
    
        投稿者 魔界の仮面弁士  (社会人)
        
        投稿日時 
            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 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/16 00:24:43
        
    
    
        「ゆうさく」さんと、「コントロールをまとめて操作。」さんは同じ方ですか? あるいは同僚?
> 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 を用いてやれば良いのではないか、という意味です。
    
> a = Val(TextBox1.Text)
この書き方だとエラーになりえますので、これも先の回答と同じ理由により NG です。
TryParse を使うとか、NumericUpDown に切り替えるなどするのが安全かと思います。
Val を使った変換は、一見うまくいくかのようにも見えますが、たとえば
TextBox1.Text = "1.2%"
a = Val(TextBox1.Text)
などのように、変換できずに InvalidCastException となるパターンがあります。
> emptyのところに空欄のテキストボックスの数が入るようにしたいです
その代入操作を、For Each のループ処理で、繰り返し行っている理由が分からなかったのです。
前回のコード例にて、ループ処理せずに使わずにカウントする方法を提示していますよね。
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    Dim emptyCount As Integer = Controls.OfType(Of TextBox)().Count(Function(t) t.TextLength = 0)
    MsgBox(emptyCount & "個空白です")
End Sub>> For Each o As Control In Me.Controls
>> If TypeOf o Is TextBox Then
>> If o.Text = "" Then
> 先の例のように、OfType で絞り込んだ方が手っ取り早いかと。
これは要するに、For Each をするにしても、わざわざ TypeOf や .GetType() で型判定せずとも、
最初の回答に載せた OfType を用いてやれば良いのではないか、という意味です。
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    Dim emptyCount As Integer = 0
    Dim nonValueCount As Integer = 0
    Dim minusCount As Integer = 0
    Dim d As Double
    For Each txt In Me.Controls.OfType(Of TextBox)()
        If txt.TextLength = 0 Then
            emptyCount += 1
        ElseIf Not Double.TryParse(txt.Text, d) Then
            nonValueCount += 1
        ElseIf d < 0.0 Then
            minusCount += 1
        End If
    Next
    MsgBox("空白=" & emptyCount & "/非数値=" & nonValueCount & "/負数=" & minusCount)
End Sub
ボタンとテキストボックスを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