最近项目客户需要对生产数据进行CPK分析,所以通过查资料最后完成了一个版本如下,仅供参考,需要源程序的可以叫我qq584472557。
public partial class CPKAnalyze : Form
{
TextBox textbox = null;
Key key1 = null;//定义键盘
SqlServrDbase DataDB = new SqlServrDbase(MDI.ServerName);
DataTable Table = new DataTable();
List<float> listDate = new List<float>();//全部数据列表
List<float> listAverageX = new List<float>();//平均值列表
List<float> listAverageR = new List<float>();//R均值列表
int calculationSampleNum = 0;//计算样本总数
float AverageX = 0.0F;//总平均值
float AverageR = 0.0F;//R总平均值
int groupNum = 0;//总组数
float Sigma = 0.0F;//标准差
double variance = 0.0;//方差
float MaxRAverage = 0;//所有R最大值
float XUCL = 0;
float XCL = 0;
float XLCL =0;
float RUCL =0;
float RCL = 0;
float RLCL = 0;
public CPKAnalyze()
{
InitializeComponent();
}
private void CPKAnalyze_Load(object sender, EventArgs e)
{
txtboxCL.MouseClick+=new MouseEventHandler(txtbox_MouseClick);
txtboxLSL.MouseClick += new MouseEventHandler(txtbox_MouseClick);
txtboxUSL.MouseClick += new MouseEventHandler(txtbox_MouseClick);
Table.Columns.Add("A");
Table.Columns.Add("B");
Table.Columns.Add("C");
Table.Columns.Add("D");
Table.Columns.Add("E");
dataGridView1.DataSource = Table;
dataGridView1.Columns[0].Width = 160;
dataGridView1.Columns[1].Width = 160;
dataGridView1.Columns[2].Width = 160;
dataGridView1.Columns[3].Width = 160;
dataGridView1.Columns[4].Width = 160;
this.dataGridView1.DefaultCellStyle.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleCenter;
for (int i = 0; i <10; i++)
{
Table.Rows.Add();
}
chart1.Series[0].LegendText = "均值曲线";
chart1.Series[1].LegendText = "UCL曲线";
chart1.Series[2].LegendText = "CL曲线";
chart1.Series[3].LegendText = "LCL曲线";
chart2.Series[0].LegendText = "R均值曲线";
chart2.Series[1].LegendText = "UCL曲线";
chart2.Series[2].LegendText = "CL曲线";
chart2.Series[3].LegendText = "LCL曲线";
}
private void btnFindData_Click(object sender, EventArgs e)
{
CPKDateFind form = new CPKDateFind();
form.StartPosition = FormStartPosition.CenterScreen;
form.FindDataevent+=new CPKDateFind.FindDataeventhandler(form_FindDataevent);//实例事件
form.Show();
}
/// <summary>
/// 查询事件处理函数
/// </summary>
void form_FindDataevent()
{
SelectData();
}
/// <summary>
/// 查询分析数据
/// </summary>
private void SelectData()
{
try
{
DataTable datatable = new DataTable();
datatable = DataDB.GetHistoryOrder(CPKDateFind.SqlStr, "MESData");
int Rownumber = datatable.Rows.Count;//数据总数
int RNum = 0;//行号
int CNum = 0;//列号
int datagridRowNum = Rownumber / 5 + 1;//增加行数
int sampleNum = 0;//样本总个数
Table.Rows.Clear();//清空所有行
//增加datagridview行数
for (int i = 0; i < datagridRowNum; i++)
{
Table.Rows.Add();
}
//往dategridview增加数据
for (int i = 0; i < Rownumber; i++)
{
if (datatable.Rows[i][0] != null)
{
if ((float)datatable.Rows[i][0] != 0)//去除0数据
{
sampleNum = sampleNum + 1;
listDate.Add((float)datatable.Rows[i][0]);//列表增加数据
dataGridView1.Rows[RNum].Cells[CNum].Value = (float)datatable.Rows[i][0];
CNum = CNum + 1;
if (CNum == 5)
{
RNum = RNum + 1;//换行
CNum = 0;
}
}
}
}
groupNum = sampleNum / 5;//组数
calculationSampleNum = groupNum * 5;//计算样本总数
labSampleNum.Text = calculationSampleNum.ToString();
labGroupNum.Text = groupNum.ToString();
}
catch (Exception ex)
{
MessageBox.Show("查询数据时发生错误"+ex .Message);
}
}
private void button1_Click(object sender, EventArgs e)
{
this.Close();
}
private void btnCalculate_Click(object sender, EventArgs e)
{
try
{
float MaxR = 0.0F;//组最大值
float MinR = 0.0F;//组最小值
variance = 0;//方差清零
AverageX = 0.0F;//总平均值
AverageR = 0.0F;//R总平均值
Sigma = 0.0F;//标准差
MaxRAverage = 0;//所有R最大值
listAverageX.Clear();
listAverageR.Clear();
float[] RArray = new float[5] { 0.0F, 0.0F, 0.0F, 0.0F, 0.0F };//组元素数组
if (txtboxUSL.Text.Trim() != "" && txtboxCL.Text.Trim() != "" && txtboxLSL.Text.Trim() != "")
{
if (groupNum >= 2)
{
for (int i = 0; i < groupNum; i++)
{
for (int j = 0; j < 5; j++)
{
RArray[j] = float.Parse(dataGridView1.Rows[i].Cells[j].Value.ToString());
}
listAverageX.Add(RArray.Average());//每组均值列表
MaxR = RArray.Max();
MinR = RArray.Min();
listAverageR.Add(MaxR - MinR);//求每组R列表
}
AverageX = listAverageX.Average();//计算总平均值
labAverageX.Text = AverageX.ToString("0.000");
AverageR = listAverageR.Average();//计算R均值
labAverageR.Text = AverageR.ToString("0.000");
//求方差
for (int i = 0; i < calculationSampleNum; i++)
{
variance += Math.Pow(listDate[i] - AverageX, 2);
}
Sigma = (float)Math.Pow(variance / calculationSampleNum, 0.5);//求标准差
labSigma.Text = Sigma.ToString("0.0000");
XUCL = AverageX + 0.58F * AverageR;
XCL = AverageX;
XLCL = AverageX - 0.58F * AverageR;
labXUCL.Text = XUCL.ToString("0.000");
labXCL.Text = XCL.ToString("0.000");
labXLCL.Text = XLCL.ToString("0.000");
RUCL = 2.11F * AverageR;
RCL = AverageR;
RLCL = 0.0F;
labRUCL.Text = RUCL.ToString("0.000");
labRCL.Text = RCL.ToString("0.000");
labRLCL.Text = RLCL.ToString("0.000");
//显示Grade等级
if (CPK < 0.67)
{
labGrade.Text = "E";
}
else
{
if (CPK < 1)
{
labGrade.Text = "D";
}
else
{
if (CPK < 1.33)
{
labGrade.Text = "C";
}
else
{
if (CPK < 1.67)
{
labGrade.Text = "B";
}
else
{
labGrade.Text = "A";
}
}
}
}
drawAverageCurve();//画均值曲线
drawRCurve();//画R管制曲线
}
else
{
MessageBox.Show("计算样本总数必须大于10,样本组数必须大于等于2");
}
}
else
{
MessageBox.Show("规格参数没有输入,请输入上限、中限和上限值再计算!");
}
}
catch(Exception ex)
{
MessageBox.Show("计算CPK时出现故障"+ex.Message );
}
}
/// <summary>
/// 画均值曲线
/// </summary>
private void drawAverageCurve()
{
// 设置均值曲线的样式
Series seriesAverage = chart1.Series[0];
// 画均值样条曲线(Spline)
seriesAverage.ChartType = SeriesChartType.Spline;
// 线宽1个像素
seriesAverage.BorderWidth = 2;
// 线的颜色:蓝色
seriesAverage.Color = System.Drawing.Color.Blue;
// 图示上的文字
seriesAverage.LegendText = "均值曲线";
// 设置上限曲线的样式
Series seriesUCL= chart1.Series[1];
// 画上限样条曲线(Spline)
seriesUCL.ChartType = SeriesChartType.Spline;
// 线宽1个像素
seriesUCL.BorderWidth = 1;
// 线的颜色:红色
seriesUCL.Color = System.Drawing.Color.Red ;
// 图示上的文字
seriesUCL.LegendText = "UCL曲线";
// 设置中限曲线的样式
Series seriesCL = chart1.Series[2];
// 画中限样条曲线(Spline)
seriesCL.ChartType = SeriesChartType.Spline;
// 线宽1个像素
seriesCL.BorderWidth = 1;
// 线的颜色:黄色
seriesCL.Color = System.Drawing.Color.Yellow ;
// 图示上的文字
seriesCL.LegendText = "CL曲线";
// 设置下限曲线的样式
Series seriesLCL = chart1.Series[3];
// 画下限样条曲线(Spline)
seriesLCL.ChartType = SeriesChartType.Spline;
// 线宽1个像素
seriesLCL.BorderWidth = 1;
// 线的颜色:红色
seriesLCL.Color = System.Drawing.Color.Red ;
// 图示上的文字
seriesLCL.LegendText = "LCL曲线";
//清空曲线
foreach (var series1 in chart1.Series)
{
series1.Points.Clear();
}
// 在chart中显示均值数据
int x = 0;
foreach (float v in listAverageX)
{
seriesAverage.Points.AddXY(x, v);
seriesUCL.Points.AddXY(x, XUCL);
seriesCL.Points.AddXY(x, XCL);
seriesLCL.Points.AddXY(x, XLCL);
x++;
}
MaxRAverage = listAverageR.Max();//最大的R值
// 设置显示范围
ChartArea chartArea = chart1.ChartAreas[0];
chartArea.AxisX.Minimum = 0;
chartArea.AxisX.Maximum = groupNum-1;
chartArea.AxisY.Minimum = (long)(XLCL - MaxRAverage*0.5F);
chartArea.AxisY.Maximum = (long)(XUCL + MaxRAverage * 0.5F);
chartArea.BackColor = Color.AliceBlue;
chartArea.AxisX.MajorGrid.LineColor = System.Drawing.Color.Transparent;//隐藏X轴网格线
chartArea.AxisY.MajorGrid.LineColor = System.Drawing.Color.Transparent;//隐藏Y轴网格线
}