VB2019 オブジェクトの名前を読み込ませたい

タグの編集
投稿者 ロト君  (社会人) 投稿日時 2020/5/9 09:31:07
環境 ---
Visual Basic 2019
Windows10

内容 ---
Private Sub Cmb_set(ByVal cmb_name As String, ByVal cmb_str As String)
で、下記の様なコンボボックスを作成したいです。

コード ---
1)

Cmb_set("Cmb_class", "区分")

2)

    Private Sub Cmb_set(ByVal cmb_name As String, ByVal cmb_str As String)

        Try

            connect.ConnectionString = conections_str
            connect.Open()

            Dim oda As New OleDbDataAdapter
            Dim ods As New DataSet
            Dim sql As String

            sql = "Select "
            sql &= "key_name, "
            sql &= "name1, "
            sql &= "value1, "
            sql &= "sort, "
            sql &= "delflg "
            sql &= "From m_env "
            sql &= "Where delflg = 0 "
            sql &= "And key_name = '" & cmb_str & "' "
            sql &= "Order By sort Asc"

            oda = New OleDbDataAdapter(sql, connect)
            ods.Tables.Add("m_env")
            oda.Fill(ods.Tables("m_env"))

            cmb_name.DataSource = ods.Tables("m_env")
            cmb_name.DisplayMember = "name1"
            cmb_name.ValueMember = "value1"

            'ComboBox のスタイルを指定します
            cmb_name.DropDownStyle = ComboBoxStyle.DropDownList
            '先頭のアイテムを表示させる
            cmb_name.SelectedIndex = -1

            connect.Close()

        Catch ex As Exception

            MsgBox("接続エラーです。", vbOKOnly, "接続エラー")
            connect.Close()
            Exit Sub

        End Try

    End Sub

内容 ---

*.mdb内のm_envテーブルから、
区分のkey_nameだけを取り出して、sortの値でソートされた任意のコンボボックスを作成したいのですが、任意のコンボボックス名を指定する事が出来ません。

どなたか、ご教授お願いいたします。
投稿者 ロト君  (社会人) 投稿日時 2020/5/9 10:02:49
自力で解決出来ましたのでコードを記載いたします。

コード ---
1)

    Public Function FindControl(ByVal hParent As Control, ByVal stName As String) As Control
        ' hParent 内のすべてのコントロールを列挙する
        For Each hControl As Control In hParent.Controls
            ' 列挙したコントロールにコントロールが含まれている場合は再帰呼び出しする
            If hControl.HasChildren = True Then
                Dim hFindControl As Control = FindControl(hControl, stName)

                ' 再帰呼び出し先でコントロールが見つかった場合はそのまま返す
                If Not hFindControl Is Nothing Then
                    Return hFindControl
                End If
            End If

            ' コントロール名が合致した場合はそのコントロールのインスタンスを返す
            If hControl.Name = stName Then
                Return hControl
            End If
        Next hControl
    End Function

2)

   Private Sub Cmb_set(ByVal cmb_name As String, ByVal cmb_str As String)

        Try

            connect.ConnectionString = conections_str
            connect.Open()

            Dim oda As New OleDbDataAdapter
            Dim ods As New DataSet
            Dim sql As String

            sql = "Select "
            sql &= "key_name, "
            sql &= "name1, "
            sql &= "value1, "
            sql &= "sort, "
            sql &= "delflg "
            sql &= "From m_env "
            sql &= "Where delflg = 0 "
            sql &= "And key_name = '" & cmb_str & "' "
            sql &= "Order By sort Asc"

            oda = New OleDbDataAdapter(sql, connect)
            ods.Tables.Add("m_env")
            oda.Fill(ods.Tables("m_env"))

            Dim ctrl As ComboBox = FindControl(Me, cmb_name)

            ctrl.DataSource = ods.Tables("m_env")
            ctrl.DisplayMember = "name1"
            ctrl.ValueMember = "value1"

            'ComboBox のスタイルを指定します
            ctrl.DropDownStyle = ComboBoxStyle.DropDownList
            '先頭のアイテムを表示させる
            ctrl.SelectedIndex = -1

            connect.Close()

        Catch ex As Exception

            MsgBox("接続エラーです。", vbOKOnly, "接続エラー")
            connect.Close()
            Exit Sub

        End Try

    End Sub

3)

        Cmb_set("Cmb_class", "区分")
        Cmb_set("Cmb_landowner", "地権")
        Cmb_set("Cmb_produce1", "作物名")
        Cmb_set("Cmb_produce2", "作物名")

内容 ---

上記の記述で無事に動きました。
3)が呼び出し方
2)が*mdbでの参照
1)がコントロール名の取得です。

同じように困ってる方がいらっしゃったら使って見て下さい。
投稿者 ロト君  (社会人) 投稿日時 2020/5/9 10:04:33
参考にしたものは下記のモノです。

http://uno036.starfree.jp/PRGmanual/vsnet_tips/form/findcontrol.html
投稿者 魔界の仮面弁士  (社会人) 投稿日時 2020/5/9 13:38:43
既に解決済みのようですが:

> Public Function FindControl(ByVal hParent As Control, ByVal stName As String) As Control
stName が無かった時の Return が省略されているので、警告が出ていますね。

それと上記の処理は、もっと簡単に書けそうです。

Public Function FindControl(hParent As Control, stName As StringAs Control
      Return hParent?.Controls?.Find(stName, True)?.FirstOrDefault()
End Function



> Dim ctrl As ComboBox = FindControl(Me, cmb_name)

このコードだと、Option Strict On の時に型変換の問題が発生してしまいますので、
先のメソッドに、型パラメーター付のオーバーロードを用意するのが良さそうです。

Public Function FindControl(Of T As Control)(hParent As Control, stName As StringAs T
      Return hParent?.Controls?.Find(stName, True)?.OfType(Of T)?.FirstOrDefault()
End Function


このようにしておけば、
 Dim ctrl = FindControl(Of ComboBox)(Me, cmb_name)
のように使うことで、 Option Strict On の場合にも対処させることができます。


>   connect.Close()
> Catch ex As Exception
>   MsgBox(接続エラーです。", vbOKOnly, "接続エラー")
>   connect.Close()
>   Exit Sub
> End Try

Try 句と Catch 句の両方で Close していますが、
こういう時は Finally 句を利用した方が良いと思いますよ。