none
DateTimePickerを2つ使いデータベースから、選んだ範囲のIDを呼び出して、そこから各IDにある、データを使いたい RRS feed

  • 質問

  •  

    DateTimePickerを2つ使いデータベースから、選んだ範囲のIDを呼び出して、そこから各IDにある個数をTextBoxに表示したいです。 

    ListBoxに選んだ全てのIDを表示する事が出来たのですが、それを各TextBoxに表示する方法がわかりません。

    使ってるのは、VB2008Express EditionでAccess2007です

    データベースの内容がこのような形として

    テーブル名はmainです
    ID   日付     個数
    1  2008/11/01   300
    2  2008/11/02   400
    3  2008/11/03   500
    4  2008/11/04   600
    5    2008/11/05      700

    DateTimePicker1に2008/11/02、DateTimePicker2に2008/11/04を入れまして、Button1を押すとListBoxに表示する事はできました。

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
         
    Dim Cn As New OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\a.mdb")
    Dim z As OleDbCommand = Cn.CreateCommand
    Dim time As String
    Dim time1 As String
    Dim Table As New DataTable
    Dim Adapter As New OleDbDataAdapter(z)

    time1 = DateTimePicker2.Value.Date.ToShortDateString
    time = DateTimePicker1.Value.Date.ToShortDateString

    z.CommandText = "SELECT id FROM main where  (((日付) Between #" & time & "# And #" & time1 & "#))"

    Cn.Open()

    Adapter.Fill(Table)
    ListBox1.DataSource = Table
    ListBox1.DisplayMember = "id"
          
    Cn.Close()
    End Sub

    これでListBoxに2,3,4と表示されて 入力した範囲の日付IDが選ばれてるってのは確認できたのですが、選ばれたIDの個数をTextBoxに表示する方法がわかりません。

    もう1つ聞きたいのですが 上の方法で始まりのIDと終わりのIDが選ばれて、それを 

    for s= 始まりのID  to  終わりのID  
        Next s
    としたい場合、どのようにプログラムを書いたら良いのかもわかりません。

    VB始めて1ヶ月くらいでして このような感じでしか書けないのですが
    なにとぞご教授お願いします。

    2008年11月8日 2:38

回答

  • 部分的な回答をしても分からないと思いますので、今までの質問の回答をまとめて、
    以下にサンプルコードをアップしておきます。

     

    これに別のスレッド「データベースから読込んだ数字をInteger型にしたい」の質問
    の答えも含まれていると思います。

     

    最終的に何をしたいのかが良く分からないので的外れな点があるかもしれませんが、
    参考になれば幸いです。

     

    Code Snippet

    Imports System.Data
    Imports System.Data.OleDb

    Public Class Form1
        ' Table を ListBox2_SelectedIndexChanged メソッドで使うためここに定義
        Private Table As New DataTable

        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

            Table.Clear()   ' ListBox1.Items.Clear() は不可
            ListBox2.Items.Clear()

            Dim connection As New OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=|DataDirectory|\Access.mdb")

            ' SELECT クエリに "日付" と "ORDER BY ID" を追加
            Dim query As String = "SELECT ID, 個数 FROM Table2 WHERE (日付 BETWEEN ? AND ?) ORDER BY ID"
            Dim command As OleDbCommand = New OleDbCommand(query, connection)
            command.Parameters.AddWithValue("日付", DateTimePicker1.Value.Date.ToShortDateString())
            command.Parameters.AddWithValue("日付", DateTimePicker2.Value.Date.ToShortDateString())
            Dim Adapter As New OleDbDataAdapter(command)

            ' DataAdapter の Fill メソッドを使う場合は Open, Close は不用
            Adapter.Fill(Table)

            ' ここはオリジナルのコードと同じ
            ListBox1.DataSource = Table
            ListBox1.DisplayMember = "ID"

            ' 「上の方法で始まりのIDと終わりのIDが選ばれて、それを For s = 始まりのID To 終わりのID
            ' Next s としたい場合」 (ただし、ID 順番に並んでいて、かつ、飛んでいないのが条件)
            Dim obj As DataRowView = CType(ListBox1.Items(0), DataRowView)
            Dim first As Integer = CType(obj("ID"), Integer)
            Dim last As Integer = first + ListBox1.Items.Count - 1
            Dim itemList1 As String = String.Empty
            For i As Integer = first To last
                ' ここにコードを書く。例えば、
                itemList1 = itemList1 + i.ToString() + ", "
            Next
            TextBox1.Text = itemList1

            ' 「始まりのID」→「終わりのID」という順番にこだわないのであれば、
            Dim itemList2 As String = String.Empty
            For Each item As DataRowView In ListBox1.Items
                itemList2 = itemList2 + item("ID").ToString() + ", "
            Next
            TextBox2.Text = itemList2

            ' "ID" と "個数" を ListBox に併記する場合
            For Each row As DataRow In Table.Rows
                ListBox2.Items.Add(String.Format("ID: {0}, 個数: {1}", row("ID"), row("個数")))
            Next
        End Sub

        ' ListBox1 に表示されている ID を選択すると TextBox3 に選択された ID の "個数" を表示
        Private Sub ListBox1_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ListBox1.SelectedIndexChanged
            Dim selectedItem As DataRowView = CType(ListBox1.SelectedItem, DataRowView)
            TextBox3.Text = CType(selectedItem("個数"), String)
        End Sub

        ' ListBox2 に表示されている項目を選択すると TextBox2 に選択された項目の "個数" を表示
        Private Sub ListBox2_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ListBox2.SelectedIndexChanged
            Dim selectedItem As String = CType(ListBox2.SelectedItem, String)
            Dim items As String() = selectedItem.Split(New [Char]() {","c, " "c})
            Dim selectedId As Integer = Int32.Parse(items(1))
            For Each row As DataRow In Table.Rows
                If row("ID") = selectedId Then
                    TextBox4.Text = row("個数")
                    Exit For
                End If
            Next
        End Sub
    End Class

     

     

     

    2008年11月9日 6:01

