DOBON.NET DOBON.NETプログラミング掲示板過去ログ

CheckedListBoxで選択した複数のDisplayMemberの各ValueMemberを取得するには

環境/言語:[VS.NET2003、XPSP3、.NET Framework 1.1]
分類:[.NET]

はじめまして、こんにちは。
お世話になります。

使用OS:XPSP3
使用言語:VS.NET2003
使用データベース:SQLServer2000

以下、質問させて頂きます。

SQLServer2000のデータベースに、
[業者マスタ]と[商品マスタ]の2つのテーブルがあります。

[業者マスタ]
(デザイン)
業者C(smallint)(主キー)
業者名(nvarchar)

(内容)
1 A社
2 B社
3 C社
4 D社

[商品マスタ]
(デザイン)
商品C(int)(主キー)
業者C(smallint)
商品名(nvarchar)

(内容)
100 1 商品A
101 2 商品B
102 3 商品C
103 4 商品D
104 1 商品E
105 5 商品F

フォーム(frmKensaku)をLoadしますと、
1つのCheckedListBox(lstGyousya)と、
1つの検索ボタン(btnKensaku)と、
データグリッド(dgrSyohin)があります。

lstGyousyaには、[業者マスタ]の[業者名]が表示されている状態にしています。
ValueMember=[業者C]、DisplayMember=[業者名]を設定しています。

検索したい[業者名]を複数チェックします。
この記事においては、[業者C]=1、2、3である、A社〜C社をチェックします。

この状態で、検索ボタンを押しますと、
[商品マスタ]より検索された商品一覧([商品C]、[業者C]、[商品名])がdgrSyohinに表示されるようにしたいと考えております。

[商品マスタ]の検索を行う際に必要なSQL文には、
lstGyousyaで選択された[業者名](DisplayMember)に対応する[業者C](ValueMember)が取得され、
"SELECT * FROM [商品マスタ] WHERE ([業者C] = 1 or 2 or 3)"
というSQL文が使われるようにしたいと考えております。

実際にこのコードを実行しますと、
lstGyousyaのValueMemberを取得する際に、
「型'Byte'の既定メンバが見つかりません」とエラー表示されてしまいます。
(下記コードの※※※の部分です)
複数のValueMemberを取得するためのコードに、
誤りがございましたら、
教えて頂きたく存じます。

お手数と存じますが、どうぞよろしくお願い申し上げます。

(コード)

-------------------------------------------------------------------
Private Sub frmKensaku_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load

Call ListBoxGyousya()

End Sub
-------------------------------------------------------------------
Private Sub ListBoxGyousya()

Dim cn As New SqlClient.SqlConnection
Dim da As SqlClient.SqlDataAdapter
Dim ds As New DataSet
Dim strSQL As String

Try
cn.ConnectionString = (接続文字列)
strSQL = "select [業者C],[業者名] from [業者マスタ] order by [業者C]"
da = New SqlClient.SqlDataAdapter(strSQL, cn)
da.Fill(ds)

lstGyousya.ValueMember = "業者C"
lstGyousya.DisplayMember = "業者名"
lstGyousya.DataSource = ds.Tables(0)
lstGyousya.SelectedIndex = -1

Catch ex As Exception
MessageBox.Show(ex.Message, "ListGyousya",MessageBoxButtons.OK, MessageBoxIcon.Error)

Finally
ds = Nothing
da = Nothing
cn = Nothing
End Try

End Sub
------------------------------------------------------------------------
Private Sub btnKensaku_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnKensaku.Click

Dim cnS As New SqlClient.SqlConnection(接続文字列)
Dim daS As New SqlClient.SqlDataAdapter
Dim strSQL As String
Dim strGyousya As String
Dim ds As New DataSet
Dim i As Integer
Dim blnLoopCheck As Boolean

Try
blnLoopCheck = False
If lstGyousya.CheckedItems.Count <> 0 Then
For i = 0 To lstGyousya.Items.Count - 1
If blnLoopCheck = False Then
strGyousya = "([業者C] = "
If lstGyousya.GetItemChecked(i) = True Then
strGyousya = "" & lstGyousya.SelectedValue(i).ToString & ""
End If
blnLoopCheck = True
Else
If lstGyousya.GetItemChecked(i) = True Then
strGyousya = "or"
strGyousya = "" & lstGyousya.SelectedValue(i).ToString & ""'※※※ここでエラー発生※※※
End If
      End If
Next
strGyousya &= ")"
End If

strSQL = "select * from [商品マスタ] where " & strGyousya & ""
daS = New SqlClient.SqlDataAdapter(strSQL, cnS)
daS.Fill(ds, "商品マスタ")
dgrSyohin.DataSource = ds

