From e50e0519216fd15194e9fd8e1f70b6daadb446cc Mon Sep 17 00:00:00 2001 From: "GukSang.Jin" Date: Sun, 4 Jan 2026 18:16:52 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- WindowsFormsApp6/MainForm.cs | 140 +++++++++++++++++++++++++++-------- 1 file changed, 111 insertions(+), 29 deletions(-) diff --git a/WindowsFormsApp6/MainForm.cs b/WindowsFormsApp6/MainForm.cs index e3c4f62..68ea4f2 100644 --- a/WindowsFormsApp6/MainForm.cs +++ b/WindowsFormsApp6/MainForm.cs @@ -297,68 +297,150 @@ namespace WindowsFormsApp6 /// /// 读取Form1数据(液体吸收时间) - /// PLC地址:D200 - 时间(s) + /// PLC地址:D200 - 时间(s),每次测试读取1个试样(2个字节,1个寄存器) /// 信号量:M103 + /// 每次测试添加一个试样,试样数量动态增长 /// private void ReadForm1Data(byte slaveId) { try { - // 读取D200寄存器(时间数据) - // 假设有5个试样,每个试样1个时间值 - ushort[] registers = _modbusMaster.ReadHoldingRegisters(slaveId, 200, 5); + // 每次只读取1个寄存器(1个试样的数据) + ushort[] registers = _modbusMaster.ReadHoldingRegisters(slaveId, 200, 1); // 使用反射获取Form1的私有字段 var sampleDataTableField = form1Instance.GetType() .GetField("sampleDataTable", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); - if (sampleDataTableField != null) + var currentSampleCountField = form1Instance.GetType() + .GetField("currentSampleCount", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); + + if (sampleDataTableField != null && currentSampleCountField != null) { DataTable dataTable = sampleDataTableField.GetValue(form1Instance) as DataTable; + int currentSampleCount = (int)currentSampleCountField.GetValue(form1Instance); if (dataTable != null) { - // 清除旧的平均值行 + // 移除旧的平均值行 var avgRows = dataTable.Select("序号 = '平均时间(s)'"); foreach (var row in avgRows) { dataTable.Rows.Remove(row); } - // 创建新数据行 + // 获取所有现有的时间行 + var timeRows = dataTable.AsEnumerable() + .Where(r => r.Field("序号") == "时间(s)") + .ToList(); + + // 计算当前已有的试样数量 + int existingSampleCount = timeRows.Count; + int newSampleIndex = existingSampleCount + 1; + + // 如果新试样索引超过当前列数,需要动态添加列 + if (newSampleIndex > currentSampleCount) + { + // 动态扩展DataTable列 + if (!dataTable.Columns.Contains($"试样{newSampleIndex}")) + { + dataTable.Columns.Add($"试样{newSampleIndex}", typeof(double)); + } + + // 更新currentSampleCount + currentSampleCountField.SetValue(form1Instance, newSampleIndex); + currentSampleCount = newSampleIndex; + + // 重新初始化DataGridView以显示新列 + this.Invoke(new Action(() => + { + var initMethod = form1Instance.GetType() + .GetMethod("InitializeDataGridView", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); + initMethod?.Invoke(form1Instance, null); + })); + } + + // 创建新数据行(添加新试样) DataRow dataRow = dataTable.NewRow(); dataRow["序号"] = "时间(s)"; - // 填充时间数据(将寄存器值转换为实际时间,假设寄存器值为整数秒*10) - for (int i = 0; i < Math.Min(registers.Length, 5); i++) + // 将新读取的时间值转换并填充到对应的试样列 + double timeValue = registers[0] / 10.0; // 转换为秒 + dataRow[$"试样{newSampleIndex}"] = timeValue; + + // 其他列设置为空 + for (int i = 1; i < newSampleIndex; i++) { - double timeValue = registers[i] / 10.0; // 转换为秒 - dataRow[$"试样{i + 1}"] = timeValue; + if (dataTable.Columns.Contains($"试样{i}")) + { + dataRow[$"试样{i}"] = DBNull.Value; + } } + // 添加新数据行 dataTable.Rows.Add(dataRow); - // 计算并添加平均值行 - double totalAvg = 0; - int count = 0; - for (int i = 0; i < Math.Min(registers.Length, 5); i++) - { - totalAvg += registers[i] / 10.0; - count++; - } + // 重新获取所有时间行(包括刚添加的) + timeRows = dataTable.AsEnumerable() + .Where(r => r.Field("序号") == "时间(s)") + .ToList(); + + // 计算平均值:每5个试样计算一次平均值 + int totalSamples = timeRows.Count; + int groupCount = (int)Math.Ceiling(totalSamples / 5.0); - if (count > 0) + for (int groupIndex = 0; groupIndex < groupCount; groupIndex++) { - DataRow avgRow = dataTable.NewRow(); - avgRow["序号"] = "平均时间(s)"; - avgRow["试样1"] = totalAvg / count; - - for (int i = 2; i <= 5; i++) + int startSample = groupIndex * 5 + 1; + int endSample = Math.Min(startSample + 4, totalSamples); + + // 计算该组的平均值 + double groupSum = 0; + int validCount = 0; + + for (int i = startSample; i <= endSample; i++) { - avgRow[$"试样{i}"] = DBNull.Value; + var row = timeRows[i - 1]; // 索引从0开始 + + // 找到该行中有值的列 + for (int col = 1; col <= currentSampleCount; col++) + { + if (dataTable.Columns.Contains($"试样{col}") && + row[$"试样{col}"] != DBNull.Value) + { + double value = Convert.ToDouble(row[$"试样{col}"]); + if (value > 0) + { + groupSum += value; + validCount++; + break; // 每行只取一个有效值 + } + } + } + } + + if (validCount > 0) + { + double groupAvg = groupSum / validCount; + + // 创建平均值行 + DataRow avgRow = dataTable.NewRow(); + avgRow["序号"] = "平均时间(s)"; + + // 将平均值显示在该组的第一个试样列 + avgRow[$"试样{startSample}"] = groupAvg; + + // 其他列设置为空 + for (int i = 1; i <= currentSampleCount; i++) + { + if (i != startSample && dataTable.Columns.Contains($"试样{i}")) + { + avgRow[$"试样{i}"] = DBNull.Value; + } + } + + dataTable.Rows.Add(avgRow); } - - dataTable.Rows.Add(avgRow); } // 刷新显示 @@ -373,7 +455,7 @@ namespace WindowsFormsApp6 } } - System.Diagnostics.Debug.WriteLine($"Form1数据读取成功:{registers.Length}个寄存器"); + System.Diagnostics.Debug.WriteLine($"Form1数据读取成功:试样 #{timeRows.Count + 1}"); } catch (Exception ex) {