簡體   English   中英

分離后按行值對數據表條目進行分組

[英]Group datatable entries by row value after having separated

發生了什么:我有一個由姓名,ID,評論組成的表格。 除非用戶提交多於1個條目,否則每個ID都是唯一的。 此時,用戶可能有3行,其中ID相同,以顯示這些條目全部由1個用戶輸入,並且它們屬於一起。

下面我將發布我最初做的事情,將它們分成單獨的datagridview,每個按鈕下面的按鈕最終將用於處理它上面的datagrid條目。

因此,這導致了我試圖弄清楚的兩件事,並且通過反復試驗和Google研究沒有太多運氣。

1.)如何將數據表中具有相同ID的任何條目放入相同的數據網格視圖中,而不是為每個條目創建單獨的數據網格。

2.)假設上面可以做到,如果可能的話,我怎樣才能使每個下面生成的按鈕只對應上面的數據網格? 雖然以編程方式創建的每個數據網格和按鈕都可以分配一個唯一的ID,允許每個ID對應另一個嗎?

    Dim dst As New DataSet
    For i As Integer = 0 To DT.Rows.Count - 1
        Dim intLastRow As Integer = i
        If intLastRow > DT.Rows.Count - 1 Then intLastRow = DT.Rows.Count - 1
        Dim dtbNew As DataTable = DT.Clone
        dtbNew.TableName = DT.TableName
        For j As Integer = i To intLastRow
            dtbNew.ImportRow(DT.Rows(j))
        Next j
        dst.Tables.Add(dtbNew)
    Next i

    For Each table As DataTable In dst.Tables
        Dim DGV As New DataGridView
        Dim BTN As New Button
        BTN.Text = "Show Details"
        BTN.Width = 120
        DGV.DataSource = table
        DGV.Width = 800
        DGV.Height = 80
        FlowLayoutPanel1.Controls.Add(DGV)
        FlowLayoutPanel1.Controls.Add(BTN)
    Next
    FlowLayoutPanel1.AutoScrollPosition = New Point(FlowLayoutPanel1.Top)

錯誤

Dim DT As New DataTable
    DT.Load(SQLMP)

    Dim groups As IEnumerable(Of IGrouping(Of Integer, DataRow)) = DT.Select.GroupBy(Function(row) row.Field(Of Integer)("ORDER_ID"))

System.Data.DataSetExtensions.dll中發生未處理的“System.InvalidCastException”類型異常

附加信息:指定的演員表無效

你可以用LinQ和lambda函數做你想做的事情假設你有一個DataTable,所有這些條目都是混合的。

執行此操作,您將獲得按ID分組的行:

Dim groups = DT.Select.GroupBy(Function(row) row("ID"))

從現在開始,您可以從中提取部分數據表

Dim partialTables = groups.Select(
    Function(group)
        Dim partialTable = group.CopyToDataTable
        partialTable.TableName = group.Key
        Return partialTable
    End Function).ToList

然后,您可以查詢表的列表以獲取特定ID,檢索它並將其用作數據源:

YourDataGridView.DataSource = partialtables.FirstOrDefault(
    Function(table) table.TableName = "123")

我希望它有所幫助!

編輯下面你可以看到我的建議的完整實現。 我測試了它,似乎工作正常

Private DT As DataTable, partialTables As List(Of DataTable)
Private WithEvents CB As ComboBox, DGV As DataGridView
Private Sub q37459856()
    DT = New DataTable
    DT.Columns.Add("Name", GetType(String))
    DT.Columns.Add("ID", GetType(Integer))
    DT.Columns.Add("Commens", GetType(String))
    DT.Rows.Add("aaaaaa", 1, "aaaaaa")
    DT.Rows.Add("bbbbbb", 2, "bbbbbb")
    DT.Rows.Add("cccccc", 1, "cccccc")
    DT.Rows.Add("dddddd", 2, "dddddd")
    DT.Rows.Add("eeeeee", 3, "eeeeee")
    DT.Rows.Add("ffffff", 1, "ffffff")
    DT.Rows.Add("gggggg", 2, "gggggg")
    DT.Rows.Add("hhhhhh", 3, "hhhhhh")
    DT.Rows.Add("iiiiii", 4, "iiiiii")

    Dim groups As IEnumerable(Of IGrouping(Of Integer, DataRow)) = DT.Select.GroupBy(Function(row) row.Field(Of Integer)("ID"))

    partialTables = groups.Select(
        Function(group)
            Dim partialTable = group.CopyToDataTable
            'IGrouping(Of Integer, DataRow) implements IEnumerable(of DataRow)
            'therefore, it implements Function .CopyToDataTable() 
            partialTable.TableName = group.Key.ToString("000")
            Return partialTable
        End Function).ToList

    Dim IDs = New List(Of String)({"all"}.Concat(partialTables.Select(Function(t) t.TableName)))

    Dim F As New Form
    CB = New ComboBox With {.Dock = DockStyle.Top, .DataSource = IDs}
    F.Controls.Add(CB)
    DGV = New DataGridView With {
        .Left = CB.Left,
        .Top = CB.Top + CB.Height + 3,
        .Width = CB.Width,
        .Height = F.ClientSize.Height - CB.Top - CB.Height - 6,
        .Anchor = AnchorStyles.Left + AnchorStyles.Top + AnchorStyles.Right + AnchorStyles.Bottom,
        .AllowUserToAddRows = False}
    F.Controls.Add(DGV)
    F.Show()
