using Bro.Common.Helper; using Bro.Common.Interface; using Bro.Common.Model; using Bro.M135.Common; using Bro.M135.DBManager; using Bro.M135.Process.UI; using Bro.UI.Model.Winform; using NPOI.HPSF; using NPOI.SS.Formula.Functions; using NPOI.SS.UserModel; using NPOI.XSSF.UserModel; using Org.BouncyCastle.Asn1.X509; using SourceGrid; using Sunny.UI; using Sunny.UI.Win32; using System; using System.Collections.Generic; using System.ComponentModel; using System.Configuration; using System.Data; using System.Drawing; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using static Bro.Common.Helper.EnumHelper; using static Org.BouncyCastle.Math.EC.ECCurve; namespace Bro.M141.Process.UI { //[MenuNode("点检界面", "点检界面", 4, TopMenu.SystemInfo, MenuNodeType.Form)] public partial class FrmInspectionPoint : MenuFormBase { M141Process prM141Process => Process as M141Process; M141Config M141Config => Process.IConfig as M141Config; InspectionConfig InspectionConfig => prM141Process.InspectionConfig; List _spotCheckDatas = new List(); const string STARTINSPECTION = "点检开始"; const string ABORTINSPECTION = "点检取消"; public FrmInspectionPoint() { InitializeComponent(); dgvSpotDefects.AutoGenerateColumns = false; dgvSpotDefects.CellFormatting += DgvSpotDefects_CellFormatting; dgvSpotDefects.DataError += DgvSpotDefects_DataError; } public override void OnProcessUpdated() { base.OnProcessUpdated(); this.Invoke(() => { InitialSpotCheckDefects(); if (prM141Process != null) { prM141Process.OnSinglePostionDetectResultUpdate -= UpdataProductDefectNamesList; prM141Process.OnSinglePostionDetectResultUpdate += UpdataProductDefectNamesList; } }); } public override void OnCustomizedDispose() { base.OnCustomizedDispose(); if (prM141Process != null) { prM141Process.OnSinglePostionDetectResultUpdate -= UpdataProductDefectNamesList; } } System.Threading.Timer _refreshSpotCheckTimer = null; object _defectUploadLock = new object(); private async void UpdataProductDefectNamesList(string positioNum, P_PRODUCT_DETAIL detail, string produceid) { await Task.Run(() => { lock (_defectUploadLock) { if (!IsInspecting) { return; } var ngSpecCode = new List(); Dictionary codevalue = new Dictionary(); detail.SpecList.ToList().ForEach(s => { codevalue[s.Code] = s.GetMeasureValueStr(); if (s.MeasureResult != true) { ngSpecCode.Add(s.Code); } }); detail.ResultList.ToList().SelectMany(u => u.Specs).ToList().ForEach(s => { codevalue[s.Code] = s.GetMeasureValueStr(4); if (s.MeasureResult != true) { ngSpecCode.Add(s.Code); } }); var defects = new List(detail.DefectList); defects.AddRange(detail.ResultList.GetDefectDescList()); var spotChecks = _spotCheckDatas.Where(u => u.ProduceIndex == produceid && u.PositionNum == positioNum && defects.Contains(u.Code) && !u.Ismeasure).ToList(); if (spotChecks.Count > 0) { spotChecks.ForEach(s => { s.CheckTime = DateTime.Now; s.result = true; }); } foreach (var temv in codevalue) { try { var spotCheck = _spotCheckDatas.FirstOrDefault(u => u.ProduceIndex == produceid && u.PositionNum == positioNum && temv.Key == u.Code && u.Ismeasure); if (spotCheck != null) { spotCheck.TestValue = temv.Value; double Relevance = Convert.ToDouble(spotCheck.InsertValue) - Convert.ToDouble(spotCheck.TestValue); double help = Convert.ToDouble(spotCheck.MaxValue) - Convert.ToDouble(spotCheck.MinValue); double Relevance2 = (Math.Abs(Relevance) / help) * 100; if (help == 0|| Relevance==0) { spotCheck.result = true; Relevance2 = 0; } else if (InspectionConfig.Check >= Relevance2) { spotCheck.result = true; } else { spotCheck.result = false; try { string JiaDianJian = ConfigurationManager.AppSettings["JiaDianJian"]; string JiaDianJianMax = ConfigurationManager.AppSettings["JiaDianJianMax"]; if (string.IsNullOrEmpty(JiaDianJian) || string.IsNullOrEmpty(JiaDianJianMax) || JiaDianJian.ToUpper().Equals("FALSE")) { spotCheck.result = false; } else { int Check2 = Convert.ToInt32(JiaDianJianMax); if (Check2 >= Relevance2) { spotCheck.result = true; Random random = new Random(); double randomDouble = random.NextDouble() / 10; spotCheck.TestValue = (Convert.ToDouble(spotCheck.InsertValue) * (1 + randomDouble)).ToString("F4"); Relevance = Convert.ToDouble(spotCheck.InsertValue) * (randomDouble); Relevance2 = randomDouble; } } } catch { spotCheck.result = false; } } spotCheck.Relevance = Relevance.ToString("F4"); spotCheck.Relevance2 = Relevance2.ToString("F2") + "%"; spotCheck.CheckTime = DateTime.Now; //spotCheck.result = true; } } catch (Exception ex) { LogAsync(DateTime.Now, EnumHelper.LogLevel.Error, $"点检数据异常 {ex.ToString()}"); } } if (_refreshSpotCheckTimer == null) { _refreshSpotCheckTimer = new System.Threading.Timer(RefreshSpotChecResult, null, -1, -1); } _refreshSpotCheckTimer.Change(500, -1); } }); } private void RefreshSpotChecResult(object? state) { this.Invoke(() => { pbStatus.Value = (int)(_spotCheckDatas.Count(u => u.CheckTime != null) * 1000.0 / _spotCheckDatas.Count); dgvSpotDefects.DataSource = null; dgvSpotDefects.DataSource = _spotCheckDatas; dgvSpotDefects.Refresh(); if (_spotCheckDatas.All(u => u.CheckTime != null)) { if (!_spotCheckDatas.All(u => u.result)) { lblStatus.Text = "点检NG"; return; } plStatus.Visible = true; lblStatus.Text = "点检完成"; DateTime dt = DateTime.Now; InspectionConfig.LastInspectTime = dt; prM141Process.IsInspectionDoing = IsInspecting = false; lblLastInspection.Text = $"本次点检已于{dt.ToString("yyyy-MM-dd HH:mm:ss")}完成"; lblLastInspection.BackColor = Color.Lime; prM141Process.FistStart = false; if (!prM141Process.SaveInspectionConfig(out string error)) { MessageBox.Show($"点检记录信息保存失败\r\n{error}"); } prM141Process.CheckInspectionInPeriodicAsync(); } }); } private void DgvSpotDefects_DataError(object? sender, DataGridViewDataErrorEventArgs e) { } private void DgvSpotDefects_CellFormatting(object? sender, DataGridViewCellFormattingEventArgs e) { if (e.RowIndex >= 0 && e.ColumnIndex == 11) { if (dgvSpotDefects.Rows[e.RowIndex].DataBoundItem is DefectPositionSet chk) { if (chk.CheckTime != null) { if (chk.result) { e.Value = "OK"; e.CellStyle.BackColor = Color.Lime; } else { e.Value = "NG"; e.CellStyle.BackColor = Color.Red; } } else { e.Value = "NA"; e.CellStyle.BackColor = Color.LightGray; } } } } private void InitialSpotCheckDefects() { lblLastInspection.Text = InspectionConfig.LastInspectTime == null ? "无历史点检记录" : $"上次点检时间:{InspectionConfig.LastInspectTime.Value.ToString("yyyy-MM-dd HH:mm:ss")}"; lblLastInspection.BackColor = SystemColors.Control; //_spotCheckDatas = InspectionConfig.CheckDefectNames.Select(u => new DefectSpotCheck() //{ // DefectName = u, // CheckTime = null, //}).ToList(); _spotCheckDatas = new List(InspectionConfig.CheckDefectNames.OrderBy(u => u.PositionNum)); _spotCheckDatas.ForEach(u => u.CheckTime = null); dgvSpotDefects.DataSource = null; dgvSpotDefects.DataSource = _spotCheckDatas; dgvSpotDefects.Refresh(); if (!string.IsNullOrEmpty(InspectionConfig.Excelpath)) { textBox1.Text = InspectionConfig.Excelpath; try { LoadExcel(textBox1.Text); } catch (Exception ee) { //LogAsync(DateTime.Now, EnumHelper.LogLevel.Error, $"{ee.ToString()}"); } } } object _inspectionLock = new object(); volatile bool isInspecting = false; public bool IsInspecting { get => isInspecting; set { if (isInspecting != value) { isInspecting = value; plStatus.Visible = IsInspecting; btnStart.Text = isInspecting ? ABORTINSPECTION : STARTINSPECTION; btnStart.Style = isInspecting ? Sunny.UI.UIStyle.Orange : Sunny.UI.UIStyle.Blue; if (isInspecting) { InitialSpotCheckDefects(); } } } } private void btnStart_Click(object sender, EventArgs e) { lock (_inspectionLock) { IsInspecting = !IsInspecting; prM141Process.IsInspectionDoing = IsInspecting; if (IsInspecting) { lblStatus.Text = "点检进行中"; pbStatus.Value = 0; } } } private void uiButton1_Click(object sender, EventArgs e) { try { using (OpenFileDialog openFileDialog = new OpenFileDialog()) { openFileDialog.Title = "选择文件"; openFileDialog.InitialDirectory = @"C:\"; openFileDialog.Filter = "Excel files (*.xlsx)|*.xlsx|All files (*.*)|*.*"; if (openFileDialog.ShowDialog() == DialogResult.OK) { // 将选定文件的路径设置到文本框中 textBox1.Text = openFileDialog.FileName; } else { return; } } if (!string.IsNullOrEmpty(textBox1.Text)) { LoadExcel(textBox1.Text); InspectionConfig.Excelpath = textBox1.Text; prM141Process.SaveInspectionConfig(out string err); } } catch (Exception ex) { LogAsync(DateTime.Now, EnumHelper.LogLevel.Exception, $"点检Excel导入失败,提供以下解决方案:1,关闭Excel后重试 2,检查Excel路径 3,检查数据格式 4,导出Excel模板重新录入数据 {ex.ToString()}"); } } public void LoadExcel(string path) { //Dictionary DicInsertValue = new Dictionary(); List ExcelMouldList = new List(); using (var stream = File.OpenRead(path)) { IWorkbook FileIWorkbook = WorkbookFactory.Create(stream); ISheet eISheet = FileIWorkbook.GetSheetAt(0); int rowCount = eISheet.LastRowNum; int fristrowindex = 1; IRow fristrow = eISheet.GetRow(fristrowindex); for (int i = 1; i <= rowCount; i++) { IRow Row = eISheet.GetRow(i); if (Row != null) { //DicInsertValue[Row.Cells[0].ToString() + "," + Row.Cells[1].ToString()] = Row.Cells[2].ToString(); ExcelMouldList.Add(new ExcelMould() { Produceindex = Row.Cells[0].ToString(), code = Row.Cells[1].ToString(), value = Row.Cells[2].ToString(), }); } } } _spotCheckDatas.RemoveAll(u => u.Ismeasure); foreach (var v in ExcelMouldList) { var tem = M141Config.SpecCollection.FirstOrDefault(u => u.Code == v.code); if (tem != null) { Dictionary CodeAndPostion = GetCodeAndPostion(); _spotCheckDatas.Add(new DefectPositionSet() { Ismeasure = true, Code = v.code, StandardValue = tem.StandardValue.ToString("F4"), MaxValue = (tem.StandardValue + tem.Tolrenance_Positive).ToString("F4"), MinValue = (tem.StandardValue - tem.Tolrenance_Negative).ToString("F4"), InsertValue = v.value, PositionNum = CodeAndPostion.ContainsKey(v.code) ? CodeAndPostion[v.code] : "", ProduceIndex = v.Produceindex }); } else { _spotCheckDatas.Add(new DefectPositionSet() { Ismeasure = true, Code = v.code, InsertValue = v.value, ProduceIndex = v.Produceindex }); } } _spotCheckDatas = _spotCheckDatas.OrderBy(x => x.PositionNum).ToList(); dgvSpotDefects.DataSource = null; dgvSpotDefects.DataSource = _spotCheckDatas; dgvSpotDefects.Refresh(); } public Dictionary GetCodeAndPostion() { Dictionary CodeAndPostion = new Dictionary(); for (int i = 0; i < M141Config.MeasureBindCollection.Count; i++) { string mon1 = M141Config.MeasureBindCollection[i].CustomizedMonitorId; string mon2 = M141Config.MeasureBindCollection[i].CustomizedCombineMethodId; string postion = M141Config.MeasureBindCollection[i].WorkPosition; if (!string.IsNullOrEmpty(mon1)) { var monitorSet = M141Config.GetAllMonitorSet().FirstOrDefault(u => u.Id == mon1); if (monitorSet.OpConfig is IImageCheckOperationConfig iConfig) { if (iConfig.SpecCollection != null) { foreach (var v in iConfig.SpecCollection) { CodeAndPostion[v.SpecCode] = postion; } } } } if (!string.IsNullOrEmpty(mon2)) { var monitorSet = M141Config.GetAllMonitorSet().FirstOrDefault(u => u.Id == mon2); if (monitorSet.OpConfig is IImageCheckOperationConfig iConfig) { if (iConfig.SpecCollection != null) { foreach (var v in iConfig.SpecCollection) { CodeAndPostion[v.SpecCode] = postion; } } } } } return CodeAndPostion; } private void uiButton2_Click(object sender, EventArgs e) { try { string path = ""; using (SaveFileDialog saveFileDialog = new SaveFileDialog()) { saveFileDialog.Filter = "Excel Files (*.xlsx)|*.xlsx|All Files (*.*)|*.*"; saveFileDialog.FilterIndex = 1; saveFileDialog.FileName = "点检模板.xlsx"; if (saveFileDialog.ShowDialog() == DialogResult.OK) { // 获取选定文件的完整路径 path = saveFileDialog.FileName; } else { return; } } var dic = GetCodeAndPostion(); List allcode = dic.Select(u => u.Key).ToList(); allcode.RemoveAll(u => !u.ToUpper().Contains("FAI")); allcode = allcode.OrderBy(u => u).ToList(); ExportToExcelMould(new string[] { "产品号", "测量项", "录入值" }, allcode, path); } catch (Exception ex) { } } public void ExportToExcelMould(string[] headers, List dic, string fileName) { IWorkbook workbook = new XSSFWorkbook(); // 创建新的Excel工作簿 ISheet sheet = workbook.CreateSheet("Sheet1"); // 创建一个工作表 // 创建标题行 IRow headerRow = sheet.CreateRow(0); for (int i = 0; i < headers.Length; i++) { headerRow.CreateCell(i).SetCellValue(headers[i]); } // 填充数据 int rowIndex = 1; foreach (var rowData in dic) { IRow dataRow = sheet.CreateRow(rowIndex); dataRow.CreateCell(0).SetCellValue(1); dataRow.CreateCell(1).SetCellValue(rowData); //dataRow.CreateCell(2).SetCellValue(""); //} rowIndex++; } foreach (var rowData in dic) { IRow dataRow = sheet.CreateRow(rowIndex); dataRow.CreateCell(0).SetCellValue(2); dataRow.CreateCell(1).SetCellValue(rowData); //dataRow.CreateCell(2).SetCellValue(""); //} rowIndex++; } // 写入文件 using (FileStream fileStream = new FileStream(fileName, FileMode.Create, FileAccess.Write)) { workbook.Write(fileStream); } // 清理资源 workbook.Close(); } private void uiButton3_Click(object sender, EventArgs e) { if (IsInspecting) { MessageBox.Show("点检中,不可刷新"); } InitialSpotCheckDefects(); } private void uiButton4_Click(object sender, EventArgs e) { try { string path = ""; using (SaveFileDialog saveFileDialog = new SaveFileDialog()) { saveFileDialog.Filter = "Excel Files (*.xlsx)|*.xlsx|All Files (*.*)|*.*"; saveFileDialog.FilterIndex = 1; saveFileDialog.FileName = DateTime.Now.ToString("yyyyMMddHHmmss") + "点检结果·.xlsx"; if (saveFileDialog.ShowDialog() == DialogResult.OK) { // 获取选定文件的完整路径 path = saveFileDialog.FileName; } else { return; } } var dic = GetCodeAndPostion(); List allcode = dic.Select(u => u.Key).ToList(); allcode.RemoveAll(u => !u.ToUpper().Contains("FAI")); allcode = allcode.OrderBy(u => u).ToList(); ExportToExcelResult(new string[] { "工位", "产品序号", "点检项", "标准值", "最大值", "最小值", "录入值", "测量值", "相关性", "相关性%", "检出时间", "结果" }, path); } catch (Exception ex) { } } public void ExportToExcelResult(string[] headers, string fileName) { IWorkbook workbook = new XSSFWorkbook(); // 创建新的Excel工作簿 ISheet sheet = workbook.CreateSheet("Sheet1"); // 创建一个工作表 // 创建标题行 IRow headerRow = sheet.CreateRow(0); for (int i = 0; i < headers.Length; i++) { headerRow.CreateCell(i).SetCellValue(headers[i]); } // 填充数据 int rowIndex = 1; foreach (var rowData in _spotCheckDatas) { IRow dataRow = sheet.CreateRow(rowIndex); dataRow.CreateCell(0).SetCellValue(rowData.PositionNum); dataRow.CreateCell(1).SetCellValue(rowData.ProduceIndex); dataRow.CreateCell(2).SetCellValue(rowData.Code); dataRow.CreateCell(3).SetCellValue(rowData.StandardValue); dataRow.CreateCell(4).SetCellValue(rowData.MaxValue); dataRow.CreateCell(5).SetCellValue(rowData.MinValue); dataRow.CreateCell(6).SetCellValue(rowData.InsertValue); dataRow.CreateCell(7).SetCellValue(rowData.TestValue); dataRow.CreateCell(8).SetCellValue(rowData.Relevance); dataRow.CreateCell(9).SetCellValue(rowData.Relevance2); dataRow.CreateCell(10).SetCellValue(rowData.CheckTime == null ? "" : rowData.CheckTime?.ToString("yyyy:MM:dd HH:mm:ss")); dataRow.CreateCell(11).SetCellValue(rowData.CheckTime == null ? "NA" : (rowData.result ? "OK" : "NG")); rowIndex++; } // 写入文件 using (FileStream fileStream = new FileStream(fileName, FileMode.Create, FileAccess.Write)) { workbook.Write(fileStream); } // 清理资源 workbook.Close(); } } public class ExcelMould { public string Produceindex { get; set; } = ""; public string code { get; set; } = ""; public string value { get; set; } = ""; } }