SelectedValueChangedに関して

解決


misamisa  2012-12-11 10:11:48  No: 148018  IP: [192.*.*.*]

環境:Visual Basic 2008

何度も投稿して申し訳ありません。

SelectedValueChangedの使い方に関して教えて下さい。

現在、画面の起動時にデータベースからデータをバインドし、コンボボックスを2つ(CMB_依頼業者名/CMB_返却業者名)
作成していますが、起動後の動きとして、そのプルダウンが選択されたらその選択肢によってDataRepeterに表示される内容を
変更しようと考えています。

その際、下記の例でいくと、依頼業者名が変更されたら、絞込み表示という事をしたいと考えていますが、
同時にもう1つの返却業者の値も条件に付加しないといけないと考えています。

そこで、依頼業者の方のSelectedValueChangedの中に、返却業者の取得する記述をしましたが、画面起動時に
返却業者の方のプルダウンが作成される以前にSelectedValueChangedへ飛んでしまう為、下記の"ここでエラー"という箇所
で、
  "オブジェクト参照がオブジェクト インスタンスに設定されていません。"
というエラーとなってしまいます。

当然といえば当然ですが、、、、

画面Load時にSelectedValueChangedへ飛ばない方法や、飛んだとしても抜ける方法、あるいは何か他の回避方法があれば
教えて頂きたいと思います。

わかりにくい内容で申し訳ありません。

よろしくお願いします。

《記述内容  −−  かなり抜粋してあります。》

    Private Sub 仕様書_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

        Try

            Dim dt3 = New DataTable
            Dim ds3 As New DataSet

            'SQL文作成
            Dim adp3 As New OracleDataAdapter("SELECT * FROM T_仕入先マスタ ORDER BY 仕入先コード", Connection)

            ds3.Clear()

            adp3.Fill(ds3, "T_仕入先コード")

            Dim newCustomersRow As DataRow = ds3.Tables("T_仕入先コード").NewRow()

            newCustomersRow("仕入先コード") = "000"
            newCustomersRow("仕入先名称") = ""

            ds3.Tables("T_仕入先コード").Rows.InsertAt(newCustomersRow, 0)

            CMB_依頼業者名.DataSource = ds3.Tables("T_仕入先コード")
            CMB_依頼業者名.DisplayMember = "仕入先名称"
            CMB_依頼業者名.ValueMember = "仕入先コード"

        Catch ex As Exception

            ' 例外が発生した時の処理
            MessageBox.Show(ex.ToString, "例外発生")

        End Try

        Try

            Dim dt4 = New DataTable
            Dim ds4 As New DataSet

            'SQL文作成
            Dim adp4 As New OracleDataAdapter("SELECT * FROM T_仕入先マスタ ORDER BY 仕入先コード", Connection)

            ds4.Clear()

            'データセットの中にT_部品名称というテーブルを作成し、そこへ格納する。
            adp4.Fill(ds4, "T_返却業者")

            Dim newCustomersRow As DataRow = ds4.Tables("T_返却業者").NewRow()

            newCustomersRow("仕入先コード") = "000"
            newCustomersRow("仕入先名称") = ""

            ds4.Tables("T_返却業者").Rows.InsertAt(newCustomersRow, 0)

            ' コンボボックスに部品名称テーブルを連結する
            CMB_返却業者名.DataSource = ds4.Tables("T_返却業者")
            ' コンボボックスに部品名称を表示する
            CMB_返却業者名.DisplayMember = "仕入先名称"
            ' 部品コードをSelectdValueで取得する
            CMB_返却業者名.ValueMember = "仕入先コード"

        Catch ex As Exception

            ' 例外が発生した時の処理
            MessageBox.Show(ex.ToString, "例外発生")

        End Try




    End Sub

    Private Sub CMB_依頼業者名_SelectedValueChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CMB_依頼業者名.SelectedValueChanged


        Dim IN_CMB_依頼業者コード As String
        Dim IN_CMB_返却業者コード As String

        '変数初期化
        A_FLAG = 0

        Dim RowV As DataRowView = CType(CMB_依頼業者名.SelectedItem, DataRowView)
        IN_CMB_依頼業者コード = RowV("仕入先コード")


        If IN_CMB_依頼業者コード Is Nothing Or IN_CMB_依頼業者コード = "000" Then

            A_FLAG = 1

        End If

        Dim RowV4 As DataRowView = CType(CMB_返却業者名.SelectedItem, DataRowView)    ←  ここでエラー
        IN_CMB_返却業者コード = RowV4("仕入先コード")


        If IN_CMB_返却業者コード Is Nothing Or IN_CMB_返却業者コード = "000" Then

            A_FLAG = 1

        End If

    End Sub

編集 削除
shu  2012-12-11 16:50:01  No: 148019  IP: [192.*.*.*]

> Dim RowV4 As DataRowView = CType(CMB_返却業者名.SelectedItem, DataRowView)    ←  ここでエラー
ここでエラーだとするとCMB_返却業者名がNothingということになってしまいます。

> IN_CMB_返却業者コード = RowV4("仕入先コード")
ここではないでしょうか?

この例外が出るときは何かがNothingなのにそれを使おうとしたときに
発生します。〜 is Nothingで条件判定して処理を行わないようにすると
よいです。

編集 削除
うさぎ  2012-12-11 17:02:17  No: 148020  IP: [192.*.*.*]

今回の質問とは関係ないのですが、If文での論理和・論理積はOr, AndではなくOrElse, AndAlsoを使うようにしましょう。

例えば、

> If IN_CMB_依頼業者コード Is Nothing Or IN_CMB_依頼業者コード = "000" Then

では論理和の演算子としてOrが使用されていますが、これは、
・IN_CMB_依頼業者コード Is Nothing
・IN_CMB_依頼業者コード = "000"
を両方評価します。これだと、IN_CMB_依頼業者コードがNothingの場合でも(IN_CMB_依頼業者コード = "000")の評価を行おうとしますが、
肝心のIN_CMB_依頼業者コードがNothingのため、結局
"オブジェクト参照がオブジェクト インスタンスに設定されていません。"
の例外となってしまいます。

  If IN_CMB_依頼業者コード Is Nothing OrElse IN_CMB_依頼業者コード = "000" Then

とすれば、(IN_CMB_依頼業者コード Is Nothing)を評価し、これがTrueであれば(つまり、IN_CMB_依頼業者コードがNothingであれば)即時に評価を終了し、
このIf文はTrueであるとして処理します。

VB.netでのOrやAndはビット演算にのみ使うようにしてください。

編集 削除
misamisa  2012-12-14 10:15:13  No: 148021  IP: [192.*.*.*]

shu様、うさぎ様、ご回答ありがとうございます。

Nothing の処理で回避する方法をとりました。

ありがとうございました!

編集 削除