using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Data; using System.Text; using System.Windows.Forms; using Estsh.Client.Base; using System.Configuration; using System.IO; namespace Estsh.Client.StepLibrary { public partial class KPSNP : StepBase { private StepLibraryAPP app = null; private List _kpsnTable = null; //绑定数据 private delegate void DeleGrdBind(List dt); private int _terminalID = 0; private string _sn = ""; string _stationType = ""; ////PASS上一次成功扫描时间 //private DateTime _lastPassDatetime; //PASS扫描间隔 private int _passIntervalValue = 2000; //PASS间隔限制工位集合 private string _passIntervalLimit = string.Empty; public KPSNP() { InitializeComponent(); // 有用户界面的工步在初始化时需要设置为不可见 // 开始执行此工步后再置为可见 this.Visible = false; } private void txtSN_KeyPress(object sender, KeyPressEventArgs e) { if (e.KeyChar == (char)13) { if (string.IsNullOrEmpty(txtSN.Text)) { return; } string el_no = _sn; string input = txtSN.Text.Trim().ToUpper(); txtSN.Text = string.Empty; if (_kpsnTable == null || _kpsnTable.Count == 0) { if (input == "PASS") { if (IsAllowPass()) { _lastPassDatetime = DateTime.Now; } else { ShowMessage(this, "red|扫描太快,请等待!"); return; } string pdlineID = app.pdLineID(_terminalID.ToString()); if (Context["station_type"].ToString() == "B") { app.updateOnLineStatus(_sn, pdlineID); } dgbKPItems.AutoGenerateColumns = false; dgbKPItems.DataSource = null; Complate(this, e); ShowMessage(this, "green|上一个已完成,请继续操作!"); return; } } // KPSN 的类型 int RowNo = -1; int ErrorNo = 0; bool ErrorState = false; try { ErrorNo = MatchKPSNRule(input, _terminalID, out RowNo); } catch { ShowMessage(this, "red|条码输入错误!"); return; } switch (ErrorNo) { case 1: case 4: ShowMessage(this, "red|系统异常,请联系管理员并检查零件条码!"); resetFocus(); ErrorState = false; break; case 2: ShowMessage(this, "red|零件条码长度不正确,请检查零件条码信息!"); resetFocus(); ErrorState = false; break; case 3: ShowMessage(this, "red|零件条码重复绑定!"); resetFocus(); ErrorState = false; break; case 6: ShowMessage(this, "red|零件条码特征码不正确,请检查零件条码信息!"); resetFocus(); ErrorState = false; break; default: break; } if (RowNo == -1) { resetFocus(); return; } //更新已扫描条码 if (!UpdateKPSNTable(RowNo, input)) { resetFocus(); } if (IsAllBindFull()) { //需要绑定的关键零部件都绑定完成后再进行KPSN的数据插入 for (int i = 0; i < _kpsnTable.Count; i++) { bool insert_kpsn = false; // 插入 KPSN 数据 insert_kpsn = app.InsertKPSNTemp(el_no, _kpsnTable[i]["kpsn"].ToString().Trim(), Convert.ToInt32(_kpsnTable[i]["item_part_id"]), _kpsnTable[i]["version"].ToString(), _kpsnTable[i]["location"].ToString(), _terminalID); if (!insert_kpsn) { ShowMessage(this, "red|插入 KPSN " + _kpsnTable[i]["kpsn"].ToString() + "数据失败,请重试"); } } // 工步执行完成后调用此方法 Complate(this, e); } else { ShowMessage(this, "green|请扫描下一个关键零件"); resetFocus(); } } } /// /// 重置光标 /// private void resetFocus() { txtSN.SelectAll(); txtSN.Focus(); } public override bool Do() { try { ShowMessage(this, "green|请扫描关键零部件条码进行匹配操作!"); // 置为可见并加载到最前端 this.Visible = true; this.BringToFront(); // 从配置文件中加载工位编号 _terminalID = Convert.ToInt32(Context["terminal_id"].ToString()); _stationType = Convert.ToString(Context["station_type"].ToString()); _sn = Context["serial_number"].ToString(); app = new StepLibraryAPP(httpClient); string _PartNo = app.GetPartNo(_sn); string rule = app.GetRuleNo(_PartNo); string partLocation = app.GetPartLoc(_PartNo); _kpsnTable = app.GetBindData(_PartNo, _terminalID); if (_kpsnTable.Count == 0) { if (_stationType != "A") { Complate(this, new EventArgs()); return base.Do(); } } //PASS码两次扫描时间 try { _passIntervalValue = Convert.ToInt32(app.validataLimit("PassIntervalValue")); } catch { _passIntervalValue = 2000; } //PASS码间隔限制工位集合 _passIntervalLimit = app.validataLimit("PassIntervalLimit"); WriteGrdBind(_kpsnTable); // 执行父类的 Do 方法并返回 return base.Do(); } catch (Exception ex) { // 记录日志 using (StreamWriter sw = new StreamWriter("Error_Log_" + DateTime.Now.ToString("yyyyMM") + ".txt", true)) { sw.WriteLine(string.Format("{0} {1}", "[" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "] ", ex.ToString())); sw.Flush(); sw.Close(); } return false; } } public void WriteGrdBind(List dt) { if (!dgbKPItems.InvokeRequired) { dgbKPItems.AutoGenerateColumns = false; dgbKPItems.DataSource = dt; bool theNext = true; for (int i = 0; i < dgbKPItems.Rows.Count; i++) { if (dgbKPItems.Rows[i].Cells["sno"].Value != null && dgbKPItems.Rows[i].Cells["sno"].Value.ToString().Length > 0) { dgbKPItems.Rows[i].DefaultCellStyle.BackColor = Color.Green; } else { if (theNext) { theNext = false; } } } dgbKPItems.Update(); } else { DeleGrdBind de = new DeleGrdBind(WriteGrdBind); this.Invoke(de, new object[] { dt }); } } /// /// 更新 KPSN TABLE /// /// 行号 /// KPSN private bool UpdateKPSNTable(int rowID, string kpsn) { int BindQty = Convert.ToInt16(_kpsnTable[rowID]["BindQty"].ToString()); _kpsnTable[rowID]["BindQty"] = BindQty + 1; _kpsnTable[rowID]["KPSN"] = _kpsnTable[rowID]["KPSN"].ToString() + " " + kpsn; if (dgbKPItems.RowCount >= rowID) { dgbKPItems.Rows[rowID].DefaultCellStyle.BackColor = Color.Green; dgbKPItems.Rows[rowID].DefaultCellStyle.SelectionBackColor = Color.Green; dgbKPItems.Rows[rowID].DefaultCellStyle.SelectionForeColor = Color.Black; } return true; } /// /// 匹配 KPSN RULE /// /// KPSN /// 关键零件的类型(取自 sys_part_sn_rule.type) /// 匹配成功返回 KPSN RULE 的行号,失败返回 -1 private int MatchKPSNRule(string kpsn, int terminalID, out int RowNo) { RowNo = -1; ; int i = 0; try { for (; i < _kpsnTable.Count; i++) { int lenght = Convert.ToInt16(_kpsnTable[i]["lenght"].ToString()); string isValidateUnique = _kpsnTable[i]["is_validate_unique"].ToString(); string isValidateLength = _kpsnTable[i]["is_validate_length"].ToString(); int startPos1 = Convert.ToInt16(_kpsnTable[i]["from1"].ToString()); int endPos1 = Convert.ToInt16(_kpsnTable[i]["to1"].ToString()); string fix1 = _kpsnTable[i]["fix1"].ToString(); string subStr = ""; string kpsnSN = _kpsnTable[i]["kpsn"].ToString(); if (!string.IsNullOrEmpty(kpsnSN)) { continue; } try { // 匹配 RULE1 if (startPos1 > 0 && endPos1 >= startPos1) { try { subStr = kpsn.Substring(startPos1 - 1, endPos1 - startPos1 + 1); } catch { continue; } } } catch { return 1; } if (isValidateLength.ToUpper() == "Y") { if (lenght != kpsn.Length) { return 2; } } string[] fixArr = fix1.Split('/'); if (Array.Exists(fixArr, str => str.Equals(subStr)) == false) { return 6; } if (isValidateUnique.ToUpper() == "Y") { if (app.ExistsKPSN(kpsn, _terminalID)) { return 3; } } RowNo = i; return 0; } return 7; } catch { return 4; } } /// /// 判断 KPSN 是否绑满 /// /// KPSN RULE 的行号 /// 是否绑满 private bool IsBindFull(int rowID) { int Qty = (int)Convert.ToDouble(_kpsnTable[rowID]["item_count"].ToString()); int BindQty = (int)Convert.ToDouble(_kpsnTable[rowID]["BindQty"].ToString()); return Qty == BindQty; } /// /// 判断所有的 KPSN 是否都绑满了 /// /// private bool IsAllBindFull() { for (int i = 0; i < _kpsnTable.Count; i++) { if (!IsBindFull(i)) return false; } return true; } //判断是否允许扫描"PASS"码,通过时间间隔 private bool IsAllowPass() { //如果不在限制的工位集合范围则返回TRUE if (_passIntervalLimit.IndexOf(_terminalID.ToString() + ",") < 0) { return true; } try { TimeSpan ts1 = new TimeSpan(DateTime.Now.Ticks); TimeSpan ts2 = new TimeSpan(_lastPassDatetime.Ticks); TimeSpan ts = ts1.Subtract(ts2).Duration(); long diffValue = Convert.ToInt64(ts.TotalMilliseconds); if (diffValue >= _passIntervalValue) { return true; } } catch { return true; } return false; } private void KPSN_VisibleChanged(object sender, EventArgs e) { txtSN.Focus(); } private void KPSN_Load(object sender, EventArgs e) { txtSN.Focus(); } private void txtSN_Enter(object sender, EventArgs e) { txtSN.SelectAll(); txtSN.BackColor = Color.PeachPuff; } private void txtSN_Leave(object sender, EventArgs e) { txtSN.BackColor = Color.White; } private void dgbKPItems_SelectionChanged(object sender, EventArgs e) { dgbKPItems.ClearSelection(); txtSN.Focus(); } private void timRefreshFocus_Tick(object sender, EventArgs e) { txtSN.Focus(); } private void dgbKPItems_SelectionChanged_1(object sender, EventArgs e) { dgbKPItems.ClearSelection(); } } }