using System; using System.Collections.Generic; using System.Data; using System.Drawing; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using UAS_MES_NEW.CustomControl.ButtonUtil; using UAS_MES_NEW.CustomControl.RichText; using UAS_MES_NEW.DataOperate; using UAS_MES_NEW.Entity; using UAS_MES_NEW.PublicMethod; namespace UAS_MES_NEW.Make { public partial class Make_ShipmentVerify : Form { public Make_ShipmentVerify() { InitializeComponent(); } DataTable dt, data; DataHelper dh; int panelQty; string oMakeCode, oMSID, reworkstatus, ifrework, ErrorMessage; private void Make_HandFeedRegistration_Load(object sender, EventArgs e) { dh = SystemInf.dh; data = new DataTable(); data.Columns.Add("isDel", typeof(bool)); data.Columns.Add("rn", typeof(int)); data.Columns.Add("ms_sncode", typeof(string)); data.Columns.Add("ms_makecode", typeof(string)); dgv.AutoGenerateColumns = false; dgv.DataSource = data; snVal.Enabled = false; if (string.IsNullOrEmpty(BoxQtyVal.Text)) BoxQtyVal.Text = "0"; LockMakeCode.GetMakeCodeCtl(ma_code); ma_code.SetLockCheckBox(LockMakeCode); ma_code.TableName = "make left join product on ma_prodcode=pr_code"; ma_code.SelectField = "ma_code # 工单号,ma_prodcode # 产品编号,ma_qty # 工单数量,pr_spec # 产品规格,ma_softversion # 软件版本,ma_salecode # 销售单号,pr_sendchecktype # 产品送检方式,pr_pcbacount # 拼版数"; ma_code.FormName = Name; ma_code.SetValueField = new string[] { "ma_code", "ma_prodcode", "ma_qty", "pr_spec", "ma_softversion", "ma_salecode", "nvl(pr_sendchecktype,'LineCode')pr_sendchecktype", "pr_pcbacount" }; ma_code.Condition = "ma_statuscode='STARTED'"; ma_code.Focus(); } private void ma_code_DbChange(object sender, EventArgs e) { BaseUtil.SetFormValue(this.Controls, ma_code.ReturnData); string makeCode = ma_code.Text.Trim(); if (string.IsNullOrEmpty(makeCode)) return; workOrder.Text = makeCode; LoadMakeSummary(makeCode); } private void Confirm_Click(object sender, EventArgs e) { if (Confirm.Text == "确认") { if (string.IsNullOrEmpty(PanelQtyVal.Text)) { PanelQtyVal.Text = ""; ShowMsg(Msg1, 0, "请输入拼板数"); PanelQtyVal.Focus(); return; } if (!int.TryParse(PanelQtyVal.Text, out int qty) || qty <= 0) { PanelQtyVal.Text = ""; ShowMsg(Msg1, 0, "拼板数请输入正整数"); PanelQtyVal.Focus(); return; } if (!int.TryParse(BoxQtyVal.Text.Trim(), out int boxQty) || boxQty < 0) { ShowMsg(Msg1, 0, "当前箱容量请输入非负整数"); BoxQtyVal.Focus(); BoxQtyVal.SelectAll(); return; } panelQty = qty; BoxQtyVal.Text = boxQty.ToString(); Confirm.Text = "取消"; PanelQtyVal.Enabled = false; BoxQtyVal.Enabled = false; snVal.Enabled = true; snVal.Focus(); snVal.SelectAll(); } else if (Confirm.Text == "取消") { Confirm.Text = "确认"; panelQty = 0; PanelQtyVal.Enabled = true; BoxQtyVal.Enabled = true; snVal.Enabled = false; snVal.Text = ""; data.Rows.Clear(); UpdateSN("C"); PanelQtyVal.Focus(); PanelQtyVal.SelectAll(); } } private void snVal_KeyDown(object sender, KeyEventArgs e) { if (e.KeyCode != Keys.Enter) return; e.Handled = true; e.SuppressKeyPress = true; if (string.IsNullOrEmpty(ma_code.Text.Trim())) { ShowMsg(Msg1, 0, "请先选择工单"); ma_code.Focus(); return; } if (PanelQtyVal.Enabled || panelQty <= 0) { ShowMsg(Msg1, 0, "请先确认拼板数量"); return; } string scanSn = snVal.Text.Trim(); if (string.IsNullOrEmpty(scanSn)) { ShowMsg(Msg1, 0, "请扫描序列号"); snVal.Focus(); return; } if (data.Rows.Count >= panelQty) { ShowMsg(Msg1, 0, "已达到拼板数量"); snVal.Focus(); snVal.SelectAll(); return; } string snSql = scanSn.Replace("'", "''"); dt = (DataTable)dh.ExecuteSql($@"SELECT ms_sncode, ms_makecode FROM makeserial a WHERE a.ms_sncode = '{snSql}'", "select"); if (dt.Rows.Count > 0) { string snCode = dt.Rows[0]["ms_sncode"].ToString(); string makeCode = dt.Rows[0]["ms_makecode"].ToString(); string filterMake = ma_code.Text.Trim(); if (!string.IsNullOrEmpty(filterMake) && !string.Equals(filterMake, makeCode, StringComparison.OrdinalIgnoreCase)) { ShowMsg(Msg1, 0, "序列号不属于当前工单"); snVal.Focus(); snVal.SelectAll(); return; } foreach (DataRow row in data.Rows) { if (string.Equals(row["ms_sncode"].ToString(), snCode, StringComparison.OrdinalIgnoreCase)) { ShowMsg(Msg1, 0, "序列号已扫描"); snVal.Focus(); snVal.SelectAll(); return; } } if (!CheckCollectSN(snCode, makeCode)) { snVal.Focus(); snVal.SelectAll(); return; } data.Rows.Add(false, data.Rows.Count + 1, snCode, makeCode); UpdateSN("L", snCode); snVal.Text = ""; snVal.Focus(); if (data.Rows.Count >= panelQty) { ShowMsg(Msg1, 1, "拼板数量已扫满"); PanelFull(); } } else { ShowMsg(Msg1, 0, "序列号不存在"); UpdateSN("C"); snVal.Focus(); snVal.SelectAll(); } } /// /// 采集工序校验。不通过时已输出红色提示,调用处只需处理焦点。 /// private bool CheckCollectSN(string snCode, string makeCode) { if (!LogicHandler.CheckStepAttribute(Tag.ToString(), User.UserSourceCode, out ErrorMessage)) { ShowMsg(Msg1, 0, ErrorMessage); return false; } bool NoteAlready = LogicHandler.CheckDiffMakeCodeBeforeStepCheck(snCode, makeCode, true, out oMakeCode, out ErrorMessage); if (!NoteAlready) { ShowMsg(Msg1, 0, ErrorMessage); return false; } if (!LogicHandler.CheckStepSNAndMacode(oMakeCode, User.UserSourceCode, snCode, User.UserCode, out oMakeCode, out oMSID, out ErrorMessage)) { ShowMsg(Msg1, 0, ErrorMessage); return false; } if (!LogicHandler.CheckDiffMakeCodeAfterStepCheck(snCode, oMakeCode, true, NoteAlready, workOrder, out ErrorMessage)) { ShowMsg(Msg1, 0, ErrorMessage); return false; } if (workOrder.Text != oMakeCode && oMakeCode != null) { string makeSql = oMakeCode.Replace("'", "''"); dt = (DataTable)dh.ExecuteSql("select ma_code,ma_prodcode,ma_softversion,ma_salecode,pr_spec,nvl(pr_sendchecktype,'LineCode')pr_sendchecktype,ma_qty from make left join product on ma_prodcode=pr_code where ma_code='" + makeSql + "'", "select"); if (dt.Rows.Count > 0) { BaseUtil.SetFormValue(this.Controls, dt); workOrder.Text = dt.Rows[0]["ma_code"].ToString(); productCode.Text = dt.Rows[0]["ma_prodcode"].ToString(); productName.Text = dt.Rows[0]["pr_spec"].ToString(); LoadMakeSummary(workOrder.Text); } } string msIdSql = (oMSID ?? "").Replace("'", "''"); dt = (DataTable)dh.ExecuteSql("select ms_nextstepcode,ms_sncode,ms_reworkstatus,nvl(ms_ifrework,0)ms_ifrework,ms_stepcode,ms_status,nvl(st_ifrepair,0) st_ifrepair from makeserial left join step on ms_stepcode=st_code where ms_id='" + msIdSql + "'", "select"); if (dt.Rows.Count == 0) { ShowMsg(Msg1, 0, "未查询到序列号工序信息"); return false; } string status = dt.Rows[0]["ms_status"].ToString(); reworkstatus = dt.Rows[0]["ms_reworkstatus"].ToString(); string stepcode = dt.Rows[0]["ms_stepcode"].ToString(); string ifrepair = dt.Rows[0]["st_ifrepair"].ToString(); string ms_nextstepcode = dt.Rows[0]["ms_nextstepcode"].ToString(); string sncode = dt.Rows[0]["ms_sncode"].ToString(); if (sncode != snCode) { ShowMsg(Msg1, 0, snCode + " 序列号已执行过转号,不允许使用TSN采集"); return false; } ifrework = dt.Rows[0]["ms_ifrework"].ToString(); bool sameStep = stepcode == User.CurrentStepCode && ms_nextstepcode != User.CurrentStepCode && ifrepair == "0"; if (ifrework != "0" && sameStep && (reworkstatus == "1" || reworkstatus == "2")) { ShowMsg(Msg1, 0, snCode + " 序列号已执行过" + User.CurrentStepCode + "工序,采集结果为良品"); return false; } if (ifrework == "0" && sameStep && (status == "1" || status == "2")) { ShowMsg(Msg1, 0, snCode + " 序列号已执行过" + User.CurrentStepCode + "工序,采集结果为良品"); return false; } return true; } /// /// 拼板扫满后,表格中的序列号一次全部过站。 /// private void PanelFull() { dgv.EndEdit(); List rows = new List(); foreach (DataRow row in data.Rows) { if (row.RowState == DataRowState.Deleted) continue; rows.Add(row); } if (rows.Count == 0) { ShowMsg(Msg1, 0, "没有可过站的序列号"); return; } List successList = new List(); List afterList = new List(); List failList = new List(); List passedRows = new List(); foreach (DataRow row in rows) { string snCode = row["ms_sncode"].ToString(); string makeCode = row["ms_makecode"].ToString(); string stepError; if (!PassOneSN(snCode, makeCode, out stepError)) { failList.Add(string.IsNullOrEmpty(stepError) ? snCode : snCode + "(" + stepError + ")"); continue; } successList.Add(snCode); passedRows.Add(row); if (!string.IsNullOrEmpty(stepError) && stepError.IndexOf("AFTERSUCCESS", StringComparison.OrdinalIgnoreCase) >= 0) afterList.Add(snCode + " " + stepError); LogicHandler.DoCommandLog(Tag.ToString(), User.UserCode, makeCode, User.UserLineCode, User.UserSourceCode, "出货核对", "过站成功", snCode, ""); } foreach (DataRow row in passedRows) data.Rows.Remove(row); for (int i = 0; i < data.Rows.Count; i++) data.Rows[i]["rn"] = i + 1; if (successList.Count > 0 && failList.Count == 0) { int boxQty = 0; int.TryParse(BoxQtyVal.Text.Trim(), out boxQty); boxQty += successList.Count; BoxQtyVal.Text = boxQty.ToString(); ShowMsg(Msg1, 1, $"过站成功{successList.Count}条,序列号:{string.Join("、", successList)},当前箱容量:{boxQty}"); } else if (successList.Count > 0) { ShowMsg(Msg1, 1, $"过站成功{successList.Count}条,序列号:{string.Join("、", successList)}"); } foreach (string afterMsg in afterList) ShowMsg(Msg1, 2, afterMsg); if (failList.Count > 0) ShowMsg(Msg1, 0, $"过站失败{failList.Count}条,序列号:{string.Join("、", failList)}"); if (successList.Count > 0) LoadMakeSummary(workOrder.Text); if (snVal.Enabled) { snVal.Focus(); snVal.SelectAll(); } } /// /// 单条过站。失败原因写入 stepError,成功且带 AFTERSUCCESS 时 stepError 为附加信息。 /// private bool PassOneSN(string snCode, string makeCode, out string stepError) { stepError = ""; try { string snSql = (snCode ?? "").Replace("'", "''"); string makeSql = (makeCode ?? "").Replace("'", "''"); DataTable reworkDt = (DataTable)dh.ExecuteSql($@"SELECT nvl(ms_ifrework,0) ms_ifrework, ms_reworkstatus FROM makeserial WHERE ms_sncode='{snSql}' AND ms_makecode='{makeSql}'", "select"); if (reworkDt.Rows.Count == 0) { stepError = "未查询到序列号"; return false; } string rowIfRework = reworkDt.Rows[0]["ms_ifrework"].ToString(); string rowReworkStatus = reworkDt.Rows[0]["ms_reworkstatus"].ToString(); if (rowIfRework != "0" && rowReworkStatus == "3") { stepError = "返修不良必须先维修"; return false; } if (rowIfRework == "0") { DataTable badDt = (DataTable)dh.ExecuteSql($@"SELECT mb_id,bc_name,mbr_mbid FROM makebad LEFT JOIN makebadreason ON mbr_mbid=mb_id LEFT JOIN badcode ON mb_badcode=bc_code WHERE mb_sncode='{snSql}' AND mb_makecode='{makeSql}' AND mb_status=0", "select"); List badNames = new List(); for (int i = 0; i < badDt.Rows.Count; i++) { if (badDt.Rows[i]["mb_id"].ToString() != badDt.Rows[i]["mbr_mbid"].ToString()) badNames.Add("【" + badDt.Rows[i]["bc_name"].ToString() + "】"); } if (badNames.Count > 0) { stepError = "已判为不良品" + string.Join("", badNames); return false; } } if (!LogicHandler.SetStepResult(makeCode, User.UserSourceCode, snCode, "出货核对", "检测合格", User.UserCode, out stepError)) { if (string.IsNullOrEmpty(stepError) || stepError == "null") stepError = "过站失败"; return false; } if (stepError == "null") stepError = ""; return true; } catch (Exception ex) { stepError = ex.Message; return false; } } private void Delete_Click(object sender, EventArgs e) { dgv.EndEdit(); List removeRows = new List(); foreach (DataRow row in data.Rows) { if (row.RowState == DataRowState.Deleted) continue; if (row["isDel"] != DBNull.Value && Convert.ToBoolean(row["isDel"])) removeRows.Add(row); } if (removeRows.Count == 0) { ShowMsg(Msg1, 0, "请勾选要删除的序列号"); return; } List snList = new List(); foreach (DataRow row in removeRows) { snList.Add(row["ms_sncode"].ToString()); data.Rows.Remove(row); } for (int i = 0; i < data.Rows.Count; i++) data.Rows[i]["rn"] = i + 1; ShowMsg(Msg1, 1, $"已删除{removeRows.Count}条,序列号:{string.Join("、", snList)}"); if (snVal.Enabled) { snVal.Focus(); snVal.SelectAll(); } } private void dgv_CellClick(object sender, DataGridViewCellEventArgs e) { if (e.RowIndex < 0 || e.ColumnIndex < 0) return; var column = dgv.Columns[e.ColumnIndex]; if (column is DataGridViewCheckBoxColumn) { var cell = dgv[e.ColumnIndex, e.RowIndex] as DataGridViewCheckBoxCell; if (cell != null && !cell.ReadOnly) { bool currentValue = false; if (cell.Value != null && cell.Value != DBNull.Value) { currentValue = Convert.ToBoolean(cell.Value); } bool nextValue = !currentValue; cell.Value = nextValue; if (e.RowIndex < data.Rows.Count) data.Rows[e.RowIndex]["isDel"] = nextValue; dgv.CommitEdit(DataGridViewDataErrorContexts.Commit); dgv.EndEdit(); var row = dgv.Rows[e.RowIndex]; if (currentValue) { row.DefaultCellStyle.BackColor = dgv.DefaultCellStyle.BackColor; row.DefaultCellStyle.ForeColor = dgv.DefaultCellStyle.ForeColor; } else { row.DefaultCellStyle.BackColor = Color.LightSkyBlue; row.DefaultCellStyle.ForeColor = Color.Black; } } } } private void UpdateSN(string type, string sn = "") { if (type == "C") { serialNumber.Text = ""; workOrder.Text = ""; productCode.Text = ""; productName.Text = ""; makeQty.Text = ""; stepCollectQty.Text = ""; } else if (type == "L") { string snSql = sn.Replace("'", "''"); dt = (DataTable)dh.ExecuteSql($@"SELECT ms_sncode,ma_code,pr_code,pr_spec FROM makeserial,make,product WHERE ms_sncode = '{snSql}' AND ms_makecode = ma_code AND ms_prodcode = pr_code", "select"); if (dt.Rows.Count > 0) { serialNumber.Text = dt.Rows[0]["ms_sncode"].ToString(); workOrder.Text = dt.Rows[0]["ma_code"].ToString(); productCode.Text = dt.Rows[0]["pr_code"].ToString(); productName.Text = dt.Rows[0]["pr_spec"].ToString(); LoadMakeSummary(workOrder.Text); } else { UpdateSN("C", sn); } } } private void LoadMakeSummary(string makeCode) { makeQty.Text = ""; stepCollectQty.Text = ""; if (string.IsNullOrEmpty(makeCode)) return; string makeSql = makeCode.Replace("'", "''"); DataTable qtyDt = (DataTable)dh.ExecuteSql("select ma_qty from make where ma_code='" + makeSql + "'", "select"); if (qtyDt.Rows.Count > 0) makeQty.Text = qtyDt.Rows[0]["ma_qty"].ToString(); string stepCode = User.CurrentStepCode ?? ""; if (string.IsNullOrEmpty(stepCode)) return; string stepSql = stepCode.Replace("'", "''"); DataTable countDt = (DataTable)dh.ExecuteSql($@"SELECT COUNT(*) collect_qty FROM ( SELECT mp_sncode FROM makeprocess WHERE mp_makecode = '{makeSql}' AND mp_stepcode = '{stepSql}' GROUP BY mp_sncode)", "select"); if (countDt.Rows.Count > 0) stepCollectQty.Text = countDt.Rows[0]["collect_qty"].ToString(); } private void claerBtn_Click(object sender, EventArgs e) { Msg1.Clear(); } private void boxResetBtn_Click(object sender, EventArgs e) { BoxQtyVal.Text = "0"; ShowMsg(Msg1, 1, "当前箱容量已归零"); } private void ShowMsg(RichTextAutoBottom msgBox, int type, string msg) { msg = msg.Replace("\r", "").Replace("\n", ""); string msgTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); string showMsg = $"{msgTime}: {msg}\n"; if (type == 0) { msgBox.AppendText(showMsg, Color.Red); msgBox.SelectionStart = msgBox.Text.Length; msgBox.ScrollToCaret(); } else if (type == 1) { msgBox.AppendText(showMsg, Color.Green); msgBox.SelectionStart = msgBox.Text.Length; msgBox.ScrollToCaret(); } else if (type == 2) { msgBox.AppendText(showMsg, Color.YellowGreen); msgBox.SelectionStart = msgBox.Text.Length; msgBox.ScrollToCaret(); } } } }