基于另一列的列总和将显示在另一列上
sum of column based on another column will show on another
你能帮我处理我的 DataGridView 吗?我需要显示基于另一列的列总和。
例如,我有部件号 1,2,3。由于给定的序列号,PN 的数量始终为 1。
PN 1 有 10 个(10 行)。我需要根据该 PN 对其求和并将总和值放在末尾的单元格中。请看下面的示例:
它是 excel 我知道,但请容忍我假装它是 DataGridView。
总金额基于同一 PN 的成本总和。
你需要按照我评论中的link,在DataGridView_Paint事件中做一些操作。我已经在下面完成了。
我做了一个 class 来保存你的数据,叫做模型。我还使用 DataBinding 将该数据放入 DataGridView。您保存和应用数据的方法可能不同,但这很有效。
Public Class Form1
Private data As List(Of Model)
Private dataGroups As IEnumerable(Of (PN As Integer, TotalSum As Double, Count As Integer))
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
data = New List(Of Model) From {
New Model(1, 1, 11.5),
New Model(1, 12, 2),
New Model(1, 13, 10.4),
New Model(1, 14, 12.3),
New Model(1, 15, 10),
New Model(1, 16, 10),
New Model(2, 17, 5),
New Model(2, 18, 1),
New Model(2, 19, 7),
New Model(2, 20, 2),
New Model(2, 21, 4),
New Model(3, 22, 4),
New Model(3, 23, 6),
New Model(3, 24, 3),
New Model(3, 25, 7)}
DataGridView1.DataSource = data
dataGroups = data.GroupBy(Function(d) d.PN).Select(Function(g) (g.Key, g.Sum(Function(g1) g1.Cost), g.Count()))
Dim textBoxColumn = New DataGridViewTextBoxColumn() With {.HeaderText = "Total Sum"}
DataGridView1.Columns.Add(textBoxColumn)
End Sub
Private Sub DataGridView1_Paint(sender As Object, e As PaintEventArgs) Handles DataGridView1.Paint
If DataGridView1.DataSource IsNot Nothing Then
Dim columnIndex = DataGridView1.Columns.Count - 1
Dim counter As Integer = 0
Dim index As Integer = 0
Dim rowDisplayRectangle = DataGridView1.GetRowDisplayRectangle(0, True)
Dim headerCell = DataGridView1.Columns(0).HeaderCell
Dim defaultCellStyle = DataGridView1.DefaultCellStyle
Dim font = DataGridView1.Font
For Each dataGroup In dataGroups
Dim columnDisplayRectangle = DataGridView1.GetColumnDisplayRectangle(columnIndex, True)
Dim totalSumString = dataGroup.TotalSum.ToString()
Dim rect As New Rectangle(
columnDisplayRectangle.X,
columnDisplayRectangle.Y + headerCell.ContentBounds.Height + counter * rowDisplayRectangle.Height + 8,
columnDisplayRectangle.Width - 1,
(rowDisplayRectangle.Height + 1) * dataGroup.Count - 7 + index)
e.Graphics.FillRectangle(New SolidBrush(defaultCellStyle.BackColor), rect)
Dim point As New Point(
columnDisplayRectangle.X + columnDisplayRectangle.Width - e.Graphics.MeasureString(totalSumString, font).Width - 8,
rect.Y + rect.Height - e.Graphics.MeasureString(totalSumString, font).Height - (rowDisplayRectangle.Height - e.Graphics.MeasureString(totalSumString, font).Height) / 2)
e.Graphics.DrawString(totalSumString, font, New SolidBrush(defaultCellStyle.ForeColor), point)
counter += dataGroup.Count
index += 1
Next
End If
End Sub
End Class
Public Class Model
Public Sub New(pn As Integer, serial As Integer, cost As Double)
Me.PN = pn
Me.Serial = serial
Me.Cost = cost
End Sub
Public Property PN As Integer
Public Property Serial As Integer
Public Property Cost As Double
End Class
它并不简单,也不是开箱即用的。如果您发现项目没有与不同的字体对齐,您可能还需要在绘制事件中欺骗整数。我没时间做那个。
你能帮我处理我的 DataGridView 吗?我需要显示基于另一列的列总和。
例如,我有部件号 1,2,3。由于给定的序列号,PN 的数量始终为 1。
PN 1 有 10 个(10 行)。我需要根据该 PN 对其求和并将总和值放在末尾的单元格中。请看下面的示例:
它是 excel 我知道,但请容忍我假装它是 DataGridView。
总金额基于同一 PN 的成本总和。
你需要按照我评论中的link,在DataGridView_Paint事件中做一些操作。我已经在下面完成了。
我做了一个 class 来保存你的数据,叫做模型。我还使用 DataBinding 将该数据放入 DataGridView。您保存和应用数据的方法可能不同,但这很有效。
Public Class Form1
Private data As List(Of Model)
Private dataGroups As IEnumerable(Of (PN As Integer, TotalSum As Double, Count As Integer))
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
data = New List(Of Model) From {
New Model(1, 1, 11.5),
New Model(1, 12, 2),
New Model(1, 13, 10.4),
New Model(1, 14, 12.3),
New Model(1, 15, 10),
New Model(1, 16, 10),
New Model(2, 17, 5),
New Model(2, 18, 1),
New Model(2, 19, 7),
New Model(2, 20, 2),
New Model(2, 21, 4),
New Model(3, 22, 4),
New Model(3, 23, 6),
New Model(3, 24, 3),
New Model(3, 25, 7)}
DataGridView1.DataSource = data
dataGroups = data.GroupBy(Function(d) d.PN).Select(Function(g) (g.Key, g.Sum(Function(g1) g1.Cost), g.Count()))
Dim textBoxColumn = New DataGridViewTextBoxColumn() With {.HeaderText = "Total Sum"}
DataGridView1.Columns.Add(textBoxColumn)
End Sub
Private Sub DataGridView1_Paint(sender As Object, e As PaintEventArgs) Handles DataGridView1.Paint
If DataGridView1.DataSource IsNot Nothing Then
Dim columnIndex = DataGridView1.Columns.Count - 1
Dim counter As Integer = 0
Dim index As Integer = 0
Dim rowDisplayRectangle = DataGridView1.GetRowDisplayRectangle(0, True)
Dim headerCell = DataGridView1.Columns(0).HeaderCell
Dim defaultCellStyle = DataGridView1.DefaultCellStyle
Dim font = DataGridView1.Font
For Each dataGroup In dataGroups
Dim columnDisplayRectangle = DataGridView1.GetColumnDisplayRectangle(columnIndex, True)
Dim totalSumString = dataGroup.TotalSum.ToString()
Dim rect As New Rectangle(
columnDisplayRectangle.X,
columnDisplayRectangle.Y + headerCell.ContentBounds.Height + counter * rowDisplayRectangle.Height + 8,
columnDisplayRectangle.Width - 1,
(rowDisplayRectangle.Height + 1) * dataGroup.Count - 7 + index)
e.Graphics.FillRectangle(New SolidBrush(defaultCellStyle.BackColor), rect)
Dim point As New Point(
columnDisplayRectangle.X + columnDisplayRectangle.Width - e.Graphics.MeasureString(totalSumString, font).Width - 8,
rect.Y + rect.Height - e.Graphics.MeasureString(totalSumString, font).Height - (rowDisplayRectangle.Height - e.Graphics.MeasureString(totalSumString, font).Height) / 2)
e.Graphics.DrawString(totalSumString, font, New SolidBrush(defaultCellStyle.ForeColor), point)
counter += dataGroup.Count
index += 1
Next
End If
End Sub
End Class
Public Class Model
Public Sub New(pn As Integer, serial As Integer, cost As Double)
Me.PN = pn
Me.Serial = serial
Me.Cost = cost
End Sub
Public Property PN As Integer
Public Property Serial As Integer
Public Property Cost As Double
End Class
它并不简单,也不是开箱即用的。如果您发现项目没有与不同的字体对齐,您可能还需要在绘制事件中欺骗整数。我没时间做那个。