Catch ex As Exception
MessageBox.Show(ex.Message, "FrameShukei", MessageBoxButtons.OK, MessageBoxIcon.Error)
Finally
cnS = Nothing
End Try

End Sub
-----------------------------------------------------------------------
■No29607に返信(けいすけさんの記事)

> lstGyousya.SelectedValue(i)
lstGyousya.Items(i)
でどうでしょう?
■No29607に返信(けいすけさんの記事)
質問と直接には関係ありませんが、SQLのOR演算子の引数には、ブール値を返す式を指定する
必要があったように思います。
SELECT * FROM [商品マスタ] WHERE ([業者C] = 1 OR [業者C] = 2 OR [業者C] = 3)
もしくはIN演算子を使って、
SELECT * FROM [商品マスタ] WHERE [業者C] IN (1, 2, 3)
こんな感じのSQLが生成されるようにした方がよいと思われます。
■No29608に返信(shuさんの記事)

shuさま、ありがとうございます。
修正してみます。

> ■No29607に返信(けいすけさんの記事)
>
>>lstGyousya.SelectedValue(i)
> lstGyousya.Items(i)
> でどうでしょう?
■No29610に返信(もりおさんの記事)

もりおさま、ありがとうございます。
修正してみます。

> ■No29607に返信(けいすけさんの記事)
> 質問と直接には関係ありませんが、SQLのOR演算子の引数には、ブール値を返す式を指定する
> 必要があったように思います。
> SELECT * FROM [商品マスタ] WHERE ([業者C] = 1 OR [業者C] = 2 OR [業者C] = 3)
> もしくはIN演算子を使って、
> SELECT * FROM [商品マスタ] WHERE [業者C] IN (1, 2, 3)
> こんな感じのSQLが生成されるようにした方がよいと思われます。
■No29611に返信(けいすけさんの記事)
shuさま

修正して実行してみましたところ、
strGyousya="System.Data.DataRowView)"と代入されてしまいました。
引き続き、取り組んでみます。

> ■No29608に返信(shuさんの記事)
>
> shuさま、ありがとうございます。
> 修正してみます。
>
>>■No29607に返信(けいすけさんの記事)
>>
> >>lstGyousya.SelectedValue(i)
>>lstGyousya.Items(i)
>>でどうでしょう?
■No29613に返信(けいすけさんの記事)

ToStringを除いたところ、
型'DataRowView'から型'String'へのキャストが有効ではありません、
と出ました。
引き続き、取り組んでみます。

> ■No29611に返信(けいすけさんの記事)
> shuさま
>
> 修正して実行してみましたところ、
> strGyousya="System.Data.DataRowView)"と代入されてしまいました。
> 引き続き、取り組んでみます。
>
>>■No29608に返信(shuさんの記事)
>>
>>shuさま、ありがとうございます。
>>修正してみます。
>>
> >>■No29607に返信(けいすけさんの記事)
> >>
>>>>lstGyousya.SelectedValue(i)
> >>lstGyousya.Items(i)
> >>でどうでしょう?
■No29613に返信(けいすけさんの記事)

> strGyousya="System.Data.DataRowView)"と代入されてしまいました。
DataRowViewが取得できれば
DataRowView.RowでもとになるDataRowが取得できるので
DataRow("項目名")で値が取得できるかと思います。
■No29616に返信(shuさんの記事)

shuさま、ありがとうございます。
上記のコードで、具体的に、どのように修正すればよいのか、
やってみたのですが、
出来ませんでした。

上記の、

blnLoopCheck = False
If lstGyousya.CheckedItems.Count <> 0 Then
For i = 0 To lstGyousya.Items.Count - 1
If blnLoopCheck = False Then
strGyousya = "([業者C] = "
If lstGyousya.GetItemChecked(i) = True Then
strGyousya = "" & lstGyousya.SelectedValue(i).ToString & ""
End If
blnLoopCheck = True
Else
If lstGyousya.GetItemChecked(i) = True Then
strGyousya = "or"
strGyousya = "" & lstGyousya.SelectedValue(i).ToString & ""'※※※ここでエラー発生※※※
End If
End If
Next
strGyousya &= ")"
End If

の部分を、

blnLoopCheck = False
If lstMeka.CheckedItems.Count <> 0 Then
For i = 0 To lstGyousya.SelectedItems.Count - 1
For Each itm As Data.DataRowView In Me.lstGyousya.SelectedItems
If blnLoopCheck = False Then
strGyousya = "( [業者C] = "
strGyousya &= itm.Item(0).ToString
blnLoopCheck = True
Else
strGyousya &= "or"
strGyousya &= itm.Item(0).ToString
End If
Next
Next
strGyousya &= " )"
End If

