You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何根据数据库列值填充DataGridView并转置展示设备使用数据

实现DataGridView的交叉表(行转列)展示

要实现你需要的这种机器-周的交叉表展示,核心是将源数据的行(按周的记录)转置为列(周作为表头),然后绑定到DataGridView。下面以C# WinForms为例,一步步实现:

核心思路

  1. 从数据库获取原始数据
  2. 提取所有唯一的机器和需要展示的周(包括无数据的周,比如2018-14)
  3. 构建转置后的DataTable,把机器作为行,周作为列,单元格填充对应的HOURSH PIECESP格式
  4. 将转置后的表绑定到DataGridView

代码实现

步骤1:获取原始数据

首先用ADO.NET从数据库读取USAGE表的数据(这里以SQL Server为例,其他数据库只需替换对应的连接和适配类):

DataTable sourceData = new DataTable();
// 替换成你的数据库连接字符串
string connString = "Server=你的服务器;Database=你的库名;Integrated Security=True;";
using (SqlConnection conn = new SqlConnection(connString))
{
    string query = "SELECT MACHINE, WEEK, HOURS, PIECES FROM USAGE";
    SqlDataAdapter adapter = new SqlDataAdapter(query, conn);
    adapter.Fill(sourceData);
}

步骤2:整理元数据(机器和周列表)

我们需要先拿到所有唯一的机器,以及从最小到最大周的连续周列表(确保2018-14这种无数据的周也显示为列):

// 获取排序后的唯一机器列表
List<string> machines = sourceData.AsEnumerable()
    .Select(r => r.Field<string>("MACHINE"))
    .Distinct()
    .OrderBy(m => m)
    .ToList();

// 处理周:将"yyyy-ww"转为可排序的数值(如2018-12→201812),生成连续周范围
var weekNums = sourceData.AsEnumerable()
    .Select(r => r.Field<string>("WEEK"))
    .Distinct()
    .Select(w => int.Parse(w.Replace("-", "")))
    .ToList();
int minWeek = weekNums.Min();
int maxWeek = weekNums.Max();

// 生成所有连续周的字符串格式
List<string> allWeeks = new List<string>();
for (int w = minWeek; w <= maxWeek; w++)
{
    string year = w.ToString().Substring(0, 4);
    string week = w.ToString().Substring(4).PadLeft(2, '0'); // 确保周数是两位
    allWeeks.Add($"{year}-{week}");
}

步骤3:构建转置后的DataTable

创建交叉表结构,填充每个机器的周数据:

DataTable pivotTable = new DataTable();
// 添加第一列:机器名
pivotTable.Columns.Add("MACHINE", typeof(string));
// 添加所有周作为列
foreach (string week in allWeeks)
{
    pivotTable.Columns.Add(week, typeof(string));
}

// 预构建数据字典提升查找效率(大数据量时更明显)
var dataLookup = sourceData.AsEnumerable()
    .ToDictionary(
        r => Tuple.Create(r.Field<string>("MACHINE"), r.Field<string>("WEEK")),
        r => Tuple.Create(r.Field<int>("HOURS"), r.Field<int>("PIECES"))
    );

// 填充每一行机器的数据
foreach (string machine in machines)
{
    DataRow row = pivotTable.NewRow();
    row["MACHINE"] = machine;

    foreach (string week in allWeeks)
    {
        var key = Tuple.Create(machine, week);
        if (dataLookup.ContainsKey(key))
        {
            var hp = dataLookup[key];
            row[week] = $"{hp.Item1}H {hp.Item2}P";
        }
        else
        {
            row[week] = string.Empty; // 无数据则留空
        }
    }

    pivotTable.Rows.Add(row);
}

步骤4:绑定到DataGridView

最后把转置好的表绑定到控件,调整显示样式:

dataGridView1.DataSource = pivotTable;
// 自动调整列宽,优化显示
dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells;
dataGridView1.RowHeadersVisible = false; // 隐藏行头,更简洁

注意事项

  • 如果不需要显示无数据的周(比如2018-14),可以跳过生成连续周的步骤,直接使用weekNums转成字符串的列表即可
  • 如果使用其他数据库(如MySQL、Oracle),只需替换SqlConnection、SqlDataAdapter为对应数据库的类(如MySqlConnection)
  • 若数据量极大,建议在数据库层面先做分组聚合,减少内存处理的压力(比如用SQL的PIVOT函数提前转置,但不同数据库的PIVOT语法有差异)

内容的提问来源于stack exchange,提问作者Miguel Terlaak

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 08:31:56