質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

87.48%

VB.NET DataGridView 一覧表示の方法について

受付中

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 6,561

score 17

.NETで在庫管理システムを作成しています。データベースはAccessを使用しています。在庫一覧画面にて在庫されている商品の情報を、「商品テーブル」という名前のテーブルからSelectで検索して、DataGridViewで一覧表示する部分を現在実装しています。表示項目の名称とデータベースでのデータ型については以下の通りとなります。

項目名 品番 入荷日 ロットNo 最終出荷日 残箱数
データ型 テキスト 日付/時刻 テキスト 日付/時刻 数値

上の表のうち、入荷日と最終出荷日については、DataGridViewで表示する際に、各マスをカレンダー表示になるようにしたいです。

現在のソースは以下の通りとなります。

Form2.vb

''' <summary>
''' 在庫一覧画面
''' </summary>
Public Class Form2
    Public searchFlg As Integer = 0

    'ホストネーム
    Public HostName As String = System.Net.Dns.GetHostName

    'プロジェクトネーム
    Public projectName As String = "在庫管理システム"

    Public productTable As String = "商品テーブル"

    'データグリッドビュー
    Public dgv As DataGridView

    Private dbCon As Class1

    'クエリー
    Private query As String

    'テーブルデータ
    Private tableData As DataTable

    'チェックボックス
    Private column As New DataGridViewCheckBoxColumn

    Private form3 As New Form3

    'ターゲットリスト
    Private list As TargetList

    'チェックボックスの行番号
    Private columnIndex As Integer = 5





    ''' <summary>
    ''' 一覧画面読み込み時の操作
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load

        'DataGridViewにセットするテーブル内容を取得する
        dbCon = New Class1(HostName, projectName, productTable)

        list = New TargetList 'TargetListインスタンス生成

        dgv = DataGridView1

        If searchFlg <> 1 Then

            '列が自動的に作成されないようにする
            dgv.AutoGenerateColumns = False

            tableData = dbCon.setDataSource()



            'DataGridViewに先頭行に値をセットする
            ColumnSet(dgv, tableData)


            ''コネクションを切断する
            dbCon.Dispose()

        Else
            searchFlg = 0

        End If

    End Sub

    ''' <summary>
    ''' DataGridViewの先頭行に項目名をセットする
    ''' </summary>
    ''' <returns></returns>
    Public Function headTxtNameSet() As ArrayList

        'ヘッダーテキストのArrayList
        Dim headTxtArrayList As New ArrayList()

        headTxtArrayList.Add("品番")
        headTxtArrayList.Add("入荷日")
        headTxtArrayList.Add("ロットNo")
        headTxtArrayList.Add("最終出荷日")
        headTxtArrayList.Add("残箱数")

        Return headTxtArrayList

    End Function


    ''' <summary>
    ''' DataGridViewに値と文字の配置をセットする
    ''' </summary>
    ''' <param name="dgv"></param>
    Public Sub ColumnSet(dgv As DataGridView, tableData As DataTable)

        Dim headArrayList As New ArrayList()

        headArrayList = headTxtNameSet()



        Dim headerTxt As String = ""

        Dim tableRow As DataRow

        'DataGridViewの列数を取得する
        Dim cellCount As Integer = headArrayList.Count

        '列のインデックス
        Dim cellIndex As Integer = 0

        'DataTableの行数を取得する
        Dim rowCount As Integer = tableData.Rows.Count

        For i = 0 To cellCount - 1



            Dim col As Object


            If i = 1 Or i = 3 Then

                '入荷日、出荷日の場合
                'CalendarColumn列を作成する
                col = New CalendarColumn()

                '日付は右側表示にする


            Else

                '品番、ロットNo、残箱数のの場合
                'DataGridViewTextBoxColumn列を作成する
                col = New DataGridViewTextBoxColumn




            End If



            '囲み文字を取得する
            headerTxt = headArrayList(i)

            '列を追加
            dgv.Columns().Add(col)

            '行のコレクションを取得
            tableRow = tableData.Rows(0)

            'DataGridViewに値を格納する
            dgv.Rows(0).Cells(i).Value = tableRow(headerTxt)



            'インデックスを初期化
            cellIndex = 0

            'ヘッダーを設定する
            dgv.Columns(i).HeaderText = headerTxt

            'ヘッダーは中央表示
            dgv.Columns(i).HeaderCell.Style.Alignment = DataGridViewContentAlignment.MiddleCenter

            If i = 4 Then

                '残箱数は右側表示
                dgv.Columns(i).DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight

            End If

        Next

        ''CheckBox列を追加する
        dgv.Columns.Add(column)

        'チェックボックスのヘッダー文字位置と名前を設定
        dgv.Columns(cellCount).HeaderCell.Style.Alignment = DataGridViewContentAlignment.MiddleCenter
        dgv.Columns(cellCount).HeaderText = "データ削除"

    End Sub

End Class


Class1.vb

Imports System.Data.OleDb
''' <summary>
''' データベース接続クラス
''' </summary>
Public Class Class1

    Private connectionString As String


    'フィールド
    Private tableName As String
    Private errortable As String
    Private fileName As String = "在庫管理システム.mdb"
    Private dgv As DataGridView = Form2.DataGridView1

    'チェックボックス
    Private column As New DataGridViewCheckBoxColumn

    '行番号
    Private columnIndex As Integer = 4

    '''' <summary>
    '''' コンストラクタ
    '''' </summary>
    Public Sub New(ByVal HostName As String, ByVal projectName As String,
                   ByVal tableName_ As String)

        tableName = tableName_


        If HostName = "Kentaro-PC" Then

            connectionString =
                "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\Users\Kentaro\Documents\Visual Studio 2015\Projects\" & projectName & "\DB\" & fileName

        Else

        End If

    End Sub


    '----------------------------------------------------
    '  テーブルに関すること
    '----------------------------------------------------

    Private dbCnc As OleDbConnection = New OleDbConnection
    Private dbAdp As OleDbDataAdapter
    Private cmd As System.Data.OleDb.OleDbCommand
    Private primaryKeyArray() As DataColumn

    Private tableData As New DataTable

    ''' <summary>
    ''' テーブルレコードを一覧で抽出する
    ''' </summary>
    ''' <returns></returns>
    Public Function setDataSource()

        Dim selectSql As String
        selectSql = "SELECT * FROM " & tableName

        If tableName.Equals("商品テーブル") Then

            selectSql &= " Where 残箱数 > 0 ORDER BY 入荷日,品番"

        ElseIf tableName.Equals("出荷履歴テーブル") Then

            selectSql &= " ORDER BY 出荷日"

        ElseIf tableName.Equals("エラーテーブル")

            selectSql &= " ORDER BY 発生日時"

        End If

        tableData = getTableData(selectSql)

        'フィールド情報
        primaryKeyArray = tableData.PrimaryKey '主キー情報を取得

        Return tableData

    End Function


    ''' <summary>
    ''' テーブルデータを取得する
    ''' </summary>
    ''' <param name="query">SELECT文</param>
    ''' <returns>tableData</returns>
    Public Function DBconnect(ByVal query As String)

        tableData = New DataTable()

        dbAdp = New OleDbDataAdapter(query, connectionString)

        dbAdp.Fill(tableData)

        Return tableData

    End Function


    ''' <summary>
    ''' 
    ''' </summary>
    ''' <param name="sqlList"></param>
    ''' <returns></returns>
    Public Function runSQL(sqlList As List(Of String)) As Boolean
        'テーブル情報の変更
        Dim checkFlg As Boolean

        If dbCnc.ConnectionString Is Nothing Or dbCnc.ConnectionString.Length = 0 Then

            '接続文字列の設定
            dbCnc.ConnectionString = connectionString


        End If


        dbCnc.Open() 'コネクションオープン

        Dim dbCmd As OleDbCommand = dbCnc.CreateCommand
        Dim dbTrz As OleDbTransaction = dbCnc.BeginTransaction
        dbCmd.Connection = dbCnc 'コマンド接続
        dbCmd.Transaction = dbTrz   'トランザクション開始

        Try
            For Each strSQL As String In sqlList
                dbCmd.CommandText = strSQL 'リスト内のSQL文をセット
                dbCmd.ExecuteNonQuery() '実行
            Next
            dbTrz.Commit() 'コミット(確定)
            checkFlg = True
        Catch ex As Exception
            MessageBox.Show(dbCmd.CommandText & vbCrLf & vbCrLf & ex.Message, "エラー", MessageBoxButtons.OK, MessageBoxIcon.Error) 'エラー内容表示

            'エラーが発生した日付時刻を取得
            Dim dtNow As DateTime = DateTime.Now



            dbTrz.Rollback() 'ロールバック
        Finally
            dbCmd.Dispose() 'コマンドを破棄
            dbCnc.Close()   'コネクションを閉じる
        End Try

        Return checkFlg
    End Function





    ''' <summary>
    ''' 主キー情報を取得する
    ''' </summary>
    ''' <param name="targetColumn"></param>
    ''' <returns></returns>
    Public Function isPrimaryKey(ByVal targetColumn As Integer) As Boolean
        '主キー列か判定
        Dim checkFlg As Boolean
        For i As Integer = 0 To primaryKeyArray.Length - 1
            If primaryKeyArray(i).Ordinal = targetColumn Then checkFlg = True
        Next
        Return checkFlg
    End Function

    Public Function isAutoIncrement(ByVal targetColumn As Integer) As Boolean
        'オートインクリメント列か判定
        Dim checkFlg As Boolean

        If tableData.Columns(targetColumn).AutoIncrement = True Then

            checkFlg = True

        End If

        Return checkFlg
    End Function




