接上一篇我们已经对混料生产工单自动下发基础函数封装完毕,现在模拟具体的生产场景。
在windows窗体应用程序WorkOrderDemo的默认Form1重命名为FormWorkOrderSimulation
用于【仿真模拟器】生产工单混料生产自动下发
一、窗体基本设计
1).自动下发工单仿真测试窗体FormWorkOrderSimulation设计器如图:
2).工单基本信息窗体FormWorkOrderBasic设计器如图:
3).工单生产方案窗体FormWorkOrderPlan设计器如图:
二、窗体相关代码【忽略设计器自动生成的事件和代码】
1)FormWorkOrderBasic.cs相关源程序
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WorkOrderDemo
{
public partial class FormWorkOrderBasic : Form
{
public FormWorkOrderBasic()
{
InitializeComponent();
//为列绑定数据库列名称
dgvData.AutoGenerateColumns = false;
dgvcCoreId.DataPropertyName = "CoreId";
dgvcWorkOrderCode.DataPropertyName = "WorkOrderCode";
dgvcWorkOrderName.DataPropertyName = "WorkOrderName";
dgvcWorkOrderCategory.DataPropertyName = "WorkOrderCategory";
dgvcWorkOrderPn.DataPropertyName = "WorkOrderPn";
dgvcOrderTotal.DataPropertyName = "WorkOrderTotal";
dgvcRemainderCount.DataPropertyName = "RemainderCount";
dgvcProcessEndTime.DataPropertyName = "ProcessEndTime";
}
/// <summary>
/// 基本输入验证
/// </summary>
/// <returns></returns>
private bool CheckInput()
{
if (txtWorkOrderCode.Text.Trim().Length == 0)
{
txtWorkOrderCode.Focus();
MessageBox.Show("工单编号不能为空", "出错");
return false;
}
int WorkOrderTotal;
if (!int.TryParse(txtWorkOrderTotal.Text, out WorkOrderTotal) || WorkOrderTotal <= 0)
{
txtWorkOrderTotal.Focus();
MessageBox.Show("工单总数不是正整数,请重新输入", "出错");
return false;
}
int RemainderCount;
if (!int.TryParse(txtRemainderCount.Text, out RemainderCount) || RemainderCount < 0)
{
txtRemainderCount.Focus();
MessageBox.Show("剩余数量不是正整数,请重新输入", "出错");
return false;
}
return true;
}
private void FormWorkOrderBasic_Load(object sender, EventArgs e)
{
try
{
DataTable dt = WorkOrderUtil.GetAllWorkOrderBasic();
dgvData.DataSource = dt;
}
catch (Exception ex)
{
string msg = $"读取工单基本信息失败!\n错误原因-【{ex.Message}】";
MessageBox.Show(msg, "读取工单信息");
}
}
private void btnSave_Click(object sender, EventArgs e)
{
if (!CheckInput())
{
return;
}
btnSave.Enabled = false;
try
{
WorkOrderBasic workOrderBasic = new WorkOrderBasic();
workOrderBasic.WorkOrderCode = txtWorkOrderCode.Text;
workOrderBasic.WorkOrderName = txtWorkOrderName.Text;
workOrderBasic.WorkOrderCategory = txtWorkOrderCategory.Text;
workOrderBasic.WorkOrderPn = txtWorkOrderPn.Text;
workOrderBasic.ProcessEndTime = DateTime.Now;
workOrderBasic.WorkOrderTotal = int.Parse(txtWorkOrderTotal.Text);
workOrderBasic.RemainderCount = int.Parse(txtRemainderCount.Text);
WorkOrderUtil.SaveWorkOrderBasic(workOrderBasic);
btnSave.Enabled = true;
string msg = $"保存工单基本信息完成!\n工单编号-【{txtWorkOrderCode.Text}】\n";
FormWorkOrderBasic_Load(null, null);
MessageBox.Show(msg, "保存工单结果");
}
catch (Exception ex)
{
btnSave.Enabled = true;
string msg = $"保存工单基本信息失败!\n错误原因-【{ex.Message}】";
MessageBox.Show(msg, "保存工单结果");
}
}
private void btnDelete_Click(object sender, EventArgs e)
{
string workOrderCode = txtWorkOrderCode.Text.Trim();
if (workOrderCode.Length == 0)
{
txtWorkOrderCode.Focus();
MessageBox.Show("工单编号不能为空", "出错");
return;
}
try
{
int result = WorkOrderUtil.DeleteWorkOrderBasic(workOrderCode);
if (result == -1)
{
MessageBox.Show($"工单正在被使用,无法删除\n工单编号-【{workOrderCode}】", "删除工单结果");
return;
}
string msg = $"删除工单基本信息完成!\n工单编号-【{workOrderCode}】\n";
FormWorkOrderBasic_Load(null, null);
MessageBox.Show(msg, "删除工单结果");
}
catch (Exception ex)
{
string msg = $"删除工单基本信息失败!\n错误原因-【{ex.Message}】";
MessageBox.Show(msg, "删除工单结果");
}
}
private void btnAddMaterial_Click(object sender, EventArgs e)
{
if (txtWorkOrderCodeUpdate.Text.Trim().Length == 0)
{
txtWorkOrderCodeUpdate.Focus();
MessageBox.Show("工单编号不能为空", "出错");
return;
}
int RemainderCount;
if (!int.TryParse(txtRemainderCountUpdate.Text, out RemainderCount) || RemainderCount < 0)
{
txtRemainderCountUpdate.Focus();
MessageBox.Show("剩余数量不是正整数,请重新输入", "出错");
return;
}
try
{
WorkOrderUtil.UpdateWorkOrderRemainder(txtWorkOrderCodeUpdate.Text.Trim(), RemainderCount);
string msg = $"更新工单剩余数量【库存】完成!\n工单编号-【{txtWorkOrderCodeUpdate.Text}】,当前数量【{RemainderCount}】\n";
FormWorkOrderBasic_Load(null, null);
MessageBox.Show(msg, "更新工单库存");
}
catch (Exception ex)
{
string msg = $"更新工单剩余数量【库存】失败!\n错误原因-【{ex.Message}】";
MessageBox.Show(msg, "更新工单库存");
}
}
private void dgvData_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
DataGridView gridView = sender as DataGridView;
int index = e.RowIndex;
if (index < 0 || index > gridView.RowCount - 1)
return;
txtWorkOrderCode.Text = gridView.Rows[index].Cells[1].Value.ToString();
txtWorkOrderName.Text = gridView.Rows[index].Cells[2].Value.ToString();
txtWorkOrderCategory.Text = gridView.Rows[index].Cells[3].Value.ToString();
txtWorkOrderPn.Text = gridView.Rows[index].Cells[4].Value.ToString();
txtWorkOrderTotal.Text = gridView.Rows[index].Cells[5].Value.ToString();
txtRemainderCount.Text = gridView.Rows[index].Cells[6].Value.ToString();
txtWorkOrderCodeUpdate.Text = gridView.Rows[index].Cells[1].Value.ToString();
txtRemainderCountUpdate.Text = gridView.Rows[index].Cells[6].Value.ToString();
}
private void dgvData_CellEnter(object sender, DataGridViewCellEventArgs e)
{
dgvData_CellContentClick(dgvData, e);
}
}
}
2)FormWorkOrderPlan.cs相关源程序
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WorkOrderDemo
{
public partial class FormWorkOrderPlan : Form
{
/// <summary>
/// 刷新当前工单和下一工单事件。第一个元组代表当前工单,第二个元组代表下一工单
/// </summary>
public event Action<Tuple<string, string, string, string>, Tuple<string, string, string, string>> EventRefreshWorkOrder;
public FormWorkOrderPlan()
{
InitializeComponent();
//周期工单数CycleCount
cboCycleCount.SelectedIndex = 3;//默认是AB
//只有工单编号可以编辑,其他列不可编辑
dgvc1.ReadOnly = true;//顺序号不可编辑
dgvc3.ReadOnly = true;
dgvc4.ReadOnly = true;
dgvc5.ReadOnly = true;
dgvc6.ReadOnly = true;
dgvc7.ReadOnly = true;
dgvData.AutoGenerateColumns = false;
dgvcCoreId.DataPropertyName = "CoreId";
dgvcPlanCode.DataPropertyName = "PlanCode";
dgvcPlanName.DataPropertyName = "PlanName";
dgvcPlanSequence.DataPropertyName = "PlanSequence";
dgvcOrderCode.DataPropertyName = "OrderCode";
dgvcOrderName.DataPropertyName = "OrderName";
dgvcWorkOrderCategory.DataPropertyName = "WorkOrderCategory";
dgvcWorkOrderPn.DataPropertyName = "WorkOrderPn";
dgvcOrderTotal.DataPropertyName = "OrderTotal";
dgvcRemainderCount.DataPropertyName = "RemainderCount";
dgvcProcessEndTime.DataPropertyName = "ProcessEndTime";
}
private void FormWorkOrderDistribution_Load(object sender, EventArgs e)
{
try
{
BindHistoryOrderToGridView();
ReadCurrentOrderPlan();
//加载完之后再触发索引改变事件
cboCycleCount.SelectedIndexChanged += CboCycleCount_SelectedIndexChanged;
}
catch (Exception ex)
{
string msg = $"读取历史生产方案失败!\n错误原因-【{ex.Message}】";
MessageBox.Show(msg, "读取历史工单");
}
}
private void CboCycleCount_SelectedIndexChanged(object sender, EventArgs e)
{
if (cboCycleCount.SelectedIndex == -1)
{
return;
}
dgvPlanDetail.Rows.Clear();
int cycleCount = Convert.ToInt32(cboCycleCount.SelectedItem);
for (int i = 0; i < cycleCount; i++)
{
dgvPlanDetail.Rows.Add(i + 1, "", "A", "XPXS", "123456-66666", "100", "100");
}
}
/// <summary>
/// 绑定历史生产工单到网格视图
/// </summary>
private void BindHistoryOrderToGridView()
{
DataTable dt = WorkOrderUtil.GetHistoryOrderPlan();
dgvData.DataSource = dt;
}
/// <summary>
/// 读取当前工单方案,也可以用于刷新工单剩余数量
/// 刷新显示剩余数量,当自动下发工单时,剩余数量刷新
/// </summary>
public void ReadCurrentOrderPlan()
{
List<WorkOrderPlanDetail> list = WorkOrderUtil.GetCurrentOrderPlan();
for (int i = 0; i < cboCycleCount.Items.Count; i++)
{
if (Convert.ToInt32(cboCycleCount.Items[i]) == list.Count)
{
cboCycleCount.SelectedIndex = i;
break;
}
}
dgvPlanDetail.Rows.Clear();
if (list.Count > 0)
{
txtPlanCode.Text = list[0].PlanCode;
txtPlanName.Text = list[0].PlanName;
for (int i = 0; i < list.Count; i++)
{
dgvPlanDetail.Rows.Add(i + 1, list[i].OrderCode, list[i].OrderName, list[i].WorkOrderCategory,
list[i].WorkOrderPn, list[i].OrderTotal, list[i].RemainderCount);
}
}
}
private void btnWorkOrderEdit_Click(object sender, EventArgs e)
{
FormWorkOrderBasic formWorkOrderBasic = new FormWorkOrderBasic();
formWorkOrderBasic.ShowDialog();
//刷新当前工单方案剩余工单数量
ReadCurrentOrderPlan();
WorkOrderUtil.RefreshCurrentAndNextWorkOrder(EventRefreshWorkOrder);
}
/// <summary>
/// 基本输入数据过滤
/// </summary>
/// <returns></returns>
private bool CheckInput()
{
if (cboCycleCount.SelectedIndex == -1 || dgvPlanDetail.Rows.Count == 0)
{
cboCycleCount.Focus();
MessageBox.Show("请选择工单周期数 以及 设定相应的工单信息", "异常");
return false;
}
List<string> listWorkOrder = new List<string>();
for (int i = 0; i < dgvPlanDetail.Rows.Count; i++)
{
string OrderCode = Convert.ToString(dgvPlanDetail.Rows[i].Cells["dgvc2"].Value);
string OrderName = Convert.ToString(dgvPlanDetail.Rows[i].Cells["dgvc3"].Value);
string OrderTotal = Convert.ToString(dgvPlanDetail.Rows[i].Cells["dgvc6"].Value);
string RemainderCount = Convert.ToString(dgvPlanDetail.Rows[i].Cells["dgvc7"].Value);
listWorkOrder.Add(OrderCode);
if (string.IsNullOrWhiteSpace(OrderCode))
{
dgvPlanDetail.Rows[i].Cells["dgvc2"].Selected = true;
MessageBox.Show("工单编号不能为空", "异常");
return false;
}
if (string.IsNullOrWhiteSpace(OrderName))
{
dgvPlanDetail.Rows[i].Cells["dgvc3"].Selected = true;
MessageBox.Show("工单标记不能为空", "异常");
return false;
}
int orderTotal;
int remainderCount;
if (!int.TryParse(OrderTotal, out orderTotal) || orderTotal < 0)
{
dgvPlanDetail.Rows[i].Cells["dgvc6"].Selected = true;
MessageBox.Show("工单总数必须是数字并且不小于0,请重新输入", "异常");
return false;
}
if (!int.TryParse(RemainderCount, out remainderCount) || remainderCount < 0)
{
dgvPlanDetail.Rows[i].Cells["dgvc7"].Selected = true;
MessageBox.Show("剩余数量必须是数字并且不小于0,请重新输入", "异常");
return false;
}
}
//工单编号必须存在
for (int i = 0; i < listWorkOrder.Count; i++)
{
string workOrderCode = listWorkOrder[i];
DataTable dt = WorkOrderUtil.GetWorkOrderBasic(workOrderCode);
if (dt == null || dt.Rows.Count == 0)
{
MessageBox.Show($"没有配置工单号【{workOrderCode}】的基本信息,请重新输入工单号", "异常");
return false;
}
}
return true;
}
/// <summary>
/// 当前选定单元格【工单编号】的编辑模式停止时发生。
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void dgvPlanDetail_CellEndEdit(object sender, DataGridViewCellEventArgs e)
{
if (e.RowIndex < 0 || e.ColumnIndex != 1)
{
//只编辑工单编号列
return;
}
string workOrderCode = Convert.ToString(dgvPlanDetail.Rows[e.RowIndex].Cells[1].Value);
DataTable dt = WorkOrderUtil.GetWorkOrderBasic(workOrderCode);
if (dt == null || dt.Rows.Count == 0)
{
dgvPlanDetail.Rows[e.RowIndex].Cells[1].Selected = true;
MessageBox.Show($"没有配置工单号【{workOrderCode}】的基本信息,请重新输入工单号", "异常");
return;
}
DataRow dataRow = dt.Rows[0];
dgvPlanDetail.Rows[e.RowIndex].Cells["dgvc3"].Value = dataRow["WorkOrderName"].ToString();
dgvPlanDetail.Rows[e.RowIndex].Cells["dgvc4"].Value = dataRow["WorkOrderCategory"].ToString();
dgvPlanDetail.Rows[e.RowIndex].Cells["dgvc5"].Value = dataRow["WorkOrderPn"].ToString();
dgvPlanDetail.Rows[e.RowIndex].Cells["dgvc6"].Value = dataRow["WorkOrderTotal"].ToString();
dgvPlanDetail.Rows[e.RowIndex].Cells["dgvc7"].Value = dataRow["RemainderCount"].ToString();
}
private void btnSetPlan_Click(object sender, EventArgs e)
{
if (!CheckInput())
{
return;
}
//自动设置生产方案代码、生产方案名称
List<string> listPlanCode = new List<string>();
for (int i = 0; i < dgvPlanDetail.Rows.Count; i++)
{
string OrderName = Convert.ToString(dgvPlanDetail.Rows[i].Cells["dgvc3"].Value);
listPlanCode.Add(OrderName);
}
txtPlanCode.Text = string.Join("-", listPlanCode);
//一个托盘有两个电芯
txtPlanName.Text = $"轮回工单个数【{int.Parse(cboCycleCount.Text)}】【{string.Join("-", listPlanCode)}】";
//周期工单数CycleCount
//WorkOrderPlanDetail详细表
//比如方案序号是【1,2,3,4】
//第一次【1】作为当前工单号 【2】作为预设工单号
//第二次【2】作为当前工单号 【3】作为预设工单号
//第三次【3】作为当前工单号 【4】作为预设工单号
//第四次【4】作为当前工单号 【1】作为预设工单号
//第五次 和 第一次 一样
btnSetPlan.Enabled = false;
try
{
WorkOrderPlan workOrderPlan = new WorkOrderPlan();
workOrderPlan.PlanCode = txtPlanCode.Text;
workOrderPlan.PlanName = txtPlanName.Text;
workOrderPlan.CycleCount = int.Parse(cboCycleCount.Text);
workOrderPlan.ProcessEndTime = DateTime.Now;
List<WorkOrderPlanDetail> workOrderPlanDetails = new List<WorkOrderPlanDetail>();
Queue<string> queue = new Queue<string>();
for (int i = 0; i < dgvPlanDetail.Rows.Count; i++)
{
queue.Enqueue(Convert.ToString(dgvPlanDetail.Rows[i].Cells["dgvc2"].Value));
WorkOrderPlanDetail workOrderPlanDetail = new WorkOrderPlanDetail();
workOrderPlanDetail.PlanSequence = i + 1;
workOrderPlanDetail.OrderCode = Convert.ToString(dgvPlanDetail.Rows[i].Cells["dgvc2"].Value);
workOrderPlanDetail.OrderName = Convert.ToString(dgvPlanDetail.Rows[i].Cells["dgvc3"].Value);
workOrderPlanDetail.WorkOrderCategory = Convert.ToString(dgvPlanDetail.Rows[i].Cells["dgvc4"].Value);
workOrderPlanDetail.WorkOrderPn = Convert.ToString(dgvPlanDetail.Rows[i].Cells["dgvc5"].Value);
workOrderPlanDetail.OrderTotal = Convert.ToInt32(dgvPlanDetail.Rows[i].Cells["dgvc6"].Value);
workOrderPlanDetail.RemainderCount = Convert.ToInt32(dgvPlanDetail.Rows[i].Cells["dgvc7"].Value);
workOrderPlanDetails.Add(workOrderPlanDetail);
}
WorkOrderUtil.EnableOrderPlan(workOrderPlan, workOrderPlanDetails);
btnSetPlan.Enabled = true;
string msg = $"设置当前生产方案【{txtPlanCode.Text}】成功!\n工单队列【{string.Join("-", queue)}】";
BindHistoryOrderToGridView();
WorkOrderUtil.RefreshCurrentAndNextWorkOrder(EventRefreshWorkOrder);
MessageBox.Show(msg, "设置当前生产方案");
}
catch (Exception ex)
{
btnSetPlan.Enabled = true;
string msg = $"设置当前生产方案失败!\n错误原因-【{ex.Message}】";
MessageBox.Show(msg, "设置当前生产方案");
}
}
private void btnReadPlan_Click(object sender, EventArgs e)
{
ReadCurrentOrderPlan();
}
private void btnSearchHistory_Click(object sender, EventArgs e)
{
try
{
BindHistoryOrderToGridView();
}
catch (Exception ex)
{
string msg = $"读取历史生产方案失败!\n错误原因-【{ex.Message}】";
MessageBox.Show(msg, "读取历史工单");
}
}
private void btnClearHistory_Click(object sender, EventArgs e)
{
DialogResult dialog = MessageBox.Show("您确定要一键清除历史工单方案?\n清除后,可适当优化【工单发放】性能!", "提示", MessageBoxButtons.YesNo, MessageBoxIcon.Information);
if (dialog != DialogResult.Yes)
{
return;
}
try
{
WorkOrderUtil.ClearHistoryOrderPlan();
BindHistoryOrderToGridView();
string msg = $"一键清除历史工单方案成功!";
MessageBox.Show(msg, "清除历史工单方案");
}
catch (Exception ex)
{
string msg = $"清除历史工单方案失败!\n错误原因-【{ex.Message}】";
MessageBox.Show(msg, "清除历史工单方案");
}
}
}
}
3)FormWorkOrderSimulation.cs相关源程序
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WorkOrderDemo
{
public partial class FormWorkOrderSimulation : Form
{
/// <summary>
/// 是否已启动线程
/// </summary>
bool isRun = false;
/// <summary>
/// 仿真任务:每隔5秒就自动下发一个工单。当某一个工单剩余数量为0时,自动停止
/// </summary>
Task task;
public FormWorkOrderSimulation()
{
InitializeComponent();
//初始化创建数据库
SqliteAssist.IniDataTable();
}
private void FormWorkOrderSimulation_Load(object sender, EventArgs e)
{
//读取当前工单和下一工单
WorkOrderUtil.RefreshCurrentAndNextWorkOrder(EventProcess_EventRefreshWorkOrder);
}
private void btnStartSimulation_Click(object sender, EventArgs e)
{
isRun = !isRun;
SetButtonStatus(isRun);
task = Task.Factory.StartNew(() =>
{
while (isRun)
{
try
{
DisplayInfo($"【请求工单和预设工单】触发:开始处理释放工单事务...");
string errMsg;
DataTable dtSequence;
bool result = WorkOrderUtil.GetNextAndPresetWorkOrder(out errMsg, out dtSequence);
if (!result || dtSequence == null)
{
DisplayInfo($"【请求工单和预设工单】发送工单失败,出现错误 或 无法获取当前工单.{errMsg}");
isRun = false;
SetButtonStatus(isRun);
return;
}
//有两行,当前工单 和 下一个预设工单
if (dtSequence.Rows.Count != 2)
{
DisplayInfo($"【请求工单和预设工单】发送工单失败,当前工单 和 预设工单的记录总数不是两行,实际【{dtSequence.Rows.Count }】行数据");
isRun = false;
SetButtonStatus(isRun);
return;
}
DataRow drSequence = dtSequence.Rows[0];
DataRow drPreset = dtSequence.Rows[1];
string WorkOrderCode = drSequence["OrderCode"].ToString();
string RemainderCount = drSequence["RemainderCount"].ToString();
string PlanSequence = drSequence["PlanSequence"].ToString();
string WorkOrderCategory = drSequence["WorkOrderCategory"].ToString();
//预设工单信息
string NextWorkOrderCode = drPreset["OrderCode"].ToString();
string NextRemainderCount = drPreset["RemainderCount"].ToString();
string NextPlanSequence = drPreset["PlanSequence"].ToString();
string NextWorkOrderCategory = drPreset["WorkOrderCategory"].ToString();
DisplayInfo($"【请求工单和预设工单】操作成功,当前工单号【{WorkOrderCode}】,剩余数量【{RemainderCount}】,顺序号【{PlanSequence}】,产品类型【{WorkOrderCategory}】");
DisplayInfo($"【请求工单和预设工单】操作成功,下一工单号【{NextWorkOrderCode}】,剩余数量【{NextRemainderCount}】,顺序号【{NextPlanSequence}】,产品类型【{NextWorkOrderCategory}】");
//刷新前台界面
EventProcess_EventRefreshWorkOrder(Tuple.Create(WorkOrderCode, RemainderCount, PlanSequence, WorkOrderCategory), Tuple.Create(NextWorkOrderCode, NextRemainderCount, NextPlanSequence, NextWorkOrderCategory));
}
catch (Exception ex)
{
DisplayInfo($"【请求工单和预设工单】出现异常【{ex.Message}】");
isRun = false;
SetButtonStatus(isRun);
return;
}
Thread.Sleep(5000);
}
});
}
FormWorkOrderPlan formWorkOrderPlan;
private void btnEditPlan_Click(object sender, EventArgs e)
{
if (isRun)
{
MessageBox.Show("请先停止下发工单线程,方可编辑工单生产方案", "非法操作");
return;
}
if (formWorkOrderPlan == null || formWorkOrderPlan.IsDisposed)
{
formWorkOrderPlan = new FormWorkOrderPlan();
formWorkOrderPlan.EventRefreshWorkOrder -= EventProcess_EventRefreshWorkOrder;
formWorkOrderPlan.EventRefreshWorkOrder += EventProcess_EventRefreshWorkOrder;
formWorkOrderPlan.Show();
}
else
{
formWorkOrderPlan.Activate();
}
}
/// <summary>
/// 显示文本框的消息
/// </summary>
/// <param name="message"></param>
private void DisplayInfo(string message)
{
this.BeginInvoke(new Action(() =>
{
if (rtxbResult.TextLength >= 20480)
{
rtxbResult.Clear();
}
rtxbResult.AppendText($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")} --> {message}\n");
rtxbResult.ScrollToCaret();
}));
}
private void SetButtonStatus(bool isRunning)
{
this.BeginInvoke(new Action(() =>
{
if (isRunning)
{
btnStartSimulation.Text = "停止工单下发(仿真)";
DisplayInfo($"【下发工单】线程已启动...");
}
else
{
btnStartSimulation.Text = "启动工单下发(仿真)";
DisplayInfo($"【下发工单】线程已停止...");
}
}));
}
/// <summary>
/// 刷新当前工单和下一工单,同时刷新工单剩余数量【工单生产方案界面】
/// </summary>
/// <param name="tupleCurrentWorkOrder">当前工单方案信息</param>
/// <param name="tupleNextWorkOrder">下一工单方案信息</param>
private void EventProcess_EventRefreshWorkOrder(Tuple<string, string, string, string> tupleCurrentWorkOrder, Tuple<string, string, string, string> tupleNextWorkOrder)
{
try
{
this.BeginInvoke(new Action(() =>
{
txtCurrentOrder.Text = tupleCurrentWorkOrder.Item1;
txtRemainderCount.Text = tupleCurrentWorkOrder.Item2;
txtPlanSequence.Text = tupleCurrentWorkOrder.Item3;
txtWorkOrderCategory.Text = tupleCurrentWorkOrder.Item4;
txtNextOrder.Text = tupleNextWorkOrder.Item1;
txtNextRemainderCount.Text = tupleNextWorkOrder.Item2;
txtNextPlanSequence.Text = tupleNextWorkOrder.Item3;
txtNextWorkOrderCategory.Text = tupleNextWorkOrder.Item4;
formWorkOrderPlan?.ReadCurrentOrderPlan();
}));
}
catch (Exception ex)
{
MessageBox.Show($"当前工单刷新错误:{ex.Message}");
}
}
private void FormWorkOrderSimulation_FormClosing(object sender, FormClosingEventArgs e)
{
if (isRun)
{
DialogResult dialog = MessageBox.Show("下发工单线程进行中!您确定要关闭该应用程序吗?", "警告", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Warning);
if (dialog != DialogResult.Yes)
{
e.Cancel = true;
return;
}
}
//线程标记清除
isRun = false;
task?.Wait(5000);
Application.Exit();
}
}
}
三、程序运行效果如图:
1).设置新方案
2).启动工单下发
3).无法下发工单时,自动停止。
此时可以重新设置工单计划 或者 修改库存剩余数量(上料)