异常情况兜底不中断信号流程
This commit is contained in:
@@ -152,6 +152,18 @@ namespace MesWork
|
|||||||
|
|
||||||
return !string.IsNullOrWhiteSpace(productNo);
|
return !string.IsNullOrWhiteSpace(productNo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 业务资料异常时只记录兜底日志,PLC交互仍尽量继续,避免现场流程被MES辅助数据卡住。
|
||||||
|
/// </summary>
|
||||||
|
private void LogWeighingFallback(string opName, string productNo, string flowName, string reason, long AID)
|
||||||
|
{
|
||||||
|
string safeProductNo = string.IsNullOrWhiteSpace(productNo) ? "未知产品" : productNo;
|
||||||
|
string msg = $"【{opName}】兜底放行:产品={safeProductNo},流程={flowName},原因={reason}";
|
||||||
|
B_DB_Opera.SaveLog_Response(msg, AID);
|
||||||
|
WeighingPage?.AppendLog($"[{opName}] {msg}");
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 处理请求工作信号 (tagTypeCodeID=44)
|
/// 处理请求工作信号 (tagTypeCodeID=44)
|
||||||
/// 流程:读取工件信息 → 查询参数 → 写过站记录 → 按类型处理称重记录 → 回写允许工作
|
/// 流程:读取工件信息 → 查询参数 → 写过站记录 → 按类型处理称重记录 → 回写允许工作
|
||||||
@@ -166,6 +178,7 @@ namespace MesWork
|
|||||||
string modelNo = PLC_R.GetString_CleanGarbled(ReadPLC(11, opName)); // 机型号
|
string modelNo = PLC_R.GetString_CleanGarbled(ReadPLC(11, opName)); // 机型号
|
||||||
string orderNo = PLC_R.GetString_CleanGarbled(ReadPLC(39, opName)); // 工单号
|
string orderNo = PLC_R.GetString_CleanGarbled(ReadPLC(39, opName)); // 工单号
|
||||||
string palletNo = PLC_R.GetString_CleanGarbled(ReadPLC(80, opName)); // 托盘号
|
string palletNo = PLC_R.GetString_CleanGarbled(ReadPLC(80, opName)); // 托盘号
|
||||||
|
string rawCodeBlock = engineNo;
|
||||||
// 解析代码串格式: 0/DHN2.5Q0219-36/D426E016767 或 DHH02K0014-400/B726E00584555
|
// 解析代码串格式: 0/DHN2.5Q0219-36/D426E016767 或 DHH02K0014-400/B726E00584555
|
||||||
if (TryConvertCodeBlockData(engineNo, out string parsedOrderNo, out string parsedProductNo))
|
if (TryConvertCodeBlockData(engineNo, out string parsedOrderNo, out string parsedProductNo))
|
||||||
{
|
{
|
||||||
@@ -180,8 +193,10 @@ namespace MesWork
|
|||||||
out decimal residualOilUpperLimit, out decimal residualOilLowerLimit)) // 根据订货号 查询基本参数
|
out decimal residualOilUpperLimit, out decimal residualOilLowerLimit)) // 根据订货号 查询基本参数
|
||||||
{
|
{
|
||||||
WritePLC_IF(112, opName, 3); // 报警代码=3,机型错误
|
WritePLC_IF(112, opName, 3); // 报警代码=3,机型错误
|
||||||
B_DB_Opera.SaveLog_Response($"【{opName}】工件管理中未找到订货号[{orderNo}]的匹配规则,发动机={engineNo}", AID);
|
LogWeighingFallback(opName, engineNo, "请求工作", $"订货号[{orderNo}]未匹配到工件参数,使用PLC机型[{modelNo}]继续允许工作", AID);
|
||||||
WeighingPage?.AppendLog($"[{opName}] 订货号[{orderNo}]未匹配到工件参数");
|
// 兜底机制:参数资料缺失不再卡PLC,请求保存时若无法正常更新记录会生成异常完成记录。
|
||||||
|
WritePLC_IF(66, opName, true);
|
||||||
|
CurveCollector_Start(opName, engineNo, modelNo);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
modelNo = matchedModelNo;
|
modelNo = matchedModelNo;
|
||||||
@@ -199,9 +214,7 @@ namespace MesWork
|
|||||||
if (!B_DB_Opera.QueryWeighingBeforeOil(engineNo, out _, out decimal preWeight, out _, out _, out _))
|
if (!B_DB_Opera.QueryWeighingBeforeOil(engineNo, out _, out decimal preWeight, out _, out _, out _))
|
||||||
{
|
{
|
||||||
WritePLC_IF(112, opName, 3);
|
WritePLC_IF(112, opName, 3);
|
||||||
B_DB_Opera.SaveLog_Response($"【{opName}】未找到发动机[{engineNo}]的空中称重记录", AID);
|
LogWeighingFallback(opName, engineNo, "请求工作-放油后", "未找到放油前记录,继续允许工作,保存时按异常放油后记录处理", AID);
|
||||||
WeighingPage?.AppendLog($"[{opName}] 未找到[{engineNo}]放油前记录,进站失败");
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -223,8 +236,11 @@ namespace MesWork
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
WritePLC_IF(112, opName, 1); // 报警代码=1,获取数据失败
|
WritePLC_IF(112, opName, 1); // 报警代码=1,获取数据失败
|
||||||
B_DB_Opera.SaveLog_Response($"【{opName}】码块数据转换失败:原始码值=[{engineNo}]", AID);
|
engineNo = string.IsNullOrWhiteSpace(rawCodeBlock) ? $"未知产品_{opName}_{DateTime.Now:yyyyMMddHHmmss}" : rawCodeBlock.Trim();
|
||||||
WeighingPage?.AppendLog($"[{opName}] 码块数据转换失败:{engineNo}");
|
LogWeighingFallback(opName, engineNo, "请求工作", $"码块数据转换失败,原始码值=[{rawCodeBlock}],仍允许工作", AID);
|
||||||
|
// 兜底机制:产品解析失败时仍给允许工作,后续保存阶段会按异常产品记录并判不合格。
|
||||||
|
WritePLC_IF(66, opName, true);
|
||||||
|
CurveCollector_Start(opName, engineNo, modelNo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception err)
|
catch (Exception err)
|
||||||
@@ -251,6 +267,11 @@ namespace MesWork
|
|||||||
{
|
{
|
||||||
engineNo = parsedProductNo;
|
engineNo = parsedProductNo;
|
||||||
}
|
}
|
||||||
|
else if (string.IsNullOrWhiteSpace(engineNo))
|
||||||
|
{
|
||||||
|
engineNo = $"未知产品_{opName}_{DateTime.Now:yyyyMMddHHmmss}";
|
||||||
|
LogWeighingFallback(opName, engineNo, "请求保存", "保存时产品编号为空,使用临时产品号继续保存", AID);
|
||||||
|
}
|
||||||
|
|
||||||
if (CurveCollector_TryGetStableWeight(opName, out decimal curveWeight, out int curvePointCount, out string curveMsg))
|
if (CurveCollector_TryGetStableWeight(opName, out decimal curveWeight, out int curvePointCount, out string curveMsg))
|
||||||
{
|
{
|
||||||
@@ -263,7 +284,9 @@ namespace MesWork
|
|||||||
decimal rawWeight = plcWeight;
|
decimal rawWeight = plcWeight;
|
||||||
if (!WeightCalibrationHelper.Apply(opName, rawWeight, out decimal calibratedWeight, out string calibrationFormula, out string calibrationMsg))
|
if (!WeightCalibrationHelper.Apply(opName, rawWeight, out decimal calibratedWeight, out string calibrationFormula, out string calibrationMsg))
|
||||||
{
|
{
|
||||||
throw new Exception($"工具标定公式处理失败:{calibrationMsg}");
|
LogWeighingFallback(opName, engineNo, "请求保存", $"工具标定公式处理失败:{calibrationMsg},使用PLC原始重量继续保存", AID);
|
||||||
|
calibrationFormula = "未标定兜底";
|
||||||
|
calibratedWeight = rawWeight;
|
||||||
}
|
}
|
||||||
weight = calibratedWeight;
|
weight = calibratedWeight;
|
||||||
B_DB_Opera.SaveLog_Response($"【{opName}】PLC锁定重量标定:原始重量={rawWeight:F3}kg,公式={calibrationFormula},标定后={weight:F3}kg", AID);
|
B_DB_Opera.SaveLog_Response($"【{opName}】PLC锁定重量标定:原始重量={rawWeight:F3}kg,公式={calibrationFormula},标定后={weight:F3}kg", AID);
|
||||||
@@ -280,8 +303,9 @@ namespace MesWork
|
|||||||
if (weighType == "地面")
|
if (weighType == "地面")
|
||||||
{
|
{
|
||||||
// 地面:查最新记录 → 放油量=重量/密度 → 标记完成
|
// 地面:查最新记录 → 放油量=重量/密度 → 标记完成
|
||||||
B_DB_Opera.QueryLatestRecord(opName, engineNo,
|
if (B_DB_Opera.QueryLatestRecord(opName, engineNo,
|
||||||
out long recordId, out _, out decimal addOil, out decimal extractOil, out decimal dens);
|
out long recordId, out _, out decimal addOil, out decimal extractOil, out decimal dens))
|
||||||
|
{
|
||||||
curveWeighingRecordId = recordId; // 曲线记录最终关联这条称重记录
|
curveWeighingRecordId = recordId; // 曲线记录最终关联这条称重记录
|
||||||
oilReleaseQty = dens > 0 ? weight / dens : 0; // 地面:油桶重量/密度=放油量
|
oilReleaseQty = dens > 0 ? weight / dens : 0; // 地面:油桶重量/密度=放油量
|
||||||
residualOilQty = addOil - extractOil - oilReleaseQty; // 残油=加油-抽油-放油
|
residualOilQty = addOil - extractOil - oilReleaseQty; // 残油=加油-抽油-放油
|
||||||
@@ -292,11 +316,23 @@ namespace MesWork
|
|||||||
WeighingPage?.UpdateOilResult(WeighingPage?.GetStationIndex(opName) ?? 1, oilReleaseQty, residualOilQty);
|
WeighingPage?.UpdateOilResult(WeighingPage?.GetStationIndex(opName) ?? 1, oilReleaseQty, residualOilQty);
|
||||||
WeighingPage?.AppendLog($"[{opName}] 保存完成:{engineNo},重量={weight:F2}kg,放油量={oilReleaseQty:F4}L");
|
WeighingPage?.AppendLog($"[{opName}] 保存完成:{engineNo},重量={weight:F2}kg,放油量={oilReleaseQty:F4}L");
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// 兜底机制:请求工作阶段资料异常可能没有占位记录,保存时补一条异常完成记录,避免PLC等不到保存完成。
|
||||||
|
curveWeighingRecordId = B_DB_Opera.InsertWeighingRecord(opName, "地面", engineNo, "", "", "",
|
||||||
|
0, weight, 0, 0, 0, 0, 0, 0, 0, 2, waterContent,
|
||||||
|
opName, Curr_UserName, isComplete: 1);
|
||||||
|
finalQualityFlag = 2;
|
||||||
|
qualityMsg = "未找到请求工作占位记录,已按异常地面记录保存";
|
||||||
|
LogWeighingFallback(opName, engineNo, "请求保存-地面", qualityMsg, AID);
|
||||||
|
}
|
||||||
|
}
|
||||||
else if (weighType == "放油前")
|
else if (weighType == "放油前")
|
||||||
{
|
{
|
||||||
// 空中放油前:查最新记录 → 仅写入进站重量,不标记完成
|
// 空中放油前:查最新记录 → 仅写入进站重量,不标记完成
|
||||||
B_DB_Opera.QueryLatestRecord(opName, engineNo,
|
if (B_DB_Opera.QueryLatestRecord(opName, engineNo,
|
||||||
out long recordId, out _, out _, out _, out _);
|
out long recordId, out _, out _, out _, out _))
|
||||||
|
{
|
||||||
curveWeighingRecordId = recordId; // 放油前曲线也关联同一条称重记录
|
curveWeighingRecordId = recordId; // 放油前曲线也关联同一条称重记录
|
||||||
B_DB_Opera.UpdateWeighingComplete(recordId, "空中放油前", opName,
|
B_DB_Opera.UpdateWeighingComplete(recordId, "空中放油前", opName,
|
||||||
weight, 0, 0, waterContent, out finalQualityFlag, out qualityMsg);
|
weight, 0, 0, waterContent, out finalQualityFlag, out qualityMsg);
|
||||||
@@ -304,6 +340,17 @@ namespace MesWork
|
|||||||
$"【{opName}】空中放油前保存完成:发动机={engineNo},进站重量={weight}kg,合格标志={finalQualityFlag},{qualityMsg}", AID);
|
$"【{opName}】空中放油前保存完成:发动机={engineNo},进站重量={weight}kg,合格标志={finalQualityFlag},{qualityMsg}", AID);
|
||||||
WeighingPage?.AppendLog($"[{opName}] 放油前保存:{engineNo},重量={weight:F2}kg");
|
WeighingPage?.AppendLog($"[{opName}] 放油前保存:{engineNo},重量={weight:F2}kg");
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// 兜底机制:没有占位记录时补异常记录并完成握手,后续放油后仍可按异常链路继续。
|
||||||
|
curveWeighingRecordId = B_DB_Opera.InsertWeighingRecord(opName, "空中", engineNo, "", "", "",
|
||||||
|
weight, 0, 0, 0, 0, 0, 0, 0, 0, 2, waterContent,
|
||||||
|
opName, Curr_UserName, isComplete: 1);
|
||||||
|
finalQualityFlag = 2;
|
||||||
|
qualityMsg = "未找到请求工作占位记录,已按异常放油前记录保存";
|
||||||
|
LogWeighingFallback(opName, engineNo, "请求保存-放油前", qualityMsg, AID);
|
||||||
|
}
|
||||||
|
}
|
||||||
else // 放油后
|
else // 放油后
|
||||||
{
|
{
|
||||||
// 空中放油后:查最新放油前记录(无论是否完成),计算放油量更新到该记录
|
// 空中放油后:查最新放油前记录(无论是否完成),计算放油量更新到该记录
|
||||||
|
|||||||
@@ -38,14 +38,13 @@ namespace MesWork.Pages
|
|||||||
dgv_Data.Columns.Add(new DataGridViewTextBoxColumn { Name = "发动机号", HeaderText = "发动机号", DataPropertyName = "发动机号", FillWeight = 100 });
|
dgv_Data.Columns.Add(new DataGridViewTextBoxColumn { Name = "发动机号", HeaderText = "发动机号", DataPropertyName = "发动机号", FillWeight = 100 });
|
||||||
dgv_Data.Columns.Add(new DataGridViewTextBoxColumn { Name = "机型号", HeaderText = "机型号", DataPropertyName = "机型号", FillWeight = 80 });
|
dgv_Data.Columns.Add(new DataGridViewTextBoxColumn { Name = "机型号", HeaderText = "机型号", DataPropertyName = "机型号", FillWeight = 80 });
|
||||||
dgv_Data.Columns.Add(new DataGridViewTextBoxColumn { Name = "订单号", HeaderText = "订单号", DataPropertyName = "订单号", FillWeight = 80 });
|
dgv_Data.Columns.Add(new DataGridViewTextBoxColumn { Name = "订单号", HeaderText = "订单号", DataPropertyName = "订单号", FillWeight = 80 });
|
||||||
dgv_Data.Columns.Add(new DataGridViewTextBoxColumn { Name = "称重类型", HeaderText = "称重类型", DataPropertyName = "称重类型", FillWeight = 70 });
|
|
||||||
dgv_Data.Columns.Add(new DataGridViewTextBoxColumn { Name = "托盘号", HeaderText = "托盘号", DataPropertyName = "托盘号", FillWeight = 60 });
|
|
||||||
dgv_Data.Columns.Add(new DataGridViewTextBoxColumn { Name = "进站重量", HeaderText = "进站重量(KG)", DataPropertyName = "进站重量", FillWeight = 80 });
|
dgv_Data.Columns.Add(new DataGridViewTextBoxColumn { Name = "进站重量", HeaderText = "进站重量(KG)", DataPropertyName = "进站重量", FillWeight = 80 });
|
||||||
dgv_Data.Columns.Add(new DataGridViewTextBoxColumn { Name = "离站重量", HeaderText = "离站重量(KG)", DataPropertyName = "离站重量", FillWeight = 80 });
|
dgv_Data.Columns.Add(new DataGridViewTextBoxColumn { Name = "离站重量", HeaderText = "离站重量(KG)", DataPropertyName = "离站重量", FillWeight = 80 });
|
||||||
dgv_Data.Columns.Add(new DataGridViewTextBoxColumn { Name = "加油量", HeaderText = "加油量", DataPropertyName = "加油量", FillWeight = 60 });
|
dgv_Data.Columns.Add(new DataGridViewTextBoxColumn { Name = "加油量", HeaderText = "加油量", DataPropertyName = "加油量", FillWeight = 60 });
|
||||||
dgv_Data.Columns.Add(new DataGridViewTextBoxColumn { Name = "抽油量", HeaderText = "抽油量", DataPropertyName = "抽油量", FillWeight = 60 });
|
dgv_Data.Columns.Add(new DataGridViewTextBoxColumn { Name = "抽油量", HeaderText = "抽油量", DataPropertyName = "抽油量", FillWeight = 60 });
|
||||||
dgv_Data.Columns.Add(new DataGridViewTextBoxColumn { Name = "放油量", HeaderText = "放油量", DataPropertyName = "放油量", FillWeight = 70 });
|
dgv_Data.Columns.Add(new DataGridViewTextBoxColumn { Name = "放油量", HeaderText = "放油量", DataPropertyName = "放油量", FillWeight = 70 });
|
||||||
dgv_Data.Columns.Add(new DataGridViewTextBoxColumn { Name = "残留量", HeaderText = "残留量", DataPropertyName = "残留量", FillWeight = 60 });
|
dgv_Data.Columns.Add(new DataGridViewTextBoxColumn { Name = "残留量", HeaderText = "残留量", DataPropertyName = "残留量", FillWeight = 60 });
|
||||||
|
dgv_Data.Columns.Add(new DataGridViewTextBoxColumn { Name = "残油量上下限", HeaderText = "残油量上下限", DataPropertyName = "残油量上下限", FillWeight = 90 });
|
||||||
dgv_Data.Columns.Add(new DataGridViewTextBoxColumn { Name = "油密度", HeaderText = "油密度", DataPropertyName = "油密度", FillWeight = 60 });
|
dgv_Data.Columns.Add(new DataGridViewTextBoxColumn { Name = "油密度", HeaderText = "油密度", DataPropertyName = "油密度", FillWeight = 60 });
|
||||||
dgv_Data.Columns.Add(new DataGridViewTextBoxColumn { Name = "合格标志", HeaderText = "合格", DataPropertyName = "合格标志", FillWeight = 50 });
|
dgv_Data.Columns.Add(new DataGridViewTextBoxColumn { Name = "合格标志", HeaderText = "合格", DataPropertyName = "合格标志", FillWeight = 50 });
|
||||||
dgv_Data.Columns.Add(new DataGridViewTextBoxColumn { Name = "操作员", HeaderText = "操作员", DataPropertyName = "操作员", FillWeight = 60 });
|
dgv_Data.Columns.Add(new DataGridViewTextBoxColumn { Name = "操作员", HeaderText = "操作员", DataPropertyName = "操作员", FillWeight = 60 });
|
||||||
@@ -81,7 +80,11 @@ namespace MesWork.Pages
|
|||||||
itemCountParam
|
itemCountParam
|
||||||
};
|
};
|
||||||
SqlOperation.ExecuteStoredProcedure("称重记录_分页查询", parms, out DataTable dt, out string err);
|
SqlOperation.ExecuteStoredProcedure("称重记录_分页查询", parms, out DataTable dt, out string err);
|
||||||
if (dt != null) dgv_Data.DataSource = dt;
|
if (dt != null)
|
||||||
|
{
|
||||||
|
AddResidualOilLimitColumn(dt);
|
||||||
|
dgv_Data.DataSource = dt;
|
||||||
|
}
|
||||||
_pager.UpdateState(pageCountParam, itemCountParam);
|
_pager.UpdateState(pageCountParam, itemCountParam);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
@@ -90,6 +93,53 @@ namespace MesWork.Pages
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 将残油量上下限合并为报表显示列。
|
||||||
|
/// </summary>
|
||||||
|
private void AddResidualOilLimitColumn(DataTable dt)
|
||||||
|
{
|
||||||
|
if (!dt.Columns.Contains("残油量上下限"))
|
||||||
|
{
|
||||||
|
dt.Columns.Add("残油量上下限", typeof(string));
|
||||||
|
}
|
||||||
|
if (dt.Columns.Contains("残留量"))
|
||||||
|
{
|
||||||
|
dt.Columns["残油量上下限"].SetOrdinal(dt.Columns["残留量"].Ordinal + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (DataRow row in dt.Rows)
|
||||||
|
{
|
||||||
|
row["残油量上下限"] = $"{FormatLimit(row, "残油量下限")}~{FormatLimit(row, "残油量上限")}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private string FormatLimit(DataRow row, string columnName)
|
||||||
|
{
|
||||||
|
if (!row.Table.Columns.Contains(columnName) || row[columnName] == DBNull.Value)
|
||||||
|
{
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (decimal.TryParse(row[columnName].ToString(), out decimal value))
|
||||||
|
{
|
||||||
|
return value.ToString("0.###");
|
||||||
|
}
|
||||||
|
|
||||||
|
return row[columnName].ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RemoveHiddenExportColumns(DataTable dt)
|
||||||
|
{
|
||||||
|
string[] hiddenColumns = { "称重类型", "托盘号", "残油量上限", "残油量下限" };
|
||||||
|
foreach (string columnName in hiddenColumns)
|
||||||
|
{
|
||||||
|
if (dt.Columns.Contains(columnName))
|
||||||
|
{
|
||||||
|
dt.Columns.Remove(columnName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 导出 Excel(重新查询全量数据后导出)
|
/// 导出 Excel(重新查询全量数据后导出)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -126,6 +176,8 @@ namespace MesWork.Pages
|
|||||||
|
|
||||||
if (dt != null && dt.Rows.Count > 0)
|
if (dt != null && dt.Rows.Count > 0)
|
||||||
{
|
{
|
||||||
|
AddResidualOilLimitColumn(dt);
|
||||||
|
RemoveHiddenExportColumns(dt);
|
||||||
bool exported = NPOITest.ExeclHelper.DataTableToExcel(dt, "称重记录", sfd.FileName);
|
bool exported = NPOITest.ExeclHelper.DataTableToExcel(dt, "称重记录", sfd.FileName);
|
||||||
if (exported)
|
if (exported)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user