すべての返信

  • 検証してないので、確信があるわけではありませんが・・・

     

    > 選ばれたIDの個数をTextBoxに表示する方法がわかりません。

     

    System.Windows.Forms.TextBox クラスが TextBox1 として Form に配置されて
    いるとして、

     

    TextBox1.Text = Convert.ToString(ListBox1.Items.Count)

     

    でどうですか?

     

    > 上の方法で始まりのIDと終わりのIDが選ばれて、それを 
    > for s= 始まりのID  to  終わりのID 
    >    Next s
    > としたい場合、どのようにプログラムを書いたら良いのかもわかりません。

     

    SELECT クエリの結果が id 順に並んでない可能性がありますので、id 順に並ぶ
    ように、SELECT クエリに ORDER BY id という句を追加してみてください。

     

    そうすれば、ListBox1.Items(即ち ListBox.ObjectCollection)の一番最初が「始ま

    りのID」、一番最後が「終わりのID」が格納された Object になるはずです。

    2008年11月8日 4:01
  • 追加です。

     

    「始まりのID」→「終わりのID」という順番にこだわないのであれば、
    以下のようにした方が良いと思います。

     

    For Each obj As Object In ListBox1.Items
        ' ここに obj を処置するコードを書く
    Next

    2008年11月8日 4:25
  • SurferOnWww さん 早速の回答 ありがとうございました。

    教えて貰いました やり方で IDを 何個選んだかをTextBoxに 表示する事ができました

    感謝です

     

    まことに 申し訳ないのですが もう1つお願いします

     

    たとえば、範囲で選んだIDが2~4としまして IDが3の時の個数が500だとすると

    この500をTextBoxに表示したい場合、どの様にしたら良いのでしょうか

     

    なにとぞご教授お願いします。

    2008年11月8日 6:25
  • SELECT クエリに以下のように「個数」を追加すると、

     

    SELECT id FROM ...  → SELECT id, 個数 FROM ...

     

    Fill したときに自動的に DataTable に「個数」の列が追加されるので、選んだ id 値
    と一致する DataTable の中の「id」のある行を調べて、その行にある「個数」を取得す
    るようにしてはどうですか? 例えば下記のように・・・

     

    Code Snippet

    For Each row As DataRow In Table.Rows
        If row("id") = selectedId Then
            selectedQty = row("個数")
            Exit For
        End If
    Next

     

     

    型の指定には気をつけてください。

    2008年11月8日 9:00
  • 部分的な回答をしても分からないと思いますので、今までの質問の回答をまとめて、
    以下にサンプルコードをアップしておきます。

     

    これに別のスレッド「データベースから読込んだ数字をInteger型にしたい」の質問
    の答えも含まれていると思います。

     

    最終的に何をしたいのかが良く分からないので的外れな点があるかもしれませんが、
    参考になれば幸いです。

     

    Code Snippet

    Imports System.Data
    Imports System.Data.OleDb

    Public Class Form1
        ' Table を ListBox2_SelectedIndexChanged メソッドで使うためここに定義
        Private Table As New DataTable

        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

            Table.Clear()   ' ListBox1.Items.Clear() は不可
            ListBox2.Items.Clear()

            Dim connection As New OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=|DataDirectory|\Access.mdb")

            ' SELECT クエリに "日付" と "ORDER BY ID" を追加
            Dim query As String = "SELECT ID, 個数 FROM Table2 WHERE (日付 BETWEEN ? AND ?) ORDER BY ID"
            Dim command As OleDbCommand = New OleDbCommand(query, connection)
            command.Parameters.AddWithValue("日付", DateTimePicker1.Value.Date.ToShortDateString())
            command.Parameters.AddWithValue("日付", DateTimePicker2.Value.Date.ToShortDateString())
            Dim Adapter As New OleDbDataAdapter(command)

            ' DataAdapter の Fill メソッドを使う場合は Open, Close は不用
            Adapter.Fill(Table)

            ' ここはオリジナルのコードと同じ
            ListBox1.DataSource = Table
            ListBox1.DisplayMember = "ID"

            ' 「上の方法で始まりのIDと終わりのIDが選ばれて、それを For s = 始まりのID To 終わりのID
            ' Next s としたい場合」 (ただし、ID 順番に並んでいて、かつ、飛んでいないのが条件)
            Dim obj As DataRowView = CType(ListBox1.Items(0), DataRowView)
            Dim first As Integer = CType(obj("ID"), Integer)
            Dim last As Integer = first + ListBox1.Items.Count - 1
            Dim itemList1 As String = String.Empty
            For i As Integer = first To last
                ' ここにコードを書く。例えば、
                itemList1 = itemList1 + i.ToString() + ", "
            Next
            TextBox1.Text = itemList1

            ' 「始まりのID」→「終わりのID」という順番にこだわないのであれば、
            Dim itemList2 As String = String.Empty
            For Each item As DataRowView In ListBox1.Items
                itemList2 = itemList2 + item("ID").ToString() + ", "
            Next
            TextBox2.Text = itemList2

            ' "ID" と "個数" を ListBox に併記する場合
            For Each row As DataRow In Table.Rows
                ListBox2.Items.Add(String.Format("ID: {0}, 個数: {1}", row("ID"), row("個数")))
            Next
        End Sub

        ' ListBox1 に表示されている ID を選択すると TextBox3 に選択された ID の "個数" を表示
        Private Sub ListBox1_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ListBox1.SelectedIndexChanged
            Dim selectedItem As DataRowView = CType(ListBox1.SelectedItem, DataRowView)
            TextBox3.Text = CType(selectedItem("個数"), String)
        End Sub

        ' ListBox2 に表示されている項目を選択すると TextBox2 に選択された項目の "個数" を表示
        Private Sub ListBox2_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ListBox2.SelectedIndexChanged
            Dim selectedItem As String = CType(ListBox2.SelectedItem, String)
            Dim items As String() = selectedItem.Split(New [Char]() {","c, " "c})
            Dim selectedId As Integer = Int32.Parse(items(1))
            For Each row As DataRow In Table.Rows
                If row("ID") = selectedId Then
                    TextBox4.Text = row("個数")
                    Exit For
                End If
            Next
        End Sub
    End Class

     

     

     

    2008年11月9日 6:01
  • SurferOnWww さん 丁寧な説明 まことに、ありがとうございました。

     

    教えてもらいました プログラムを基に、がんばって勉強して行きたいと思います。

     

    また何かありましたら ご質問する事があると思いますが、 なにとぞ宜しくお願いします。

     

    ほんとうに助かりました

    2008年11月10日 0:16