End Class

DBのサンプルデータは写真の通りです。
イメージ説明

現在の表示結果は以下の写真の通りです。
イメージ説明
どうすれば残箱数0より多いレコードを全件一覧表示できるでしょうか?分かる方よろしくお願いします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

0

dgv.Rows(0).Cells(i).Value = tableRow(headerTxt)

これが原因でしょう。
Rows(0) は一行目を表しますので、検索されたデータが全て一行目を上書きしていることになります。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/02/16 15:51

    ご回答頂きありがとうございます。やはりそこが原因なのですね。そこでご指摘頂いた箇所を以下のように修正したのですが、やはり以下のエラーとなってしましました。何処が原因か具体的にどうすればよいでしょうか?恐れ入りますが、併せてご教示頂けると幸いです。よろしくお願いします。

    修正後
    '列を追加
    dgv.Columns().Add(col)

    For k = 0 To rowCount - 1

    '行のコレクションを取得
    tableRow = tableData.Rows(0)

    'DataGridViewに値を格納する
    dgv.Rows(k).Cells(i).Value = tableRow(headerTxt)

    Next

    エラー内容:System.ArgumentOutOfRangeException' (mscorlib.dll の中)

    キャンセル

  • 2018/02/16 16:16

    まだ一行しか無いので他の行に書き込むことはできません。
    Rows.Add() して行を増やす必要があります。

    それはそれとして、通常は DataGridView の行に直接データを書き込むようなことはしません。
    BindingSource を作ってデータバインディングを行います。

    var bindingSource = new BindingSource();
    bindingSource.DataSource = tableData;
    dgv.DataSource = bindingSource;

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 87.48%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る