[英]Reference another cell in the same row having calculated the minimum value in a datatable column
[英]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.