分類コード(フィールド名:CD)が文字列で「01」から「10」まであり、この中でどのコードが格納されているかはその時々で違います。ただ1〜3種類は格納されています。そこでどのコードが格納されているかわからないのでFor文を使用し、すべてのコードをあるかないか判断。あった場合をDataGrid1に表示、なかった場合は飛ばし、さらに次にあった場合はDataGrid2へ表示…としていきたいのですがどのようなコーディングがいいのでしょうか?
すいません。説明がわかりづらくて(環境:VB.NET)
当然↓ではダメです。
For i = 1 To 10
CD = Format(i, "00")
'SQLを発行しデータ抽出
sql = "select * from HEAD where CD="""
sql = sql & CD & """"
oleDa = New OleDb.OleDbDataAdapter(sql, oleCn)
oleDa.Fill(dtSet, "HEAD")
dtTbl = dtSet.Tables("HEAD")
dtView1 = New DataView(dtSet.Tables("HEAD"), "CD=" & CD, "", DataViewRowState.CurrentRows.CurrentRows)
LabelA.Text = dtView1.Count
DataGrid1.DataSource = dtView1
dtView2 = New DataView(dtSet.Tables("HEAD"), "CD=" & CD, "", DataViewRowState.CurrentRows.CurrentRows)
LabelB.Text = dtView2.Count()
DataGrid2.DataSource = dtView2
dtView3 = New DataView(dtSet.Tables("HEAD"), "CD=" & CD, "", DataViewRowState.CurrentRows.CurrentRows)
LabelC.Text = dtView3.Count()
DataGrid3.DataSource = dtView3
oleCn.Close()
MsgBox("読込が終了しました。")
Next
DataSet の中には複数の DataTable を格納できるし、
1つの DataGrid で複数の DataTable を表示できますよ?。
(最初にツリー状にテーブル名の一覧が出て、そこからテーブルを
選択して表示する形となります)
まぁ…それはいいとして…上のコードをなるべく修正せずに
実現するなら CD で表示対象を Select 文の処理に分けて
やればいいんじゃないですか?変数とか共通化できるけど
…ま、修正が少ない方向で回答しておきます。
[VB.NET]
Select Case CD
Case 1
dtView1 = New DataView(dtSet.Tables("HEAD"), "CD=" & CD, "", DataViewRowState.CurrentRows.CurrentRows)
LabelA.Text = dtView1.Count
DataGrid1.DataSource = dtView1
Case 2
dtView2 = New DataView(dtSet.Tables("HEAD"), "CD=" & CD, "", DataViewRowState.CurrentRows.CurrentRows)
LabelB.Text = dtView2.Count()
DataGrid2.DataSource = dtView2
Case 3
dtView3 = New DataView(dtSet.Tables("HEAD"), "CD=" & CD, "", DataViewRowState.CurrentRows.CurrentRows)
LabelC.Text = dtView3.Count()
DataGrid3.DataSource = dtView3
End Select
まるるうさん、回答ありがとうございます。そこでもうちょっと聞かせてください。このCDですが問題がありまして、「01」で始まるとはかぎらず例えばデータベースには「02」、「04」、「10」と格納されている時や次に読込時にはテーブルクリアし別ファイルを見に行くため「01」、「03」、「08」と格納されていたりします。ちょっとなんでこんな風に格納されるかは長くなりますので割愛させてください。
どんなCDが格納されていても別CDの場合には別DataGridに表示したいというわけなのです。
なにかよい方法はありますでしょうか?
よろしくお願いします。
>「01」で始まるとはかぎらず …
それは関係ないデショ?(._゜)?
> sql = "select * from HEAD where CD="""
> sql = sql & CD & """"
の時点で検索対象としている CD を持ってるレコードのみ
検索してるんですから、順番がなぜ問題になるか理解できません。
対象となる CD を持つレコードがデータベース上に存在しない
場合は、データテーブルを取得できない場合はあるかもしれません。
その場合は Fill の時点で DataTable が作成されないでしょうから、
その辺で処理を条件分けすればいいだけですし…。
上のコードを見る限り、CD の順番は関係ないはずです。
質問の問題点が見つかりません。実際に実行してみて都合の悪い
部分をできるだけ正確に質問して下さい。
わかりづらく申し訳ありません。そこで実現したいことを記述いたします。
アドバイスいただけますでしょうか。
初回読込をした場合、DBにはCD「02」、「04」、「10」が格納されて
います。実際にはCDになにが格納されているかわかりませんので
select文で狙い撃ちはできません。
検索対象である「02」をDataGrid1へ表示、「04」をDataGrid2へ表示、
「10」をDataGrid3へ表示。
次回読込をした場合、DBにはCD「01」、「03」、「08」が格納されて
います。こちらも実際にはCDになにが格納されているかわかりません。
検索対象である「01」をDataGrid1へ表示、「03」をDataGrid2へ表示、
「08」をDataGrid3へ表示。
っという具合に検索対象で見つかったCDのレコードをDataGrid1へ、次にDataGrid1に表示したCDとは別のCDが検索対象で見つかった場合は
DataGrid2へ、DataGrid2、DataGrid3とは別のCDがさらに見つかった
場合はDataGrid3へ表示したいというわけです。
ちなみにCDは最大でも3種類しかDBには格納されていません。
質問の意図はわかっていただけましたでしょうか?
申し訳ございませんがわからない部分がありましたらまたレスをください。
よろしくお願いします。
ああ、DataGrid って3個しか無いんですね?(^^;)
>初回読込をした場合、DBにはCD「02」、「04」、「10」が格納されて
>います。実際にはCDになにが格納されているかわかりませんので
>select文で狙い撃ちはできません。
>検索対象である「02」をDataGrid1へ表示、「04」をDataGrid2へ表示、
>「10」をDataGrid3へ表示。
>次回読込をした場合、DBにはCD「01」、「03」、「08」が格納されて
>います。こちらも実際にはCDになにが格納されているかわかりません。
>検索対象である「01」をDataGrid1へ表示、「03」をDataGrid2へ表示、
>「08」をDataGrid3へ表示。
データベースの運用上、文句を言いたい部分はありますがw
とりあえず色々と変更しちゃったのでソース載せます。動作確認は
SQLサーバーでやってますので、動かない部分があれば修正して下さい。
確認用に DataGrid4 を貼り付けておいて下さい。必要無くなったら
コードでは
Me.DataGrid4.DataSource = wDS
だけ削除すれば動くと思います。
[VB.NET]
' 複数テーブル検索
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim wDS As New DataSet()
Dim wDT As DataTable
Dim i As Integer
Dim wCnStr As String = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=ファイル.mdb"
Dim wSqlStr As String = "SELECT * FROM HEAD WHERE CD="""
Dim wCD As String
Me.DataGrid4.DataSource = wDS
For i = 1 To 10
wCD = Format(i, "00")
Try
wDT = (Me.GetDataTableFromDataServer(wCnStr, wSqlStr & wCD & """", 15))
Catch ex As Exception
MsgBox("データベース検索処理に失敗しました。")
Debug.WriteLine(ex.Message)
Exit Sub
End Try
If Not (wDT Is Nothing) Then
With wDT
If .Rows.Count = 0 Then
' 対象レコード無し
Else
.TableName = "CD" & wCD
wDS.Tables.Add(.Copy) ' 検索時に DataSet に属してるため、データのみコピーしないとエラー
End If
End With
End If
' MSDN サンプル
'Dim tablesCol As DataTableCollection
'' Get the DataTableCollection of a DataGrid control's DataSet.
'tablesCol = CType(DataGrid1.DataSource, DataSet).Tables
'' Create a new DataTable.
'Dim myTable As DataTable = New DataTable()
'' Code to add columns and rows not shown here.
'' Add the table to the DataTableCollection.
'tablesCol.Add(wDataTable.Copy)
Next
With wDS.Tables 'CType(Me.DataGrid4.DataSource, DataSet).Tables
For i = 1 To .Count
Select Case i
Case 1
Me.LabelA.Text = .Item(i - 1).Rows.Count
Me.DataGrid1.DataSource = .Item(i - 1)
Case 2
Me.LabelB.Text = .Item(i - 1).Rows.Count
Me.DataGrid2.DataSource = .Item(i - 1)
Case 3
Me.LabelC.Text = .Item(i - 1).Rows.Count
Me.DataGrid3.DataSource = .Item(i - 1)
Case Else
MsgBox("4件以上検索されてますよ?")
Exit Sub
End Select
Next
End With
End Sub
Private Function GetDataTableFromDataServer( _
ByVal CnStr As String, _
ByVal SQLx As String, _
ByVal TimeoutVal As Integer _
) _
As DataTable
Dim DA As IDbDataAdapter
Dim Cn As IDbConnection
Dim Cmd As IDbCommand
Dim Prm As IDataParameter
Dim DS As New DataSet()
Dim DT As New DataTable()
Dim i As Integer
'Select Case ServerKind
' Case ServerKindInfo.SQLServer
'Cn = New SqlClient.SqlConnection()
'Cmd = New SqlClient.SqlCommand()
'DA = New SqlClient.SqlDataAdapter()
' Case ServerKindInfo.Oracle
' Cn = New OracleClient.OracleConnection()
' Cmd = New OracleClient.OracleCommand()
' DA = New OracleClient.OracleDataAdapter()
'End Select
Cn = New OleDb.OleDbConnection()
Cmd = New OleDb.OleDbCommand()
DA = New OleDb.OleDbDataAdapter()
Cn.ConnectionString = CnStr
With Cmd
.CommandText = SQLx
Debug.WriteLine(SQLx)
.Connection = Cn
.CommandTimeout = TimeoutVal
End With
With DA
.SelectCommand = Cmd
.Fill(DS)
End With
Cn = Nothing
Cmd = Nothing
DA = Nothing
If DS.Tables.Count = 0 Then
Return Nothing
Else
Return DS.Tables(0)
End If
End Function
上の方法はデータベースの中に CD が1種でも4種でも
対応できると思います。ただし、データベース検索回数は
つねに10回、すべての CD を検索してます。
CD が3種しかないなら、先に CD のみ全て検索して
検索に引っかかった CD でデータベース検索を行えば、
データベース検索回数は全部で4回で済みます。
また、どうせなら CD の制限なし(SQL文のWHERE句なし)で
全てを検索してしまい、ローカルでデータを振り分けても
いいですね。こうなるとデータベース検索回数は1回です。
そんなに難しい処理ではないので考えてみて下さい。
まるるうさん、ありがとうございます。初心者なもので勉強になります。
上記コードを参照し、精進します。
まずは把握からになりますが…
本当にありがとうございました。