と書き直してみました。

lstGyousyaでの選択が、A社だけの場合には、
strGyousya="([業者C]=1)"
となり、
うまくいきました。

ですが、
A社とB社のように、
複数選択の場合、
B社の[業者C]のみが残り、
strGyousya="([業者C]=2)"
となり、
A社の商品が取得されませんでした。

引き続き、進めてみます。


> ■No29613に返信(けいすけさんの記事)
>
>>strGyousya="System.Data.DataRowView)"と代入されてしまいました。
> DataRowViewが取得できれば
> DataRowView.RowでもとになるDataRowが取得できるので
> DataRow("項目名")で値が取得できるかと思います。
■No29632に返信(けいすけさんの記事)

調べてみましたところ、
チェックを3つつけても、
lstGyousya.Items.Count = 4
lstGyousya.SelectedItems.Count = 1
であることが分かりました。
lstGyousya.CheckedItems.Count = 3
になることが分かりました。
For〜Next文では、
lstGyousya.CheckedItems.Countを使うことに、
また、
値を取る際には、
SekectedItem(常に最後にチェックされている値が取られる)やSelectedValueではなく、
lstGyousya.CheckedItems.Itemを使用すればよいことが分かりました。
また、
"[業者C]=1 or 2 or 3"は構文不正と出るため、
"[業者C]=1 or [業者C]=2 or [業者C]=3"
になるように修正しました。

次のように書き直しました。

Dim Row As DataRowView
blnLoopCheck = False
If lstMeka.CheckedItems.Count <> 0 Then
For i = 0 To lstMeka.CheckedItems.Count - 1
If blnLoopCheck = False Then
strMeka = "([業者C] = "
Row = lstMeka.CheckedItems.Item(i)
strMeka &= Row("業者C")
blnLoopCheck = True
Else
strMeka &= " or [業者C] = "
Row = lstMeka.CheckedItems.Item(i)
strMeka &= Row("業者C")
End If
Next
strMeka &= ")"

End If

これでうまくいきました。

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


> ■No29616に返信(shuさんの記事)
>
> shuさま、ありがとうございます。
> 上記のコードで、具体的に、どのように修正すればよいのか、
> やってみたのですが、
> 出来ませんでした。
>
> 上記の、
>
> blnLoopCheck = False
> If lstGyousya.CheckedItems.Count <> 0 Then
> For i = 0 To lstGyousya.Items.Count - 1
> If blnLoopCheck = False Then
> strGyousya = "([業者C] = "
> If lstGyousya.GetItemChecked(i) = True Then
> strGyousya = "" & lstGyousya.SelectedValue(i).ToString & ""
> End If
> blnLoopCheck = True
> Else
> If lstGyousya.GetItemChecked(i) = True Then
> strGyousya = "or"
> strGyousya = "" & lstGyousya.SelectedValue(i).ToString & ""'※※※ここでエラー発生※※※
> End If
> End If
> Next
> strGyousya &= ")"
> End If
>
> の部分を、
>
> blnLoopCheck = False
> If lstMeka.CheckedItems.Count <> 0 Then
> For i = 0 To lstGyousya.SelectedItems.Count - 1
> For Each itm As Data.DataRowView In Me.lstGyousya.SelectedItems
> If blnLoopCheck = False Then
> strGyousya = "( [業者C] = "
> strGyousya &= itm.Item(0).ToString
> blnLoopCheck = True
> Else
> strGyousya &= "or"
> strGyousya &= itm.Item(0).ToString
> End If
> Next
> Next
> strGyousya &= " )"
> End If
>
> と書き直してみました。
>
> lstGyousyaでの選択が、A社だけの場合には、
> strGyousya="([業者C]=1)"
> となり、
> うまくいきました。
>
> ですが、
> A社とB社のように、
> 複数選択の場合、
> B社の[業者C]のみが残り、
> strGyousya="([業者C]=2)"
> となり、
> A社の商品が取得されませんでした。
>
> 引き続き、進めてみます。
>
>
>>■No29613に返信(けいすけさんの記事)
>>
> >>strGyousya="System.Data.DataRowView)"と代入されてしまいました。
>>DataRowViewが取得できれば
>>DataRowView.RowでもとになるDataRowが取得できるので
>>DataRow("項目名")で値が取得できるかと思います。
解決済み!
■No29633に返信(けいすけさんの記事)
もりお様、shu様、
ありがとうございました。
■No29634に返信(けいすけさんの記事)

解決しました。

> ■No29633に返信(けいすけさんの記事)
> もりお様、shu様、
> ありがとうございました。
>
解決済み!

DOBON.NET | プログラミング道 | プログラミング掲示板