環境: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
> Dim RowV4 As DataRowView = CType(CMB_返却業者名.SelectedItem, DataRowView) ← ここでエラー
ここでエラーだとするとCMB_返却業者名がNothingということになってしまいます。
> IN_CMB_返却業者コード = RowV4("仕入先コード")
ここではないでしょうか?
この例外が出るときは何かがNothingなのにそれを使おうとしたときに
発生します。〜 is Nothingで条件判定して処理を行わないようにすると
よいです。
今回の質問とは関係ないのですが、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はビット演算にのみ使うようにしてください。
shu様、うさぎ様、ご回答ありがとうございます。
Nothing の処理で回避する方法をとりました。
ありがとうございました!
ツイート | ![]() |