End Sub
Sub CB_SelectedValueChanged(sender As Object, e As EventArgs) Handles CB.SelectedValueChanged
    If CB.SelectedValue = "all" Then
        DGV.DataSource = DT
    Else
        DGV.DataSource = partialTables.FirstOrDefault(Function(t) t.TableName = CB.SelectedValue)
    End If
End Sub

編輯#2為了提供問題的工作解決方案,下面是一個具有類似邏輯的版本,但依賴於For ... Next迭代而不是Linq

Private DT As DataTable, partialTables As List(Of DataTable)
Private WithEvents CB As ComboBox, DGV As DataGridView
Private Sub q37459856_withoutLinq()
    DT = New DataTable
    DT.Columns.Add("Name", GetType(String))
    DT.Columns.Add("ORDER_ID", GetType(Integer))
    DT.Columns.Add("Comments", GetType(String))
    DT.Rows.Add("aaaaaa", 1, "aaaaaa")
    DT.Rows.Add("bbbbbb", 2, "bbbbbb")
    DT.Rows.Add("cccccc", 1, "cccccc")
    DT.Rows.Add("dddddd", 2, "dddddd")
    DT.Rows.Add("eeeeee", 3, "eeeeee")
    DT.Rows.Add("ffffff", 1, "ffffff")
    DT.Rows.Add("gggggg", 2, "gggggg")
    DT.Rows.Add("hhhhhh", 3, "hhhhhh")
    DT.Rows.Add("iiiiii", 4, "iiiiii")

    Dim allORDER_ID As New List(Of Integer)

    For Each dr In DT.Select
        If Not allORDER_ID.Contains(dr("ORDER_ID")) Then
            allORDER_ID.Add(dr("ORDER_ID"))
        End If
    Next

    Dim partialTable As DataTable
    partialTables = New List(Of DataTable)
    For Each ORDER_ID In allORDER_ID
        partialTable = DT.Clone
        partialTable.TableName = ORDER_ID.ToString("000")
        For Each dr In DT.Select("ORDER_ID=" & ORDER_ID)
            partialTable.ImportRow(dr)
        Next
        partialTables.Add(partialTable)
    Next

    Dim IDs = New List(Of String)({"all"})

    For Each partialTable In partialTables
        IDs.Add(partialTable.TableName)
    Next

    Dim F As New Form
    CB = New ComboBox With {.Dock = DockStyle.Top, .DataSource = IDs}
    F.Controls.Add(CB)
    DGV = New DataGridView With {
        .Left = CB.Left,
        .Top = CB.Top + CB.Height + 3,
        .Width = CB.Width,
        .Height = F.ClientSize.Height - CB.Top - CB.Height - 6,
        .Anchor = AnchorStyles.Left + AnchorStyles.Top + AnchorStyles.Right + AnchorStyles.Bottom,
        .AllowUserToAddRows = False}
    F.Controls.Add(DGV)
    F.Show()
End Sub
Sub CB_SelectedValueChanged(sender As Object, e As EventArgs) Handles CB.SelectedValueChanged
    If CB.SelectedValue = "all" Then
        DGV.DataSource = DT
    Else
        DGV.DataSource = partialTables.FirstOrDefault(Function(t) t.TableName = CB.SelectedValue)
    End If
End Sub

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM