using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using System.Text.RegularExpressions; using System.Collections; using System.IO; using System.Xml; using BaseFunction; using Telerik.WinControls.UI; using Telerik.WinControls; using System.Linq; using System.Windows.Forms.DataVisualization.Charting; using CheryAnalysis.Properties; using static Telerik.WinControls.UI.ValueMapper; using PLCModule; using HslCommunication.Profinet.Siemens; using static System.Windows.Forms.VisualStyles.VisualStyleElement.TrackBar; using System.Threading; using UserControlClass; using CheryAnalysisDAL; using System.Linq.Expressions; namespace CheryAnalysis { public partial class CheryCenterControl : Telerik.WinControls.UI.ShapedForm { #region 全局变量 private int[] yValues = new int[3]; private string[] xValues = new string[3]; private DataTable dtCSVContent = new DataTable(); private TMeasureDAL tmdal = new TMeasureDAL(); #region PLC相关变量 private bool bStopPlcNormal = false; private static int HeartBeatCount = 0; private bool bPlcLiveTickLast = false; private Thread m_ThreadReconnectPLC = null; private int m_ReConnectNum = 0; private bool bTickt = true; #endregion PLC相关变量 #endregion 全局变量 #region 分页全局变量 private DataTable PageTable = new DataTable(); /// /// 每页记录数 /// public int pageSize = 20; /// /// 总记录数 /// public int recordCount = 0; /// /// 总页数 /// public int pageCount = 0; /// /// 当前页 /// public int currentPage = 0; #endregion 分页全局变量 #region 主窗口事件 public CheryCenterControl() { InitializeComponent(); #region 加载皮肤 ThemeResolutionService.LoadPackageFile(ConfigDfn.strTheme); this.ThemeName = ConfigDfn.strSkinName.Substring(0, ConfigDfn.strSkinName.Length - 5); RPV.ThemeName = ConfigDfn.strSkinName.Substring(0, ConfigDfn.strSkinName.Length - 5); #endregion 加载皮肤 } private void CenterControl_Load(object sender, EventArgs e) { MyBase.rleMessage = rleMessage; rdtpStartTime.Text = DateTime.Now.ToString("yyyy-MM-dd"); rdtpEndTime.Text = DateTime.Now.ToString("yyyy-MM-dd"); MyBase.DeleteAllFiles(ConfigDfn.strNextSenseCSVPath); tmReadNextsenseCSV.Start(); rddlSizeName.SelectedIndex = 0; DataTable dtMPName = tmdal.SelectAllMeasPointName(); if (dtMPName.Rows.Count > 0) { for (int i = 0; i < dtMPName.Rows.Count; i++) { rddlMeasurePoint.Items.Add(dtMPName.Rows[i][0].ToString()); } rddlMeasurePoint.SelectedIndex = 0; } #region 清空信息 labCarNo.Text = ""; labOKCount.Text = ""; labNGCount.Text = ""; labRejectCount.Text = ""; labSumMeasureCount.Text = ""; labMeaTime.Text = ""; labResultPercent.Text = ""; labResult.Text = ""; #endregion 清空信息 #region Load Software Setup rtbCSVPath.Text = FileIni.ReadString(ConfigDfn.strConfigFile, "Chery", "NextsenseCSVPath"); rtbFPY.Text = FileIni.ReadString(ConfigDfn.strConfigFile, "Chery", "FPY"); rtbCSVReportPath.Text = FileIni.ReadString(ConfigDfn.strConfigFile, "Chery", "ReportCSVPath"); rtbPLCIP.Text = FileIni.ReadString(ConfigDfn.strConfigFile, "TCP", "ModbusTcp_IP"); #endregion Load Software Setup #region CSV始化表 //创建虚拟表 DataColumn column2 = new DataColumn("CarID", Type.GetType("System.String")); DataColumn column3 = new DataColumn("MeasPointName", Type.GetType("System.String")); DataColumn column4 = new DataColumn("DimensionName", Type.GetType("System.String")); DataColumn column5 = new DataColumn("NormalValue", Type.GetType("System.String")); DataColumn column6 = new DataColumn("LowerTolVal", Type.GetType("System.String")); DataColumn column7 = new DataColumn("UpperTolVal", Type.GetType("System.String")); DataColumn column8 = new DataColumn("MeasureValue", Type.GetType("System.String")); DataColumn column9 = new DataColumn("MeasureDate", Type.GetType("System.String")); DataColumn column10 = new DataColumn("MeasureItemResult", Type.GetType("System.String")); DataColumn column1 = new DataColumn("Remark", Type.GetType("System.String")); //将列添加到table表中 dtCSVContent.Columns.Add(column2); dtCSVContent.Columns.Add(column3); dtCSVContent.Columns.Add(column4); dtCSVContent.Columns.Add(column5); dtCSVContent.Columns.Add(column6); dtCSVContent.Columns.Add(column7); dtCSVContent.Columns.Add(column8); dtCSVContent.Columns.Add(column9); dtCSVContent.Columns.Add(column10); dtCSVContent.Columns.Add(column1); #endregion CSV始化表 #region 分页相关 //创建虚拟表 DataColumn column11 = new DataColumn("CarID", Type.GetType("System.String")); DataColumn column12 = new DataColumn("MeasPointName", Type.GetType("System.String")); DataColumn column13 = new DataColumn("DimensionName", Type.GetType("System.String")); DataColumn column14 = new DataColumn("NormalValue", Type.GetType("System.String")); DataColumn column15 = new DataColumn("LowerTolVal", Type.GetType("System.String")); DataColumn column16 = new DataColumn("UpperTolVal", Type.GetType("System.String")); DataColumn column17 = new DataColumn("MeasureValue", Type.GetType("System.String")); DataColumn column18 = new DataColumn("MeasureDate", Type.GetType("System.String")); DataColumn column19 = new DataColumn("MeasureItemResult", Type.GetType("System.String")); //将列添加到table表中 PageTable.Columns.Add(column11); PageTable.Columns.Add(column12); PageTable.Columns.Add(column13); PageTable.Columns.Add(column14); PageTable.Columns.Add(column15); PageTable.Columns.Add(column16); PageTable.Columns.Add(column17); PageTable.Columns.Add(column18); PageTable.Columns.Add(column19); labCurrentPage.Text = "当前页:" + currentPage.ToString(); //当前页 labSumPages.Text = "共 " + pageCount.ToString() + " 页";//总页数 labSumRecorders.Text = "总共 " + recordCount.ToString() + " 条记录";//总记录数 rddlPageRecorderCount.SelectedIndex = 0; #endregion 分页相关 #region Test 后期删除掉 //rddlMeasureSeq.SelectedIndex = 0; //rddlMeasureSeq2.SelectedIndex = 0; //rddlWarehouse.SelectedIndex = 0; //List data = new List { 1.2, 1.5, 1.7, 2.1, 2.3, 2.5, 2.7, 2.9, 3.1, 3.3, 3.5 }; //int binCount = 5; //DrawHistogram(chart3, data, binCount); //List data = new List { 2.6, 2.9, 2.7, 2.4, 2.8, 2.5, 2.6, 2.8, 2.7 }; //double target = 2.7; //double tolerance = 0.2; //上限限制-下限限制 //DrawCpCpkHistogram(chartCPCPK, data, target, tolerance); #endregion Test 后期删除掉 } private void CenterControl_FormClosed(object sender, FormClosedEventArgs e) { MyBase.TraceWriteLine("-------------海克斯康奇瑞面隙分析软件程序关闭---------------------"); LogDebugDfn.strEndTime = DateTime.Now.ToString("yyyy.MM.dd HH-mm-ss"); string CopyFileName = ConfigDfn.strFileFolder + "\\DebugFiles\\" + "Debug(" + LogDebugDfn.strStartTime + " To " + LogDebugDfn.strEndTime + ")" + ".txt"; if (File.Exists(LogDebugDfn.strDebugFile)) File.Copy(LogDebugDfn.strDebugFile, CopyFileName); } private void tmSystem_Tick(object sender, EventArgs e) { rleTime.Text = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); } #endregion 主窗口事件 private void DrawHistogram(Chart chart, List data, int binCount) { chart.Series.Clear(); chart.ChartAreas[0].AxisX.Minimum = data.Min(); chart.ChartAreas[0].AxisX.Maximum = data.Max(); // 计算每个bin的宽度 double binWidth = (data.Max() - data.Min()) / binCount; // 计算每个bin的频率 int[] binCounts = new int[binCount]; foreach (double d in data) { int binIndex = (int)((d - data.Min()) / binWidth); if (binIndex == binCount) { binIndex--; } binCounts[binIndex]++; } // 绘制直方图 for (int i = 0; i < binCount; i++) { string binLabel = string.Format("{0:F2}-{1:F2}", i * binWidth, (i + 1) * binWidth); chart.Series.Add(binLabel); chart.Series[binLabel].Points.AddXY((i + 0.5) * binWidth, binCounts[i]); chart.Series[binLabel].ChartType = SeriesChartType.Column; chart.Series[binLabel]["PointWidth"] = "1"; } } private void DrawCpCpkHistogram(Chart chart, List data, double target, double tolerance) { // 计算 Cp 和 Cpk double sigma = data.StandardDeviation(); double Cp = tolerance / (6 * sigma); double Cpk = Math.Min((target - data.Average()) / (3 * sigma), (data.Average() - target) / (3 * sigma)); // 画直方图 chart.Series.Clear(); chart.ChartAreas[0].AxisX.Minimum = data.Min(); chart.ChartAreas[0].AxisX.Maximum = data.Max(); double binWidth = sigma / Math.Sqrt(Cp); int binCount = (int)Math.Floor((data.Max() - data.Min()) / binWidth); if (binCount == 0) binCount = 1; for (int i = 0; i <= binCount; i++) { double binStart = data.Min() + i * binWidth; double binEnd = Math.Min(binStart + binWidth, data.Max()); var binData = data.Where(x => x >= binStart && x < binEnd); string binLabel = string.Format("{0:F2}-{1:F2}", binStart, binEnd); chart.Series.Add(binLabel); chart.Series[binLabel].Points.AddXY((binStart + binEnd) / 2.0, binData.Count()); chart.Series[binLabel].ChartType = SeriesChartType.Column; //chart.Series[binLabel]["PointWidth"] = "1"; //chart.Series[binLabel].Color = binData.Average() < target ? Color.Yellow : binData.Average() > target ? Color.Green : Color.Black; } // 标记 Cp 和 Cpk 的位置 //chart.ChartAreas[0].AxisY2.Enabled = AxisEnabled.True; //chart.ChartAreas[0].AxisY2.Maximum = data.Count(); //chart.ChartAreas[0].AxisY2.Minimum = 0; //chart.ChartAreas[0].AxisY2.LineColor = Color.Transparent; //chart.ChartAreas[0].AxisY2.MajorTickMark.Enabled = false; //chart.ChartAreas[0].AxisY2.MinorTickMark.Enabled = false; //chart.ChartAreas[0].AxisY2.LabelStyle.Enabled = false; //chart.ChartAreas[0].AxisY2.LabelAutoFitMaxFontSize = 8; //chart.ChartAreas[0].AxisY2.CustomLabels.Clear(); //chart.ChartAreas[0].AxisY2.CustomLabels.Add(0.0, data.Count(), string.Format("Cp = {0:F3}\nCpk = {1:F3}", Cp, Cpk)); //chart.ChartAreas[0].AxisY2.CustomLabels[0].ForeColor = Color.Red; ////chart.ChartAreas[0].AxisY2.CustomLabels[0].Font = new Font("Microsoft Sans Serif", 8F, FontStyle.Regular); //chart.ChartAreas[0].AxisY2.CustomLabels[0].MarkColor = Cp >= 1 && Math.Abs(Cpk) >= 1 ? Color.Green : // Cp >= 0.67 && Math.Abs(Cpk) >= 0.67 ? Color.LightPink : // Color.LightYellow; } private void tmReadNextsenseCSV_Tick(object sender, EventArgs e) { AnalysisNextSenseCSV(); } #region 解析Nextsense CSV文件功能 /// 通过给定的文件流,判断文件的编码类型 /// 文件流 /// 文件的编码类型 public static Encoding GetType(FileStream fs) { byte[] Unicode = new byte[] { 0xFF, 0xFE, 0x41 }; byte[] UnicodeBIG = new byte[] { 0xFE, 0xFF, 0x00 }; byte[] UTF8 = new byte[] { 0xEF, 0xBB, 0xBF }; //带BOM System.Text.Encoding reVal = System.Text.Encoding.Default; System.IO.BinaryReader r = new System.IO.BinaryReader(fs, System.Text.Encoding.Default); int i; int.TryParse(fs.Length.ToString(), out i); byte[] ss = r.ReadBytes(i); if (IsUTF8Bytes(ss) || (ss[0] == 0xEF && ss[1] == 0xBB && ss[2] == 0xBF)) { reVal = System.Text.Encoding.UTF8; } else if (ss[0] == 0xFE && ss[1] == 0xFF && ss[2] == 0x00) { reVal = System.Text.Encoding.BigEndianUnicode; } else if (ss[0] == 0xFF && ss[1] == 0xFE && ss[2] == 0x41) { reVal = System.Text.Encoding.Unicode; } r.Close(); return reVal; } /// 判断是否是不带 BOM 的 UTF8 格式 /// /// private static bool IsUTF8Bytes(byte[] data) { int charByteCounter = 1; //计算当前正分析的字符应还有的字节数 byte curByte; //当前分析的字节. for (int i = 0; i < data.Length; i++) { curByte = data[i]; if (charByteCounter == 1) { if (curByte >= 0x80) { //判断当前 while (((curByte <<= 1) & 0x80) != 0) { charByteCounter++; } //标记位首位若为非0 则至少以2个1开始 如:110XXXXX...........1111110X  if (charByteCounter == 1 || charByteCounter > 6) { return false; } } } else { //若是UTF-8 此时第一位必须为1 if ((curByte & 0xC0) != 0x80) { return false; } charByteCounter--; } } if (charByteCounter > 1) { throw new Exception("非预期的byte格式"); } return true; } public Encoding GetType(string FileName) { FileStream fs = new FileStream(FileName, FileMode.Open, FileAccess.Read); Encoding er = GetType(fs); fs.Close(); return er; } /// /// 解析CSV文件函数 /// private void AnalysisNextSenseCSV() { lbCSVFiles.Items.Clear(); FileInfo[] fileInfos = null; if (Directory.Exists(ConfigDfn.strNextSenseCSVPath)) { DirectoryInfo di = new DirectoryInfo(ConfigDfn.strNextSenseCSVPath); fileInfos = di.GetFiles("*.CSV"); if (fileInfos.Count() == 1) { string strCarID = ""; dtCSVContent.Clear(); dgvMeasureContent.Rows.Clear(); string strCSVName = fileInfos[0].FullName; File.Copy(fileInfos[0].FullName, ConfigDfn.strFileFolder + "\\NextSenseCSVBackup\\" + fileInfos[0].Name, true); lbCSVFiles.Items.Add(fileInfos[0].Name); MyBase.TraceWriteLine("开始解析NextSense CSV 报告:" + strCSVName); Encoding encoding = GetType(strCSVName); FileStream fs = new FileStream(strCSVName, FileMode.Open, FileAccess.Read); StreamReader sr = new StreamReader(fs, encoding); //记录每次读取的一行记录 string strLine = ""; //记录每行记录中的各字段内容 string[] aryLineContent = null; //逐行读取CSV中的数据 int LineNum = 0; //表格行数 int dtRowCount = 0; //超差个数 double OutCount = 0; //Ok个数 double OKCount = 0; //异常个数 double RejectedCount = 0; //合格率 double FPYPercent = 0; while ((strLine = sr.ReadLine()) != null) { LineNum++; if (LineNum == 2) { aryLineContent = strLine.Split(','); labCarNo.Text = aryLineContent[1]; strCarID = aryLineContent[1]; } if (LineNum >= 4) { aryLineContent = strLine.Split(','); ConfigDfn.strMeasureTime = aryLineContent[6].Substring(0, 4) + "-" + aryLineContent[6].Substring(4, 2) + "-" + aryLineContent[6].Substring(6, 2) + " " + aryLineContent[7].Substring(0, 2) + ":" + aryLineContent[7].Substring(2, 2) + ":" + aryLineContent[7].Substring(4, 2); string strMeasureResult = aryLineContent[4].ToLower(); dgvMeasureContent.Rows.Add(aryLineContent[0], aryLineContent[1], aryLineContent[5], aryLineContent[9], aryLineContent[10], aryLineContent[2], ConfigDfn.strMeasureTime, aryLineContent[4]); dtCSVContent.Rows.Add(strCarID, aryLineContent[0], aryLineContent[1], aryLineContent[5], aryLineContent[9], aryLineContent[10], aryLineContent[2], ConfigDfn.strMeasureTime, aryLineContent[4], ""); dtRowCount++; dgvMeasureContent.Rows[dtRowCount - 1].HeaderCell.Value = dtRowCount.ToString(); if (strMeasureResult.Contains("reject")) { RejectedCount++; } else if (strMeasureResult.Contains("no")) { OutCount++; } else { OKCount++; } } }//End While sr.Close(); fs.Close(); tmdal.InsertTMeasureDatabyDataTable(dtCSVContent); MyBase.TraceWriteLine("解析数据插入到数据库完毕。"); MyBase.TraceWriteLine("解析NextSense CSV 报告完毕!"); TMeasureResultModel tmrm = new TMeasureResultModel(); labNGCount.Text = OutCount.ToString(); labOKCount.Text = OKCount.ToString(); labRejectCount.Text = RejectedCount.ToString(); labMeaTime.Text = ConfigDfn.strMeasureTime; labSumMeasureCount.Text = dtRowCount.ToString(); FPYPercent = OKCount / (OKCount + OutCount); if (FPYPercent >= ConfigDfn.dFPY) { labResultPercent.Text = Math.Round(FPYPercent * 100.00d, 2).ToString("F2") + "%"; labResult.Text = "合格"; labResultPercent.ForeColor = Color.LimeGreen; labResult.ForeColor = Color.LimeGreen; pbResult.Image = Resources.OK; tmrm.Result = 1; PlcObject.InsertWriteQueue(PlcSignalDfn.CMMResult, (byte)10); } else { labResultPercent.Text = Math.Round(FPYPercent * 100.00d, 2).ToString("F2") + "%"; labResult.Text = "不合格"; labResultPercent.ForeColor = Color.Red; labResult.ForeColor = Color.Red; pbResult.Image = Resources.NG; tmrm.Result = 2; PlcObject.InsertWriteQueue(PlcSignalDfn.CMMResult, (byte)20); } xValues[0] = "合格 : " + OKCount.ToString(); xValues[1] = "不合格 : " + OutCount.ToString(); xValues[2] = "异常 : " + RejectedCount.ToString(); yValues[0] = (int)OKCount; yValues[1] = (int)OutCount; yValues[2] = (int)RejectedCount; chartResultPie.Series[0].Points.DataBindXY(xValues, yValues); tmrm.CarID = strCarID; tmrm.SumMeasureItems = dtRowCount; tmrm.GoodMeasureItems = (int)OKCount; tmrm.NoGoodMeasureItems = (int)OutCount; tmrm.RejectMeasureItems = (int)RejectedCount; tmrm.FPY = FPYPercent.ToString("F4"); tmrm.Remark = ""; tmrm.MeasureDate = ConfigDfn.strMeasureTime; tmdal.InsertTMeasureResult(tmrm); MyBase.TraceWriteLine("将总结果插入数据库完毕。"); MyBase.DeleteAllFiles(ConfigDfn.strNextSenseCSVPath); MyBase.TraceWriteLine("全部插入解析完毕,清空读取CSV的路径:" + ConfigDfn.strNextSenseCSVPath); dgvMeasureContent.Rows.Add(); dgvMeasureContent.Rows[dgvMeasureContent.Rows.Count - 1].Cells["MResult"].Value = (dtRowCount - OutCount - RejectedCount).ToString() + "/" + dtRowCount.ToString(); this.dgvMeasureContent.Rows[dgvMeasureContent.Rows.Count - 1].DefaultCellStyle.ForeColor = Color.White; if (dgvMeasureContent.Rows.Count > 0) { SetdgvRowBgColor(dgvMeasureContent); for (int i = 0; i < dgvMeasureContent.Rows.Count; i++) { if (dgvMeasureContent.Rows[i].Cells["MResult"].Value.ToString().ToLower().Contains("no")) { dgvMeasureContent.Rows[i].DefaultCellStyle.BackColor = Color.Orange; } if (dgvMeasureContent.Rows[i].Cells["MResult"].Value.ToString().ToLower().Contains("rej")) { dgvMeasureContent.Rows[i].DefaultCellStyle.BackColor = Color.Red; } } } #region 解析完报告后,重新生成客户模板报告 //TODO: #endregion 解析完报告后,重新生成客户模板报告 } } } #endregion 解析Nextsense CSV文件功能 #region Home Page /// /// 设置DataGridView各行变色 /// /// DataGridView public void SetdgvRowBgColor(DataGridView dgv) { if (dgv.Rows.Count > 0) { foreach (DataGridViewRow item in dgv.Rows) { if (item.Index % 2 == 0) { item.DefaultCellStyle.BackColor = Color.FromArgb(19, 46, 53); } else { item.DefaultCellStyle.BackColor = Color.FromArgb(27, 60, 68); } } } } //TODO: #endregion Home Page #region Search Data #region datagridview分页功能 /// /// LoadPage方法 /// private void LoadPage() { if (currentPage < 1) currentPage = 1; if (currentPage > pageCount) currentPage = pageCount; int beginRecord; //开始指针 int endRecord; //结束指针 DataTable dtTemp; dtTemp = PageTable.Clone();//Clone方法只会复制DataTable的结构(列定义),而不会复制数据行的引用。 beginRecord = pageSize * (currentPage - 1); if (currentPage == 1) beginRecord = 0; endRecord = pageSize * currentPage; if (currentPage == pageCount) endRecord = recordCount; for (int i = beginRecord; i < endRecord; i++) { // 使用ImportRow方法将源PageTable的行导入到目标dtTemp dtTemp.ImportRow(PageTable.Rows[i]); } dgvSelectMeasureData.Rows.Clear(); for (int i = 0; i < dtTemp.Rows.Count; i++) { dgvSelectMeasureData.Rows.Add(new object[] { dtTemp.Rows[i][0], dtTemp.Rows[i][1], dtTemp.Rows[i][2], dtTemp.Rows[i][3], dtTemp.Rows[i][4], dtTemp.Rows[i][5], dtTemp.Rows[i][6], dtTemp.Rows[i][7], dtTemp.Rows[i][8] }); } SetdgvRowBgColor(dgvSelectMeasureData); for (int i = 0; i < dgvSelectMeasureData.Rows.Count; i++) { string strResult = dgvSelectMeasureData.Rows[i].Cells["MeasureItemResult"].Value.ToString(); if (strResult.ToLower().Contains("no")) { dgvSelectMeasureData.Rows[i].Cells["MeasureItemResult"].Style.ForeColor = Color.Orange; } if (strResult.ToLower().Contains("rej")) { dgvSelectMeasureData.Rows[i].Cells["MeasureItemResult"].Style.ForeColor = Color.Red; } } labCurrentPage.Text = "当前页:" + currentPage.ToString(); //当前页 labSumPages.Text = "共 " + pageCount.ToString() + " 页";//总页数 labSumRecorders.Text = "总共 " + recordCount.ToString() + " 条记录";//总记录数 } private void rbtnFirtstPage_Click(object sender, EventArgs e) { if (currentPage == 1) { return; } currentPage = 1; LoadPage(); } private void rbtnPrevPage_Click(object sender, EventArgs e) { if (currentPage == 1) { return; } currentPage--; LoadPage(); } private void rbtnNextPage_Click(object sender, EventArgs e) { if (currentPage == pageCount) { return; } currentPage++; LoadPage(); } private void rbtnLastPage_Click(object sender, EventArgs e) { if (currentPage == pageCount) { return; } currentPage = pageCount; LoadPage(); } private void rddlPageRecorderCount_SelectedIndexChanged(object sender, Telerik.WinControls.UI.Data.PositionChangedEventArgs e) { pageSize = int.Parse(rddlPageRecorderCount.Text.Trim()); //PageSorter(); } #endregion datagridview分页功能 private void rbtnSearchMeaserData_Click(object sender, EventArgs e) { dgvFPYResult.Visible = false; chartFPYLine.Visible = false; rbtnExportCSVReport.Visible = false; string strStartTime = rdtpStartTime.Value.ToString("yyyy-MM-dd") + " 00:00:00"; string strEndTime = rdtpEndTime.Value.ToString("yyyy-MM-dd") + " 23:59:59"; string strCarID = rtbPartID.Text.Trim(); PageTable.Clear(); PageTable = tmdal.SelectTMeasureDataByCarIDAndTime(strCarID, strStartTime, strEndTime); if (PageTable.Rows.Count > 0) { recordCount = PageTable.Rows.Count; //记录总行数 pageCount = (recordCount / pageSize); if ((recordCount % pageSize) > 0) { pageCount++; } //默认第一页 currentPage = 1; LoadPage();//调用加载数据的方法 dgvSelectMeasureData.Visible = true; rbtnExportCSVReport.Visible = true; pnlPage.Visible = true; labSearchResult.Visible = false; pnlPage.Visible = true; } else { dgvSelectMeasureData.Visible = false; labSearchResult.Visible = true; rbtnExportCSVReport.Visible = false; pnlPage.Visible = false; } } private void rbtSelectFPY_Click(object sender, EventArgs e) { dgvSelectMeasureData.Visible = false; rbtnExportCSVReport.Visible = false; pnlPage.Visible = false; string strStartTime = rdtpStartTime.Value.ToString("yyyy-MM-dd") + " 00:00:00"; string strEndTime = rdtpEndTime.Value.ToString("yyyy-MM-dd") + " 23:59:59"; string strCarID = rtbPartID.Text.Trim(); DataTable dtFPY = new DataTable(); dtFPY = tmdal.SelectTMeasureResultByTime(strCarID, strStartTime, strEndTime); if (dtFPY.Rows.Count > 0) { dgvFPYResult.Visible = true; labSearchResult.Visible = false; rbtnExportCSVReport.Visible = true; chartFPYLine.Visible = true; dgvFPYResult.DataSource = dtFPY; SetdgvRowBgColor(dgvFPYResult); for (int i = 0; i < dgvFPYResult.Rows.Count; i++) { if (dgvFPYResult.Rows[i].Cells["SMResult"].Value.ToString().ToLower().Contains("不合格")) { dgvFPYResult.Rows[i].Cells["SMResult"].Style.ForeColor = Color.Red; } } #region 合格率折线图 //合格率折线图 string[] strXDate = new string[dtFPY.Rows.Count]; double[] dFPYResult = new double[dtFPY.Rows.Count]; for (int i = 0; i < dtFPY.Rows.Count; i++) { strXDate[i] = dtFPY.Rows[i]["CarID"].ToString(); } for (int i = 0; i < dtFPY.Rows.Count; i++) { double dResult = double.Parse(dtFPY.Rows[i]["FPY"].ToString()); dFPYResult[i] = dResult * 100.00; } chartFPYLine.ChartAreas[0].AxisX.LabelStyle.Angle = -50; //X轴标签倾斜角度设置 chartFPYLine.ChartAreas[0].AxisY.LabelStyle.Format = "{0:F2}" + "%"; //设置Y轴值的格式化 带% chartFPYLine.Series[0].Label = "#VAL%"; //设置显示Y的值 chartFPYLine.Series[0].LabelForeColor = Color.White; chartFPYLine.Series[0].ToolTip = "车身编号 : #VALX \r\n合格率 : #VAL%"; //鼠标移动到对应点显示数值 chartFPYLine.Series[0].Points.DataBindXY(strXDate, dFPYResult); #endregion 合格率折线图 } else { dgvFPYResult.Visible = false; labSearchResult.Visible = true; rbtnExportCSVReport.Visible = false; chartFPYLine.Visible = false; } } public static void ExportdgvDataToCsv(DataGridView dataGridView, string filePath) { StringBuilder sb = new StringBuilder(); // 添加列标题 foreach (DataGridViewColumn column in dataGridView.Columns) { sb.Append(column.HeaderText); sb.Append(","); } sb.Remove(sb.Length - 1, 1); sb.AppendLine(); // 添加行数据 foreach (DataGridViewRow row in dataGridView.Rows) { foreach (DataGridViewCell cell in row.Cells) { sb.Append(cell.Value); sb.Append(","); } sb.Remove(sb.Length - 1, 1); sb.AppendLine(); } // 将数据写入CSV文件 File.WriteAllText(filePath, sb.ToString()); } public static void ExportDataTableDataToCsv(DataTable dt, string filePath) { StringBuilder sb = new StringBuilder(); // 添加列标题 foreach (DataColumn column in dt.Columns) { sb.Append(column.ColumnName); sb.Append(","); } sb.Remove(sb.Length - 1, 1); sb.AppendLine(); // 添加行数据 foreach (DataRow row in dt.Rows) { foreach (object item in row.ItemArray) { sb.Append(item); sb.Append(","); } sb.Remove(sb.Length - 1, 1); sb.AppendLine(); } // 将数据写入CSV文件 File.WriteAllText(filePath, sb.ToString()); } private void rbtnExportCSVReport_Click(object sender, EventArgs e) { string strCSVExportPath = ""; string strExportTime = DateTime.Now.ToString("yyyyMMddHHmmssfff"); FolderBrowserDialog m_Folder = new FolderBrowserDialog(); m_Folder.Description = "请选择要导出的CSV文件的路径"; m_Folder.RootFolder = Environment.SpecialFolder.Desktop; if (dgvFPYResult.Visible == true && dgvFPYResult.Rows.Count > 0) { m_Folder.ShowDialog(); if (Directory.Exists(m_Folder.SelectedPath)) { strCSVExportPath = m_Folder.SelectedPath + "\\合格率" + strExportTime + ".CSV"; ExportdgvDataToCsv(dgvFPYResult, strCSVExportPath); } } if (dgvSelectMeasureData.Visible == true && dgvSelectMeasureData.Rows.Count > 0) { m_Folder.ShowDialog(); if (Directory.Exists(m_Folder.SelectedPath)) { strCSVExportPath = m_Folder.SelectedPath + "\\车身尺寸数据" + strExportTime + ".CSV"; ExportDataTableDataToCsv(PageTable, strCSVExportPath); } } } private void dgvFPYResult_RowStateChanged(object sender, DataGridViewRowStateChangedEventArgs e) { e.Row.HeaderCell.Value = string.Format("{0}", e.Row.Index + 1); } private void dgvSelectMeasureData_RowStateChanged(object sender, DataGridViewRowStateChangedEventArgs e) { e.Row.HeaderCell.Value = string.Format("{0}", e.Row.Index + 1); } #endregion Search Data #region CP CPK private void rbtnSearchCPCPK_Click(object sender, EventArgs e) { DataTable dtCPCPK = new DataTable(); string strMeasureName = rddlMeasurePoint.Text; string strSizeName = rddlSizeName.Text.Trim().Substring(0, 1); int iLimitCount = (int)nudMeasureCount.Value; dtCPCPK = tmdal.SelectMeasureValuebyMeasureNameAndSize(strMeasureName, strSizeName, iLimitCount); int iSelectRows = dtCPCPK.Rows.Count; if (iSelectRows < 5) { chartCPCPK.Visible = false; labSearchCPCPKResult.Visible = true; pnlCPCPK.Visible = false; } else { double dNormalValue = double.Parse(dtCPCPK.Rows[0]["NormalValue"].ToString()); double dLowerTolValue = double.Parse(dtCPCPK.Rows[0]["LowerTolVal"].ToString()); double dUpperTolValue = double.Parse(dtCPCPK.Rows[0]["UpperTolVal"].ToString()); double dLSL = dNormalValue + dLowerTolValue; double dUSL = dNormalValue + dUpperTolValue; List listMDoubleData = new List(); List listMStrData = new List(); listMStrData.Clear(); listMDoubleData.Clear(); for (int i = 0; i < iSelectRows; i++) { listMDoubleData.Add(double.Parse(dtCPCPK.Rows[i]["MeasureValue"].ToString())); listMStrData.Add(dtCPCPK.Rows[i]["MeasureValue"].ToString()); } #region 数据赋值 labLSL.Text = dLSL.ToString("F2"); labUSL.Text = dUSL.ToString("F2"); labTarget.Text = dNormalValue.ToString("F2"); labSampleSize.Text = iSelectRows.ToString(); labAverage.Text = CpCpHelper.GetAverage(listMStrData).ToString("F4"); labStdDev.Text = CpCpHelper.GetS(listMStrData).ToString("F4"); List listCpCpk = CpCpHelper.GetCpList(listMStrData, dUSL, dLSL); labCp.Text = listCpCpk[0].ToString("F4"); labCpl.Text = listCpCpk[1].ToString("F4"); labCpu.Text = listCpCpk[2].ToString("F4"); labCpk.Text = listCpCpk[3].ToString("F4"); #endregion 数据赋值 #region 画柱状图 Dictionary histogramDataDic = new Dictionary(); histogramDataDic = CpCpHelper.GetHistogramData(listMDoubleData); string[] strXValue = new string[histogramDataDic.Count]; int[] dYValue = new int[histogramDataDic.Count]; for (int i = 0; i <= histogramDataDic.Count - 1; i++) { strXValue[i] = (histogramDataDic.ElementAt(i).Key); dYValue[i] = int.Parse(histogramDataDic.ElementAt(i).Value); } chartCPCPK.Series[0].Label = "#VAL"; //设置显示Y的值 chartCPCPK.Series[0].LabelForeColor = Color.White; chartCPCPK.Series[0].ToolTip = "区间范围 : #VALX \r\n数量 : #VAL"; //鼠标移动到对应点显示数值 chartCPCPK.Series[0].Points.DataBindXY(strXValue, dYValue); #endregion 画柱状图 chartCPCPK.Visible = true; labSearchCPCPKResult.Visible = false; pnlCPCPK.Visible = true; } } #endregion CP CPK #region 软件设置 private void lpcPLCAddress_Click(object sender, EventArgs e) { PlcAddrSetup PLCAS = new PlcAddrSetup(3, ConfigDfn.strConfigFile); PLCAS.Show(); } private void lpcPLCTest_Click(object sender, EventArgs e) { FormDebugSiemensS7 FDS7 = new FormDebugSiemensS7(SiemensPLCS.S1200); FDS7.Show(); } private void lpcAboutSoftware_Click(object sender, EventArgs e) { AboutSoftwareInfo asi = new AboutSoftwareInfo(); asi.ShowDialog(); } private void rbtnSelectCSVPath_Click(object sender, EventArgs e) { FolderBrowserDialog m_Folder = new FolderBrowserDialog(); m_Folder.Description = "请选择要读取的Nextsense 生成的 CSV报告的路径:"; m_Folder.ShowDialog(); if (Directory.Exists(m_Folder.SelectedPath)) { rtbCSVPath.Text = m_Folder.SelectedPath; } } private void rbtnCSVReportPath_Click(object sender, EventArgs e) { FolderBrowserDialog mFolder = new FolderBrowserDialog(); mFolder.Description = "请选择CSV报告存放的路径:"; mFolder.ShowDialog(); if (Directory.Exists(mFolder.SelectedPath)) { rtbCSVReportPath.Text = mFolder.SelectedPath; } } private void rtbnSaveSetup_Click(object sender, EventArgs e) { FileIni.WriteString(ConfigDfn.strConfigFile, "Chery", "NextsenseCSVPath", rtbCSVPath.Text.Trim()); FileIni.WriteString(ConfigDfn.strConfigFile, "Chery", "FPY", rtbFPY.Text.Trim()); FileIni.WriteString(ConfigDfn.strConfigFile, "Chery", "ReportCSVPath", rtbCSVReportPath.Text.Trim()); FileIni.WriteString(ConfigDfn.strConfigFile, "TCP", "ModbusTcp_IP", rtbPLCIP.Text.Trim()); MessageBox.Show("保存设置完成,请重启软件,参数即可生效! ", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information); } #endregion 软件设置 #region RadButton鼠标事件 private void btn_MouseHover(object sender, EventArgs e) { RadButton btn = sender as RadButton; btn.BackColor = Color.FromArgb(0, 151, 186); } private void btn_MouseLeave(object sender, EventArgs e) { RadButton btn = sender as RadButton; btn.BackColor = Color.FromArgb(19, 46, 53); } #endregion RadButton鼠标事件 #region PLC相关函数 #region PLC重连操作 private void tmrReadPLCData_Tick(object sender, EventArgs e) { tmrReadPLCData.Stop(); #region 判断PLC是否正常运行 if (ConfigPlc.PlcType == 3 && ConfigPlc.bReConnect && !HslSiemensS7Obj.bConnected) { MyBase.TraceWriteLine("PLC断开,重连!"); tmrHeartBeatConnect.Stop(); ReConnectPLC(); return; } byte[] m_Datas = null; if (!HslSiemensS7Obj.ReadDatas(PlcAddrSetup.S7ReadStartAddr, (ushort)PlcAddrSetup.S7ReadByteCount, ref m_Datas)) { tmrReadPLCData.Start(); return; } if (m_Datas == null) { tmrReadPLCData.Start(); MyBase.TraceWriteLine("PLC读取数据对象为空,退出!"); return; } #endregion 判断PLC是否正常运行 #region 循环读取PLC数据块中的信息 if (m_Datas.Length >= PlcAddrSetup.S7ReadByteCount) { PLCDfn.bPlcLiveTick = PlcObject.GetS7ByteData(PlcSignalDfn.PlcLive) == 1; } #endregion 循环读取PLC数据块中的信息 tmrReadPLCData.Start(); } private void tmrRefreshPLCStatus_Tick(object sender, EventArgs e) { if (labelTimeStatus_Tip.Text == "─") { labelTimeStatus_Tip.Text = "╲"; } else if (labelTimeStatus_Tip.Text == "╲") { labelTimeStatus_Tip.Text = "│"; } else if (labelTimeStatus_Tip.Text == "│") { labelTimeStatus_Tip.Text = "╱"; } else if (labelTimeStatus_Tip.Text == "╱") { labelTimeStatus_Tip.Text = "─"; } lampPLCHeart.State = PLCDfn.bPlcLiveTick ? LampColor.Green : LampColor.Silver; rlePLCHeart.ForeColor = PLCDfn.bPlcLiveTick ? Color.Lime : Color.White; } private void tmrHeartBeatConnect_Tick(object sender, EventArgs e) { if (bPlcLiveTickLast != PLCDfn.bPlcLiveTick) { HeartBeatCount = 0; } else { HeartBeatCount++; } if (HeartBeatCount >= 600) { HeartBeatCount = 0; if (!bStopPlcNormal) { MyBase.TraceWriteLine("PLC心跳检测10分钟内未变化,断开PLC,进行PLC重连!"); PlcObject.ClosePlc(); } } bPlcLiveTickLast = PLCDfn.bPlcLiveTick; } private void tmrWritePLCLive_Tick(object sender, EventArgs e) { bTickt = !bTickt; PlcObject.InsertWriteQueue(PlcSignalDfn.SoftLive, Convert.ToByte(bTickt ? 1 : 0)); } private void ReConnectPLC() { m_ThreadReconnectPLC = null; m_ThreadReconnectPLC = new Thread(new ThreadStart(ReConnectPlcProcess)); if (!m_ThreadReconnectPLC.IsAlive) { m_ThreadReconnectPLC.Start(); } } private void ReConnectPlcProcess() { while (!PlcObject.IsPlcConnected()) { bool bConnectResult = PlcObject.ConnectPlc(); if (!bConnectResult) { m_ReConnectNum++; MyBase.TraceWriteLine("重连PLC,第" + m_ReConnectNum + "次!"); } Thread.Sleep(1000); } MyBase.TraceWriteLine("重新连接PLC成功!"); lampConnectPLCStatus.State = LampColor.Green; rlePLCStatus.ForeColor = Color.Lime; this.BeginInvoke((EventHandler)delegate { tmrHeartBeatConnect.Start(); }); bStopPlcNormal = false; m_ReConnectNum = 0; this.Invoke((EventHandler)(delegate { tmrReadPLCData.Start(); tmrWritePLCLive.Start();//启动给PLC写入心跳 1s写一次 0 1 tmrRefreshPLCStatus.Start();//刷新PLC等的状态 })); m_ThreadReconnectPLC.Abort(); } #endregion PLC重连操作 private void ConnectThread() { MyBase.TraceWriteLine("连接PLC...."); bool bConnectResult = PlcObject.ConnectPlc(); this.Invoke((EventHandler)(delegate { if (bConnectResult) { lampConnectPLCStatus.State = LampColor.Green; rlePLCStatus.ForeColor = Color.Lime; MyBase.TraceWriteLine("连接PLC成功"); } else { lampConnectPLCStatus.State = LampColor.Red; rlePLCStatus.ForeColor = Color.Red; tmrReadPLCData.Stop(); MyBase.TraceWriteLine("连接PLC失败"); return; } tmrReadPLCData.Start(); //读取PLC数据信息 tmrWritePLCLive.Start();//启动给PLC写入心跳 1s写一次 0 1 tmrRefreshPLCStatus.Start();//刷新PLC等的状态 if (ConfigPlc.bReConnect) tmrHeartBeatConnect.Start(); //监测来自plc的心跳5分钟内没有变化,重新连接PLC })); } private void btnConnectPlc_Click(object sender, EventArgs e) { try { PlcObject.InitWritePlcThread(); bStopPlcNormal = false; Thread m_Thread = new Thread(ConnectThread); m_Thread.Start(); return; } catch (Exception ex) { MessageBox.Show(ex.Message, "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning); } } private void btnClosePlc_Click(object sender, EventArgs e) { try { MyBase.TraceWriteLine("点击了断开PLC按钮,断开PLC!"); tmrReadPLCData.Stop(); tmrHeartBeatConnect.Stop(); tmrWritePLCLive.Stop(); tmrRefreshPLCStatus.Stop(); lampConnectPLCStatus.State = LampColor.White; rlePLCStatus.ForeColor = Color.White; rlePLCHeart.ForeColor = Color.White; lampPLCHeart.State = LampColor.White; bStopPlcNormal = true; PlcObject.ClosePlc(); } catch (Exception ex) { MessageBox.Show(ex.Message, "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning); } } #endregion PLC相关函数 } }