This commit is contained in:
GukSang.Jin
2026-01-05 11:25:23 +08:00
parent 81ef81300e
commit 365f6d63b9

View File

@@ -140,7 +140,7 @@ namespace WindowsFormsApp6
HeaderText = $"试样{i}\n1",
DataPropertyName = $"试样{i}_1",
Width = 100,
ReadOnly = false,
ReadOnly = true,
DefaultCellStyle = (DataGridViewCellStyle)centerStyle.Clone()
});
@@ -150,7 +150,7 @@ namespace WindowsFormsApp6
HeaderText = $"试样{i}\n2",
DataPropertyName = $"试样{i}_2",
Width = 100,
ReadOnly = false,
ReadOnly = true,
DefaultCellStyle = (DataGridViewCellStyle)centerStyle.Clone()
});
@@ -160,7 +160,7 @@ namespace WindowsFormsApp6
HeaderText = $"试样{i}\n3",
DataPropertyName = $"试样{i}_3",
Width = 100,
ReadOnly = false,
ReadOnly = true,
DefaultCellStyle = (DataGridViewCellStyle)centerStyle.Clone()
});
}
@@ -199,7 +199,7 @@ namespace WindowsFormsApp6
HeaderText = ROW_WICKING_HEIGHT,
DataPropertyName = ROW_WICKING_HEIGHT,
Width = 120,
ReadOnly = false,
ReadOnly = true,
DefaultCellStyle = (DataGridViewCellStyle)centerStyle.Clone()
});
@@ -239,33 +239,8 @@ namespace WindowsFormsApp6
/// </summary>
private void DataGridView1_CellBeginEdit(object sender, DataGridViewCellCancelEventArgs e)
{
if (e.RowIndex >= 0 && e.ColumnIndex > 0)
{
if (isVerticalLayout)
{
// 纵向布局:只有吸芯高度行可以编辑
string rowName = dataGridView1.Rows[e.RowIndex].Cells["序号"].Value?.ToString() ?? "";
if (rowName == ROW_WICKING_HEIGHT)
{
return; // 允许编辑
}
e.Cancel = true; // 其他行不可编辑
}
else
{
// 横向布局:只有吸芯高度列可以编辑
string columnName = dataGridView1.Columns[e.ColumnIndex].Name;
if (columnName == ROW_WICKING_HEIGHT)
{
return; // 允许编辑
}
e.Cancel = true; // 其他列不可编辑
}
}
// 所有单元格都不可编辑吸芯高度从PLC自动读取
e.Cancel = true;
}
/// <summary>
@@ -303,32 +278,12 @@ namespace WindowsFormsApp6
/// <summary>
/// 单元格值改变事件 - 手动输入后重新计算
/// 注意:由于所有单元格都不可编辑,此事件不会被触发
/// </summary>
private void DataGridView1_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
if (e.RowIndex >= 0 && e.ColumnIndex >= 0)
{
bool shouldRecalculate = false;
if (isVerticalLayout)
{
// 纵向布局:检查是否是吸芯高度行
string rowName = dataGridView1.Rows[e.RowIndex].Cells["序号"].Value?.ToString() ?? "";
shouldRecalculate = (rowName == ROW_WICKING_HEIGHT);
}
else
{
// 横向布局:检查是否是吸芯高度列
string columnName = dataGridView1.Columns[e.ColumnIndex].Name;
shouldRecalculate = (columnName == ROW_WICKING_HEIGHT);
}
if (shouldRecalculate)
{
CalculateAllRows();
RefreshDataGridView();
}
}
// 所有单元格都不可编辑,此事件不会被触发
// 保留此方法以防将来需要启用编辑功能
}
/// <summary>
@@ -862,7 +817,9 @@ namespace WindowsFormsApp6
/// <summary>
/// 计算平均芯吸速率mm/min
/// 计算方式:每试样显示该组3次测试的平均值
/// 计算方式:每试样的3次测试计算一个平均值合并显示在该试样的一列中
/// 纵向布局显示在该试样的第1列试样N_1
/// 横向布局显示在该试样的第3次测试行
/// </summary>
private void CalculateAverageWickingRate()
{
@@ -872,7 +829,15 @@ namespace WindowsFormsApp6
DataRow rateRow = sampleDataTable.Rows[2];
DataRow avgRow = sampleDataTable.Rows[3];
// 计算每组试样的平均值,并填充到对应列
// 清空平均值行的所有数据
for (int i = 1; i <= currentSampleCount; i++)
{
avgRow[$"试样{i}_1"] = 0.0;
avgRow[$"试样{i}_2"] = 0.0;
avgRow[$"试样{i}_3"] = 0.0;
}
// 计算每个试样的平均值并填充到该试样的第1列合并显示效果
for (int i = 1; i <= currentSampleCount; i++)
{
double rate1 = ConvertToDouble(rateRow[$"试样{i}_1"]);
@@ -884,17 +849,24 @@ namespace WindowsFormsApp6
if (rate2 > 0) groupRates.Add(rate2);
if (rate3 > 0) groupRates.Add(rate3);
// 计算该平均值
// 计算该试样的平均值
double groupAvg = groupRates.Count > 0 ? groupRates.Average() : 0;
// 填充到该试样的第3列
avgRow[$"试样{i}_3"] = Math.Round(groupAvg, 2);
// 填充到该试样的第1列实现合并显示效果
avgRow[$"试样{i}_1"] = Math.Round(groupAvg, 2);
// 第2、3列保持为0显示为空白
}
}
else
{
// 横向布局
// 计算每组试样的平均值
// 清空所有行的平均值
foreach (DataRow row in sampleDataTable.Rows)
{
row[ROW_AVG_WICKING_RATE] = 0.0;
}
// 计算每个试样的平均值
for (int i = 1; i <= currentSampleCount; i++)
{
List<double> groupRates = new List<double>();
@@ -909,10 +881,10 @@ namespace WindowsFormsApp6
}
}
// 计算该平均值
// 计算该试样的平均值
double groupAvg = groupRates.Count > 0 ? groupRates.Average() : 0;
// 填充到该的第3次测试行
// 填充到该试样的第3次测试行(合并显示效果)
int targetRowIndex = (i - 1) * 3 + 2; // 第3次测试的行索引
if (targetRowIndex < sampleDataTable.Rows.Count)
{
@@ -924,116 +896,129 @@ namespace WindowsFormsApp6
/// <summary>
/// 计算标准偏差
/// 计算方式:基于每试样的平均芯吸速率计算标准偏差(组间标准偏差)
/// 计算方式:基于每试样的平均芯吸速率计算标准偏差(组间标准偏差)
/// 结果只有一个标准偏差值合并显示在第1列
///
/// 说明:
/// - 每5个试样为一组计算该组的标准偏差
/// - 如果试样数量不足5个则计算现有试样的标准偏差
/// - 标准偏差基于每个试样的平均芯吸速率计算
/// </summary>
private void CalculateStandardDeviation()
{
List<double> groupAverages = new List<double>(); // 存储每组的平均值
if (isVerticalLayout)
{
// 纵向布局
DataRow rateRow = sampleDataTable.Rows[2];
DataRow stdRow = sampleDataTable.Rows[4];
// 计算每组试样的平均值
// 清空标准偏差行的所有数据
for (int i = 1; i <= currentSampleCount; i++)
{
double rate1 = ConvertToDouble(rateRow[$"试样{i}_1"]);
double rate2 = ConvertToDouble(rateRow[$"试样{i}_2"]);
double rate3 = ConvertToDouble(rateRow[$"试样{i}_3"]);
List<double> groupRates = new List<double>();
if (rate1 > 0) groupRates.Add(rate1);
if (rate2 > 0) groupRates.Add(rate2);
if (rate3 > 0) groupRates.Add(rate3);
// 如果该组有有效数据,计算该组平均值
if (groupRates.Count > 0)
{
double groupAvg = groupRates.Average();
groupAverages.Add(groupAvg);
}
stdRow[$"试样{i}_1"] = 0.0;
stdRow[$"试样{i}_2"] = 0.0;
stdRow[$"试样{i}_3"] = 0.0;
}
// 基于组平均值计算标准偏差
double stdDev = 0;
if (groupAverages.Count > 1)
// 计算每组5个试样标准偏差
int groupCount = (int)Math.Ceiling((double)currentSampleCount / 5.0);
for (int groupIndex = 0; groupIndex < groupCount; groupIndex++)
{
double overallAverage = groupAverages.Average();
double sumOfSquares = groupAverages.Sum(avg => Math.Pow(avg - overallAverage, 2));
stdDev = Math.Sqrt(sumOfSquares / (groupAverages.Count - 1));
}
int startSample = groupIndex * 5 + 1;
int endSample = Math.Min(startSample + 4, currentSampleCount);
List<double> groupAverages = new List<double>(); // 存储该组每个试样的平均值
// 只在第1列显示标准偏差其他列清空
for (int i = 1; i <= currentSampleCount; i++)
{
if (i == 1)
// 计算该组每个试样的平均值
for (int i = startSample; i <= endSample; i++)
{
stdRow[$"试样{i}_1"] = Math.Round(stdDev, 2);
double rate1 = ConvertToDouble(rateRow[$"试样{i}_1"]);
double rate2 = ConvertToDouble(rateRow[$"试样{i}_2"]);
double rate3 = ConvertToDouble(rateRow[$"试样{i}_3"]);
List<double> sampleRates = new List<double>();
if (rate1 > 0) sampleRates.Add(rate1);
if (rate2 > 0) sampleRates.Add(rate2);
if (rate3 > 0) sampleRates.Add(rate3);
// 如果该试样有有效数据,计算该试样的平均值
if (sampleRates.Count > 0)
{
double sampleAvg = sampleRates.Average();
groupAverages.Add(sampleAvg);
}
}
else
// 基于该组试样的平均值计算标准偏差
double stdDev = 0;
if (groupAverages.Count > 1)
{
stdRow[$"试样{i}_1"] = 0.0;
stdRow[$"试样{i}_2"] = 0.0;
stdRow[$"试样{i}_3"] = 0.0;
double overallAverage = groupAverages.Average();
double sumOfSquares = groupAverages.Sum(avg => Math.Pow(avg - overallAverage, 2));
stdDev = Math.Sqrt(sumOfSquares / (groupAverages.Count - 1));
}
// 只在该组第1个试样的第1列显示标准偏差合并显示效果
stdRow[$"试样{startSample}_1"] = Math.Round(stdDev, 2);
}
}
else
{
// 横向布局
// 计算每组试样的平均值
for (int i = 1; i <= currentSampleCount; i++)
// 清空所有行的标准偏差列
foreach (DataRow row in sampleDataTable.Rows)
{
List<double> groupRates = new List<double>();
for (int j = 1; j <= 3; j++)
{
int rowIndex = (i - 1) * 3 + (j - 1);
if (rowIndex < sampleDataTable.Rows.Count)
{
double rate = ConvertToDouble(sampleDataTable.Rows[rowIndex][ROW_WICKING_RATE]);
if (rate > 0) groupRates.Add(rate);
}
}
// 如果该组有有效数据,计算该组平均值
if (groupRates.Count > 0)
{
double groupAvg = groupRates.Average();
groupAverages.Add(groupAvg);
}
row[ROW_STD_DEVIATION] = 0.0;
}
// 基于组平均值计算标准偏差
double stdDev = 0;
if (groupAverages.Count > 1)
// 计算每组5个试样标准偏差
int groupCount = (int)Math.Ceiling((double)currentSampleCount / 5.0);
for (int groupIndex = 0; groupIndex < groupCount; groupIndex++)
{
double overallAverage = groupAverages.Average();
double sumOfSquares = groupAverages.Sum(avg => Math.Pow(avg - overallAverage, 2));
stdDev = Math.Sqrt(sumOfSquares / (groupAverages.Count - 1));
}
int startSample = groupIndex * 5 + 1;
int endSample = Math.Min(startSample + 4, currentSampleCount);
List<double> groupAverages = new List<double>(); // 存储该组每个试样的平均值
// 只在第1行显示标准偏差其他行清空
int dataRowIndex = 0;
for (int i = 1; i <= currentSampleCount; i++)
{
for (int j = 1; j <= 3; j++)
// 计算该组每个试样的平均值
for (int i = startSample; i <= endSample; i++)
{
if (dataRowIndex < sampleDataTable.Rows.Count)
List<double> sampleRates = new List<double>();
for (int j = 1; j <= 3; j++)
{
if (dataRowIndex == 0) // 只在第1行显示
int rowIndex = (i - 1) * 3 + (j - 1);
if (rowIndex < sampleDataTable.Rows.Count)
{
sampleDataTable.Rows[dataRowIndex][ROW_STD_DEVIATION] = Math.Round(stdDev, 2);
double rate = ConvertToDouble(sampleDataTable.Rows[rowIndex][ROW_WICKING_RATE]);
if (rate > 0) sampleRates.Add(rate);
}
else
{
sampleDataTable.Rows[dataRowIndex][ROW_STD_DEVIATION] = 0.0;
}
dataRowIndex++;
}
// 如果该试样有有效数据,计算该试样的平均值
if (sampleRates.Count > 0)
{
double sampleAvg = sampleRates.Average();
groupAverages.Add(sampleAvg);
}
}
// 基于该组试样的平均值计算标准偏差
double stdDev = 0;
if (groupAverages.Count > 1)
{
double overallAverage = groupAverages.Average();
double sumOfSquares = groupAverages.Sum(avg => Math.Pow(avg - overallAverage, 2));
stdDev = Math.Sqrt(sumOfSquares / (groupAverages.Count - 1));
}
// 只在该组第1个试样的第1次测试行显示标准偏差合并显示效果
int targetRowIndex = (startSample - 1) * 3; // 第1次测试的行索引
if (targetRowIndex < sampleDataTable.Rows.Count)
{
sampleDataTable.Rows[targetRowIndex][ROW_STD_DEVIATION] = Math.Round(stdDev, 2);
}
}
}