using System; using System.Collections.Generic; using System.Net.NetworkInformation; using System.Text; using System.Linq; using System.Data; using System.Data.Common; using System.Threading; using Mesnac.Action.Base; using Mesnac.Controls.Base; using System.Windows.Forms; using Mesnac.Codd.Session; using System.IO; using Mesnac.Action.Feeding.Socket; using Mesnac.Action.Feeding.FeedingPlc; using Mesnac.Action.Feeding.Sys; namespace Mesnac.Action.Feeding.ProducingPlan { #region 当班计划——窗体加载,即初始化操作 /// /// 当班计划——窗体加载 /// public class DutyPlanInit : FeedingAction , IAction { public static bool IsFirstRun = true; private DbMCControl _serverGridControl = null; public void Run(RuntimeParameter runtime) { base.RunIni(runtime); if (DutyPlanInit.IsFirstRun) { //首次执行订阅,刷新插件事件 Mesnac.Gui.Workbench.WorkbenchSingleton.Workbench.AfterRefreshPlugIn += delegate(object sender, System.EventArgs e) { SysVersionController.OnVersionChange -= new EventHandler(SysVersionController_OnVersionChange); DutyPlanInit.IsFirstRun = true; }; //首次执行,订阅版本切换事件 SysVersionController.OnVersionChange += new EventHandler(SysVersionController_OnVersionChange); DutyPlanInit.IsFirstRun = false; } base.LogDebug("当班计划——窗体加载,即初始化操作"); PlanCommon.IsInit = false; #region 初始化班次数据 string source = string.Empty; DbMCControl planDateControl = this.GetDbMCControlByKey(Mesnac.Basic.DataSourceFactory.MCDbType.Local, "[ppt_plan].[down_date]").FirstOrDefault(); DbMCControl pptShiftControl = this.GetDbMCControlByKey(Mesnac.Basic.DataSourceFactory.MCDbType.Local, "PptShift").FirstOrDefault(); DbMCControl pptClassControl = this.GetDbMCControlByKey(Mesnac.Basic.DataSourceFactory.MCDbType.Local, "PptClass").FirstOrDefault(); DbMCControl serverGridControl = this.GetDbMCControlByKey(Mesnac.Basic.DataSourceFactory.MCDbType.Server, "PptPlan").FirstOrDefault(); DbMCControl clientGridControl = this.GetDbMCControlByKey(Mesnac.Basic.DataSourceFactory.MCDbType.Local, "ppt_plan").FirstOrDefault(); //DbMCControl pptUserIDControl = this.GetDbMCControlByKey(Mesnac.Basic.DataSourceFactory.MCDbType.local, "UserID").FirstOrDefault(); //Control pptUserIDControl = this.GetAllFormControlById("LastUserID").FirstOrDefault(); //Control pptUserNameControl = this.GetAllFormControlById("LastUserName").FirstOrDefault(); this._serverGridControl = serverGridControl; if (planDateControl == null) { base.LogError("{当班计划-窗体加载} 缺少日期选择控件..."); return; } if (pptShiftControl == null) { base.LogError("{当班计划-窗体加载} 缺少班次组合框控件..."); return; } //if (pptUserIDControl == null) //{ // return; //} if (serverGridControl != null) { DataGridView serverGrid = (serverGridControl.BaseControl as DataGridView); if (serverGrid != null) { PlanCommon.SetDataGridViewStyle(serverGrid); //设置网格样式 if (base.NetType == NetTypes.Local) { if (serverGrid.Parent != null && !(serverGrid.Parent.Parent is Form)) { serverGrid.Parent.Visible = false; } else { serverGridControl.BaseControl.MCVisible = false; //单机版隐藏网络计划控件 } } //双击时取消选择行(取消高亮显示) serverGrid.CellDoubleClick += delegate(object sender, DataGridViewCellEventArgs e) { if (serverGrid.Rows != null && serverGrid.Rows.Count > 0) { foreach (DataGridViewRow row in serverGrid.Rows) { row.Selected = false; } } }; serverGrid.VisibleChanged += delegate(object sender, EventArgs e) { PlanCommon.SetBackColor(serverGrid); }; PlanCommon.SetBackColor(serverGrid); } } if (clientGridControl != null) { DataGridView clientGrid = (clientGridControl.BaseControl as DataGridView); if (clientGrid != null) { PlanCommon.SetDataGridViewStyle(clientGrid); //设置网格样式 //双击时取消选择行(取消高亮显示) clientGrid.CellDoubleClick += delegate(object sender, DataGridViewCellEventArgs e) { if (clientGrid.Rows != null && clientGrid.Rows.Count > 0) { foreach (DataGridViewRow row in clientGrid.Rows) { row.Selected = false; } } }; clientGrid.VisibleChanged += delegate(object sender, EventArgs e) { PlanCommon.SetBackColor(clientGrid); }; PlanCommon.SetBackColor(clientGrid); } } //((TextBox)pptUserIDControl).Text = base.GetConfigValue("LastUserID", "0"); //((Label)pptUserNameControl).Text = base.GetConfigValue("LastUserName", "0"); DbHelper dbHelper = NewDbHelper(pptShiftControl.DesignSource); if (dbHelper==null) { return; } dbHelper.ClearParameter(); dbHelper.CommandType = CommandType.Text; string sqlstr = "SELECT * FROM [PptShift]"; dbHelper.CommandText = sqlstr; DataTable table = dbHelper.ToDataTable(); pptShiftControl.BaseControl.BindDataSource = table; dbHelper.ClearParameter(); dbHelper.CommandType = CommandType.Text; sqlstr = "SELECT * FROM [PptClass]"; dbHelper.CommandText = sqlstr; pptClassControl.BaseControl.BindDataSource = dbHelper.ToDataTable(); PlanLog log = PlanCommon.PlanLog; if (log != null) { //如果记录了上次执行计划的时间和班次,则把日期和班次设置为上次的值 planDateControl.BaseControl.MCValue = log.LastSelectDate; pptShiftControl.BaseControl.MCValue = log.LastSelectShiftID; } //DateTime plandate = DateTime.Now; //int shiftitem = 0; //string Msg = string.Empty; //PlanCommon.PlanDateVerify(out plandate, out shiftitem, planDateControl.BaseControl.MCValue.ToString(), Convert.ToInt32(pptShiftControl.BaseControl.MCValue.ToString()), out Msg); //ShowMsg(Msg, Language(1), MessageBoxButtons.OK, MessageBoxIcon.Information); //planDateControl.BaseControl.MCValue = plandate; //pptShiftControl.BaseControl.MCValue = shiftitem.ToString(); //单机版 //if (base.NetType == NetTypes.Local) //{ // List dbMcControls = base.GetAllDbMCControls(); //} PlanCommon.IsInit = true; #endregion } protected void SysVersionController_OnVersionChange(object sender, EventArgs e) { if (this._serverGridControl != null && this._serverGridControl.BaseControl != null) { DataGridView serverGrid = this._serverGridControl.BaseControl as DataGridView; if (base.NetType == NetTypes.Net) { #region 设置网络计划的可见性 if (serverGrid != null) { if (serverGrid.Parent != null && serverGrid.Parent is Panel) { serverGrid.Parent.Visible = true; } } else { this._serverGridControl.BaseControl.MCVisible = true; } base.SetNetControlVisible(); #endregion } else { //如果是单机版,则隐藏网络计划网格控件和“刷新”、“选择接收”、“全部接收”按钮 if (serverGrid != null) { if (serverGrid.Parent != null && serverGrid.Parent is Panel) { serverGrid.Parent.Visible = false; } } else { this._serverGridControl.BaseControl.MCVisible = false; } base.SetNetControlVisible(); } } } } #endregion #region 当班计划——“刷新”网络计划、本机台计划 /// /// 当班计划——刷新网络计划 /// public class RefreshServerPlan : FeedingAction, IAction { private static bool IsFirstRun = true; //是否首次执行 public void Run(RuntimeParameter runtime) { base.RunIni(runtime); if (IsFirstRun) { #region 事件订阅 //首次执行订阅存盘信号完成事件 FinishBatch.SaveFinishBatch.OnFinishBatchSave += delegate(object sender, EventArgs e) { this.Run(runtime); }; //接收到客户端刷新计划的Socket指令时刷新计划 StartReciveProcess.OnRefreshPlan += delegate(object sender, EventArgs e) { this.Run(runtime); }; //暂停计划时,刷新网络计划 PausePlan.OnRefreshPlan += delegate(object sender, EventArgs e) { this.Run(runtime); }; //执行计划完毕,刷新网络计划 ExecutePlan.OnRefreshPlan += delegate(object sender, EventArgs e) { this.Run(runtime); }; //删除计划后,要刷新网络计划 DeletePlan.OnRefreshPlan += delegate(object sender, EventArgs e) { this.Run(runtime); }; //修改计划后,要刷新网络计划 ModifyPlan.OnRefreshPlan += delegate(object sender, EventArgs e) { this.Run(runtime); }; //修改次数后,要刷新网络计划 ModifyPlanNum.OnRefreshPlan += delegate(object sender, EventArgs e) { this.Run(runtime); }; #endregion IsFirstRun = false; } DbMCControl shiftControl = null; DbMCControl planDateControl = null; DbMCControl serverGridControl = null; #region 根据网络库连接状况自动切换版本 //判断是否由于断网导致系统自动切换的单机版 if (base.NetType == BaseAction.NetTypes.Local && base.OriginalNetType == BaseAction.NetTypes.Net) { if (PlanCommon.IsCanConnectServer()) { base.SetGlobalNetType(Mesnac.Action.Base.BaseAction.NetTypes.Net); ICSharpCode.Core.LoggingService.Warn("网络库连接成功,由临时单机转为网络版运行!"); } } else if (base.NetType == BaseAction.NetTypes.Net) //如果是网络版,则判断网络库是否能够连接上,连接不上,自动转为临时单机 { if (!PlanCommon.IsCanConnectServer()) { base.SetGlobalNetType(Mesnac.Action.Base.BaseAction.NetTypes.Local); ICSharpCode.Core.LoggingService.Warn("刷新网络计划失败:连接网络库失败,转为单机版运行!"); } } #endregion shiftControl = this.GetDbMCControlByKey(Mesnac.Basic.DataSourceFactory.MCDbType.Local, "PptShift").FirstOrDefault(); planDateControl = this.GetDbMCControlByKey(Mesnac.Basic.DataSourceFactory.MCDbType.Local, "[ppt_plan].[down_date]").FirstOrDefault(); serverGridControl = this.GetDbMCControlByKey(Mesnac.Basic.DataSourceFactory.MCDbType.Server, "PptPlan").FirstOrDefault(); if (base.NetType == NetTypes.Net) { base.LogDebug("当班计划——“刷新”网络计划"); if (shiftControl == null) { base.LogError("缺少班次控件...(班次控件为组合框,数据源要绑定PptShift)"); return; } if (planDateControl == null) { base.LogError("缺少日期控件...(日期控件为日历,数据源要绑定down_date)"); return; } if (serverGridControl == null) { base.LogError("缺少网络计划网格控件..."); return; } int shiftID = 0; int.TryParse(shiftControl.BaseControl.MCValue.ToString(), out shiftID); string equipCode = base.CurrEquipCode; //当前机台 string selectedDate = String.Format("{0:yyyyMMdd}", Convert.ToDateTime(planDateControl.BaseControl.MCValue)); //日期 try { DbHelper dbHelper = NewDbHelper(Mesnac.Basic.DataSourceFactory.MCDbType.Server); if (dbHelper == null) { return; } dbHelper.ClearParameter(); dbHelper.CommandType = CommandType.Text; //查询符合条件的网络计划(查询条件PlanState>=2、指定机台、指定日期、指定班次) string sqlstr = " select Plan_ID PlanID,Plan_Num PlanNum,CONVERT(VARCHAR(100),Real_Num) AS RealNum,Mater_code RecipeMaterialCode,Mater_Name RecipeMaterialName,Plan_State PlanState,Edt_code RecipeVersionID from [Ppt_Plan] where Plan_State>=2 and Equip_code=@RecipeEquipCode and CONVERT(varchar,cast(Plan_Date as datetime),112)=@PlanDate and Shift_ID=@ShiftID"; dbHelper.AddParameter("@RecipeEquipCode", equipCode); dbHelper.AddParameter("@PlanDate", selectedDate); dbHelper.AddParameter("@ShiftID", shiftID); dbHelper.CommandText = sqlstr; DataTable table = dbHelper.ToDataTable(); lock (String.Empty) { if (serverGridControl != null && serverGridControl.BaseControl != null) { serverGridControl.BaseControl.BindDataSource = null; serverGridControl.BaseControl.BindDataSource = table; #region 根据计划状态处理背景色 DataGridView serverGrid = serverGridControl.BaseControl as DataGridView; if (serverGrid != null) { if (serverGrid.Parent != null && serverGrid.Parent is Panel) { serverGrid.Parent.Visible = true; } } else { serverGridControl.BaseControl.MCVisible = true; } base.SetNetControlVisible(); PlanCommon.SetBackColor(serverGrid); #endregion } else { ICSharpCode.Core.LoggingService.Warn("刷新网络计划失败:网络计划控件为Null..."); } } } catch (Exception ex) { ICSharpCode.Core.LoggingService.Error("刷新网络计划失败:" + ex.Message); } } else { //如果是单机版,则隐藏网络计划网格控件和“刷新”、“选择接收”、“全部接收”按钮 if (serverGridControl != null) { DataGridView serverGrid = serverGridControl.BaseControl as DataGridView; if (serverGrid != null) { if (serverGrid.Parent != null && serverGrid.Parent is Panel) { serverGrid.Parent.Visible = false; } } else { serverGridControl.BaseControl.MCVisible = false; } base.SetNetControlVisible(); } } } } /// /// 当班计划——刷新本机台计划 /// public class RefreshClientPlan : FeedingAction, IAction { /// /// 刷新计划事件 /// public static event EventHandler OnRefreshPlan; private static bool IsFirstRun = true; //是否首次执行 public void Run(RuntimeParameter runtime) { base.RunIni(runtime); if (IsFirstRun) { #region 事件订阅 //首次执行订阅存盘信号完成事件 FinishBatch.SaveFinishBatch.OnFinishBatchSave += delegate(object sender, EventArgs e) { this.Run(runtime); }; //接收到客户端刷新计划的Socket指令时刷新计划 StartReciveProcess.OnRefreshPlan += delegate(object sender, EventArgs e) { this.Run(runtime); }; //暂停计划时,刷新本地计划 PausePlan.OnRefreshPlan += delegate(object sender, EventArgs e) { this.Run(runtime); }; //执行计划完毕,刷新本地计划 ExecutePlan.OnRefreshPlan += delegate(object sender, EventArgs e) { this.Run(runtime); }; //删除计划后,要刷新本地计划 DeletePlan.OnRefreshPlan += delegate(object sender, EventArgs e) { this.Run(runtime); }; //修改计划后,要刷新本地计划 ModifyPlan.OnRefreshPlan += delegate(object sender, EventArgs e) { this.Run(runtime); }; //修改次数数后,要刷新本地计划 ModifyPlanNum.OnRefreshPlan += delegate(object sender, EventArgs e) { this.Run(runtime); }; //移动计划后,要刷新本地计划 MoveUpPlan.OnMovePlan += delegate(object sender, EventArgs e) { this.Run(runtime); }; //接收计划后,要刷新本地计划 ReceiveSelectPlan.OnReceivePlan += delegate(object sender, EventArgs e) { this.Run(runtime); }; #endregion IsFirstRun = false; } #region 业务实现 base.LogDebug("当班计划——“刷新”本机台计划"); DbMCControl shiftControl = this.GetDbMCControlByKey(Mesnac.Basic.DataSourceFactory.MCDbType.Local, "PptShift").FirstOrDefault(); DbMCControl planDateControl = this.GetDbMCControlByKey(Mesnac.Basic.DataSourceFactory.MCDbType.Local, "[ppt_plan].[down_date]").FirstOrDefault(); DbMCControl clientGridControl = this.GetDbMCControlByKey(Mesnac.Basic.DataSourceFactory.MCDbType.Local, "ppt_plan").FirstOrDefault(); if (shiftControl == null) { base.LogError("缺少班次控件...(班次控件为组合框,数据源要绑定PptShift)"); return; } if (planDateControl == null) { base.LogError("缺少日期控件...(日期控件为日历,数据源要绑定down_date)"); return; } if (clientGridControl == null) { base.LogError("缺少本机台计划网格控件..."); return; } int shiftID = 0; int.TryParse(shiftControl.BaseControl.MCValue.ToString(), out shiftID); string equipCode = base.CurrEquipCode; //当前机台 string selectedDate = String.Format("{0:yyyyMMdd}", Convert.ToDateTime(planDateControl.BaseControl.MCValue)); //日期 DbHelper dbHelper = NewDbHelper(Mesnac.Basic.DataSourceFactory.MCDbType.Local); if (dbHelper == null) { return; } dbHelper.ClearParameter(); dbHelper.CommandType = CommandType.Text; //查询符合条件的本地计划(查询条件:机台、日期、班次) //string sqlstr = "select RecipeMaterialName,RecipeMaterialCode,PlanNum,CONVERT(VARCHAR(100),RealNum) AS RealNum,PlanID,PlanState from [PptPlan] where RecipeEquipCode=@RecipeEquipCode and CONVERT(varchar,PlanDate,112)=@PlanDate and ShiftID=@ShiftID order by ActionOrder"; string sqlstr = "select recipe_code as RecipeMaterialName,mater_code as RecipeMaterialCode,plan_num as PlanNum,CONVERT(VARCHAR(100),real_num) AS RealNum,plan_id as PlanID,plan_state as PlanState,edt_code as RecipeVersionID from [ppt_plan] where equip_code=@RecipeEquipCode and CONVERT(varchar,down_date,112)=@PlanDate and shift=@ShiftID order by ActionOrder"; dbHelper.AddParameter("@RecipeEquipCode", equipCode); dbHelper.AddParameter("@PlanDate", selectedDate); dbHelper.AddParameter("@ShiftID", shiftID); dbHelper.CommandText = sqlstr; DataTable table = dbHelper.ToDataTable(); lock (String.Empty) { if (clientGridControl != null && clientGridControl.BaseControl != null) { clientGridControl.BaseControl.BindDataSource = null; clientGridControl.BaseControl.BindDataSource = table; #region 根据计划状态处理背景色 DataGridView clientGrid = clientGridControl.BaseControl as DataGridView; PlanCommon.SetBackColor(clientGrid); #endregion } else { ICSharpCode.Core.LoggingService.Warn("刷新本地计划失败:本地计划控件为Null..."); } } #endregion #region 触发客户端计划刷新事件 if (RefreshClientPlan.OnRefreshPlan != null) { RefreshClientPlan.OnRefreshPlan(runtime, System.EventArgs.Empty); } #endregion } } /// /// 缓存查询条件-计划生产日期、班次 /// public class CacheCondition : FeedingAction, IAction { public void Run(RuntimeParameter runtime) { if (PlanCommon.IsInit == false || PlanCommon.IsShift == true) return; //如果未初始化则中断当前业务 base.RunIni(runtime); base.LogDebug("缓存查询条件-计划生产日期、班次"); DbMCControl shiftControl = this.GetDbMCControlByKey(Mesnac.Basic.DataSourceFactory.MCDbType.Local, "PptShift").FirstOrDefault(); DbMCControl classControl = this.GetDbMCControlByKey(Mesnac.Basic.DataSourceFactory.MCDbType.Local, "PptClass").FirstOrDefault(); DbMCControl planDateControl = this.GetDbMCControlByKey(Mesnac.Basic.DataSourceFactory.MCDbType.Local, "[ppt_plan].[down_date]").FirstOrDefault(); if (shiftControl == null) { base.LogError("缺少班次控件...(班次控件为组合框,数据源要绑定PptShift)"); return; } if (planDateControl == null) { base.LogError("缺少日期控件...(日期控件为日历,数据源要绑定down_date)"); return; } PlanLog planLog = PlanCommon.PlanLog; if (planLog == null) { planLog = new PlanLog(); } DateTime lastSelectDate = DateTime.Now; int lastSelectShiftID = 0; int lastClassID = 0; DateTime.TryParse(planDateControl.BaseControl.MCValue.ToString(), out lastSelectDate); planLog.LastSelectDate = lastSelectDate; int.TryParse(shiftControl.BaseControl.MCValue.ToString(), out lastSelectShiftID); if (classControl == null) { if (base.NetType == NetTypes.Net) { lastClassID = PlanCommon.GetClassID(Basic.DataSourceFactory.MCDbType.Server, 1, lastSelectDate, lastSelectShiftID); } } else { int.TryParse(classControl.BaseControl.MCValue.ToString(), out lastClassID); } planLog.LastSelectShiftID = lastSelectShiftID; planLog.LastPlanID = planLog.LastPlanID; planLog.LastClassID = lastClassID; PlanCommon.PlanLog = planLog; } } #region 执行计划日期校验 public class PlanDateVerify : FeedingAction, IAction { public void Run(RuntimeParameter runtime) { base.RunIni(runtime); DbMCControl planDateControl = this.GetDbMCControlByKey(Mesnac.Basic.DataSourceFactory.MCDbType.Local, "[PptPlan].[PlanDate]").FirstOrDefault(); DbMCControl pptShiftControl = this.GetDbMCControlByKey(Mesnac.Basic.DataSourceFactory.MCDbType.Local, "PptShift").FirstOrDefault(); if (planDateControl == null) { base.LogError("{当班计划-窗体加载} 缺少日期选择控件..."); return; } if (pptShiftControl == null) { base.LogError("{当班计划-窗体加载} 缺少班次组合框控件..."); return; } DateTime plandate = DateTime.Now; int shiftitem = 0; string Msg = string.Empty; PlanCommon.PlanDateVerify(out plandate, out shiftitem, planDateControl.BaseControl.MCValue.ToString(), Convert.ToInt32(pptShiftControl.BaseControl.MCValue.ToString()), out Msg); if (Msg != string.Empty) { MessageBox.Show(Msg); planDateControl.BaseControl.MCValue = plandate; pptShiftControl.BaseControl.MCValue = shiftitem.ToString(); } } } #endregion #endregion #region 当班计划——“选择接收” 网络计划 /// /// 当班计划——“选择接收”网络计划 /// public class ReceiveSelectPlan : FeedingAction, IAction { /// /// 接受计划事件 /// public static event EventHandler OnReceivePlan; public virtual void Run(RuntimeParameter runtime) { base.RunIni(runtime); //单机版,隐藏选择接收按钮 if (runtime.Sender != null && base.NetType == NetTypes.Local) { (runtime.Sender as IBaseControl).MCVisible = false; return; } this.ReceivePlan(runtime, false); } #region 接收网络计划业务处理 /// /// 接收网络计划业务处理 /// /// /// /// /// 是否接收所有网络计划 public void ReceivePlan(RuntimeParameter runtime, bool isAll) { List errorList = new List(); base.LogDebug("当班计划——“选择接收”网络计划"); DbMCControl pptShiftControl = this.GetDbMCControlByKey(Mesnac.Basic.DataSourceFactory.MCDbType.Local, "PptShift").FirstOrDefault(); DbMCControl planDateControl = this.GetDbMCControlByKey(Mesnac.Basic.DataSourceFactory.MCDbType.Local, "[ppt_plan].[down_date]").FirstOrDefault(); DbMCControl serverGridControl = this.GetDbMCControlByKey(Mesnac.Basic.DataSourceFactory.MCDbType.Server, "PptPlan").FirstOrDefault(); //获取网络计划网格控件 DbMCControl clientGridControl = this.GetDbMCControlByKey(Mesnac.Basic.DataSourceFactory.MCDbType.Local, "ppt_plan").FirstOrDefault(); //获取本机台计划网格控件 #region 控件存在验证 if (planDateControl == null) { base.LogError("{当班计划-窗体加载} 缺少日期选择控件..."); return; } if (pptShiftControl == null) { base.LogError("{当班计划-窗体加载} 缺少班次组合框控件..."); return; } if (serverGridControl == null) { base.LogError("{当班计划——“选择接收”网络计划}缺少网络计划网格控件..."); return; } if (clientGridControl == null) { base.LogError("{当班计划——“选择接收”网络计划}缺少本机台计划网格控件..."); return; } #endregion #region 获取选中的网络计划ID string planIds = String.Empty; DataGridView serverGridView = serverGridControl.BaseControl as DataGridView; if (serverGridView == null) { base.LogError("网络计划网格控件类型错误,控件无法转换为DataGridView..."); return; } if (isAll) { //如果是接收所有计划 foreach (DataGridViewRow row in serverGridView.Rows) { string planId = String.Empty; if (!(row.Cells["PlanID"].Value == null || System.DBNull.Value == row.Cells["PlanID"].Value)) { planId = row.Cells["PlanID"].Value.ToString(); } if (!String.IsNullOrEmpty(planId)) { planIds = String.IsNullOrEmpty(planIds) ? "'" + planId + "'" : planIds + ",'" + planId + "'"; } } } else { //如果是接收选中的计划 if (serverGridView.SelectedRows.Count > 0) { foreach (DataGridViewRow row in serverGridView.SelectedRows) { string planId = String.Empty; if (!(row.Cells["PlanID"].Value == null || System.DBNull.Value == row.Cells["PlanID"].Value)) { planId = row.Cells["PlanID"].Value.ToString(); } if (!String.IsNullOrEmpty(planId)) { planIds = String.IsNullOrEmpty(planIds) ? "'" + planId + "'" : planIds + ",'" + planId + "'"; } } } } #endregion if (!String.IsNullOrEmpty(planIds)) { bool successFlag = false; //是否有计划成功接收的标志,如果有成功接收的计划则发送网络消息 #region 查询符合条件的网络计划 DbHelper dbHelperServer = NewDbHelper(Mesnac.Basic.DataSourceFactory.MCDbType.Server); if (dbHelperServer == null) { return; } dbHelperServer.ClearParameter(); dbHelperServer.CommandType = CommandType.Text; string sqlStr1 = @"select Plan_id PlanID, Plan_date PlanDate, Equip_code RecipeEquipCode, Mater_code RecipeMaterialCode, Mater_Name RecipeMaterialName, Edt_code RecipeVersionID, User_Edtcode RecipeUserVersion , Shift_id ShiftID, Shift_class ClassID, Serial_num SerialNum, Pri_level PriLevel, recipe_code RecipeName, Recipe_Type RecipeType, Run_Type RunType, Print_Type PrintType , Plan_Source PlanSource, Total_weight TotalWeight, Plan_num PlanNum, Plan_weight PlanWeight, Real_num RealNum, Real_weight RealWeight, Urgency_state UrgencyState , Plan_state PlanState, Oper_datetime OperDatetime, Plan_EndTime PlanEndTime, Real_StartTime RealStartTime, Real_Endtime RealEndtime, Oper_code OperCode, revise_sgn ReviseSgn , XLcreate SmallCreate, MonthSerial AvgTime, Memo Remark from ppt_plan where Plan_ID in({0})"; sqlStr1 = String.Format(sqlStr1, planIds); dbHelperServer.CommandText = sqlStr1; DataTable fromTable = dbHelperServer.ToDataTable(); #endregion #region 向本地数据库追加选中的网络计划 //追加计划时,把本地计划的PlanState DbHelper dbHelperClient = NewDbHelper(Mesnac.Basic.DataSourceFactory.MCDbType.Local); if (dbHelperClient == null) { return; } foreach (DataRow row in fromTable.Rows) { #region 检测网络计划是否允许本地接收 //检测网络计划是否允许本地接收(只有PlanState的值为2、3,并且RealNum 小于 PlanNum的计划才允许本机接收) //PlanState 4-正在生产 5-已完成 都不允许下载 int planState = row["PlanState"] == null || row["PlanState"] == System.DBNull.Value ? 0 : Convert.ToInt32(row["PlanState"]); //获取计划状态 int planNum = row["PlanNum"] == null || row["PlanNum"] == System.DBNull.Value ? 0 : Convert.ToInt32(row["PlanNum"]); //设定值 int realNum = row["RealNum"] == null || row["RealNum"] == System.DBNull.Value ? 0 : Convert.ToInt32(row["RealNum"]); //完成值 if (realNum >= planNum) { errorList.Add(String.Format(Language(101), row["PlanID"])); continue; } if (planState == 4) { errorList.Add(String.Format(Language(102), row["PlanID"])); continue; } if (planState == 5) { errorList.Add(String.Format(Language(101), row["PlanID"])); continue; } #endregion #region 接收计划 bool result = PlanCommon.RecivePlan(dbHelperServer, dbHelperClient, row, base.CurrEquipCode, Convert.ToDateTime(row["PlanDate"]), Convert.ToInt32(row["ShiftID"])); if (result == true) { successFlag = true; } #endregion } if (successFlag) { //发送网络消息 PlanCommon.SendNetPlanMsg(base.CurrEquipCode, Convert.ToDateTime(planDateControl.BaseControl.MCValue), Convert.ToInt32(pptShiftControl.BaseControl.MCValue), PlanCommon.PlanLog.LastClassID, base.GetConfigValue("LastUserID", "0")); } #endregion #region 在本机台网格控件中显示本机台计划 //new RefreshClientPlan().Run(runtime); if (ReceiveSelectPlan.OnReceivePlan != null) { ReceiveSelectPlan.OnReceivePlan(runtime, System.EventArgs.Empty); } #endregion #region 下载该计划的配方数据 if (base.NetType == NetTypes.Net) { string[] planIdArr = planIds.Split(new char[]{','}); foreach(string pid in planIdArr) { new BasicInfo.NetRecipe().GetRecipeByPlanID(pid.Replace("'", String.Empty)); } } #endregion } //显示错误提示 PlanCommon.ShowErrorList(errorList); } #endregion } #endregion #region 当班计划——“全部接收”网络计划 /// /// 当班计划——“全部接收”网络计划 /// public class ReceiveAllPlan : ReceiveSelectPlan { public override void Run(RuntimeParameter runtime) { base.RunIni(runtime); //单机版,隐藏全部接收按钮 if (runtime.Sender != null && base.NetType == NetTypes.Local) { (runtime.Sender as IBaseControl).MCVisible = false; return; } base.ReceivePlan(runtime, true); } } #endregion #region 当班计划——“修改”本机台计划 只修改份数-计划数 /// /// 当班计划——“修改”本机台计划 /// public class ModifyPlan : FeedingAction, IAction { #region 事件定义 /// /// 刷新计划事件 /// public static event EventHandler OnRefreshPlan; #endregion private DbMCControl _clientGridControl = null; private RuntimeParameter _runtime; public void Run(RuntimeParameter runtime) { base.RunIni(runtime); this._runtime = runtime; DbMCControl clientGridControl = this.GetDbMCControlByKey(Mesnac.Basic.DataSourceFactory.MCDbType.Local, "ppt_plan").FirstOrDefault(); //获取本机台计划网格控件 if (clientGridControl == null) { base.LogError("{当班计划——“修改”本机台计划}缺少本机台计划网格控件..."); return; } this._clientGridControl = clientGridControl; this.DoWork(); } /// /// 修改计划 /// protected void DoWork() { List errorList = null; this._runtime.BaseControl.MCEnabled = false; DataGridView clientGridView = this._clientGridControl.BaseControl as DataGridView; if (clientGridView == null) { base.LogError("{当班计划——“修改”本机台计划}网格控件类型错误..."); return; } if (clientGridView.SelectedRows.Count == 1) { DataGridViewRow row1 = clientGridView.SelectedRows[0]; string planID = row1.Cells["PlanID"].Value as string; //获取要修改的计划号 DataRow row = PlanCommon.GetPlanData(Mesnac.Basic.DataSourceFactory.MCDbType.Local, planID); PlanStates planState = (PlanStates)Convert.ToInt32(row["PlanState"]); if (planState == PlanStates.Completed) { ShowMsg(String.Format(Language(128), planID), Language(1), MessageBoxButtons.OK, MessageBoxIcon.Information); } else if (planState == PlanStates.Producting) { ShowMsg(String.Format(Language(129), planID), Language(1), MessageBoxButtons.OK, MessageBoxIcon.Information); } else if (planState == PlanStates.Received) { int planNum = Convert.ToInt32(row["PlanNum"]); //string recipeTypeName = String.Empty; //if (base.NetType == NetTypes.Net) //{ // recipeTypeName = PlanCommon.GetSysCodeItemName(Mesnac.Basic.DataSourceFactory.MCDbType.Server, "PmtType", Convert.ToInt32(row["RecipeType"])); //} //else //{ // recipeTypeName = PlanCommon.GetSysCodeItemName(Mesnac.Basic.DataSourceFactory.MCDbType.local, "PmtType", Convert.ToInt32(row["RecipeType"])); //} //string recipeMaterialName = String.Format("{0}[{1}]{2}", row["RecipeMaterialName"], recipeTypeName, row["RecipeVersionID"]); string recipeVersionID = String.Empty; recipeVersionID = row["RecipeVersionID"] == null || row["RecipeVersionID"] == System.DBNull.Value ? String.Empty : row["RecipeVersionID"].ToString(); SimplePmtRecipe recipe = PlanCommon.GetLocalRecipeMaterial(base.CurrEquipCode, row["RecipeMaterialCode"] as string, recipeVersionID); FrmPlan frmPlan = new FrmPlan(1, planNum, recipe); frmPlan.ShowDialog(this._runtime.BaseControl.MCRoot as Control); if (frmPlan.DialogResult == DialogResult.OK) { planNum = frmPlan.PlanNum; //更新份数 PlanCommon.UpdatePlanNum(planID, planNum); if (base.NetType == NetTypes.Net) { PlanCommon.UpdatePlanNum(Basic.DataSourceFactory.MCDbType.Server, planID, planNum); } clientGridView.ClearSelection(); //清除原有选择项 foreach (DataGridViewRow rowView in clientGridView.Rows) { if (planID == rowView.Cells["PlanID"].Value as string) { rowView.Selected = true; break; } } #region 广播当班计划信息 DbMCControl pptShiftControl = this.GetDbMCControlByKey(Mesnac.Basic.DataSourceFactory.MCDbType.Local, "PptShift").FirstOrDefault(); DbMCControl planDateControl = this.GetDbMCControlByKey(Mesnac.Basic.DataSourceFactory.MCDbType.Local, "[ppt_plan].[down_date]").FirstOrDefault(); PlanCommon.SendNetPlanMsg(base.CurrEquipCode, Convert.ToDateTime(planDateControl.BaseControl.MCValue), Convert.ToInt32(pptShiftControl.BaseControl.MCValue), PlanCommon.PlanLog.LastClassID, base.GetConfigValue("LastUserID", "0")); #endregion } frmPlan.Dispose(); //触发刷新计划事件 if (ModifyPlan.OnRefreshPlan != null) { ModifyPlan.OnRefreshPlan(null, System.EventArgs.Empty); } } } else { ShowMsg(Language(127), Language(1), MessageBoxButtons.OK, MessageBoxIcon.Information); } //显示错误 PlanCommon.ShowErrorList(errorList); this._runtime.BaseControl.MCEnabled = true; } } #endregion #region 当班计划——“添加”本机台计划 /// /// 当班计划——“添加”本机台计划 /// public class AddPlan : FeedingAction, IAction { private IBaseControl _sender = null; private DbMCControl _planDateControl = null; //计划日期 private DbMCControl _pptShiftControl = null; //班次 private DbMCControl _pptClassControl = null; //班组 private DbMCControl _serverGridControl = null; //网络计划控件 public void Run(RuntimeParameter runtime) { base.RunIni(runtime); this._sender = runtime.BaseControl; DbMCControl planDateControl = this.GetDbMCControlByKey(Mesnac.Basic.DataSourceFactory.MCDbType.Local, "[ppt_plan].[down_date]").FirstOrDefault(); DbMCControl pptShiftControl = this.GetDbMCControlByKey(Mesnac.Basic.DataSourceFactory.MCDbType.Local, "PptShift").FirstOrDefault(); DbMCControl pptClassControl = this.GetDbMCControlByKey(Mesnac.Basic.DataSourceFactory.MCDbType.Local, "PptClass").FirstOrDefault(); DbMCControl serverGridControl = this.GetDbMCControlByKey(Mesnac.Basic.DataSourceFactory.MCDbType.Server, "PptPlan").FirstOrDefault(); if (planDateControl == null) { base.LogError("{当班计划-窗体加载} 缺少日期选择控件..."); return; } if (pptShiftControl == null) { base.LogError("{当班计划-窗体加载} 缺少班次组合框控件..."); return; } if (serverGridControl == null) { base.LogError("缺少网络计划网格控件..."); return; } this._planDateControl = planDateControl; this._pptShiftControl = pptShiftControl; this._pptClassControl = pptClassControl; this._serverGridControl = serverGridControl; this.DoNetWork(base.NetType); } /// /// 网络版添加计划 /// protected void DoNetWork(NetTypes netType) { List errorList = null; this._sender.MCEnabled = false; try { if (base.NetType == NetTypes.Net) { bool isConnect = PlanCommon.IsCanConnectServer(); if (!isConnect) { //网络不通 base.SetGlobalNetType(NetTypes.Local); //设置单机版运行 base.SetNetControlVisible(); //如果是单机版,则隐藏网络计划网格控件和“刷新”、“选择接收”、“全部接收”按钮 if (this._serverGridControl != null) { DataGridView serviceGrid = this._serverGridControl.BaseControl as DataGridView; if (serviceGrid != null) { if (serviceGrid.Parent != null && serviceGrid.Parent is Panel) { serviceGrid.Parent.Visible = false; } } else { this._serverGridControl.BaseControl.MCVisible = false; } } ICSharpCode.Core.LoggingService.Warn("刷新网络计划失败:连接网络库失败,转为单机方式运行..."); Mesnac.Basic.MessageBoxTimeOut.Show("连接网络库失败,转为单机方式运行...网络连通后,请重新关闭软件再打开!", Language(1), 3000); //ShowMsg(Language(122), Language(1), MessageBoxButtons.OK, MessageBoxIcon.Warning); } } //判断是单机版还是网络版 if (base.NetType == NetTypes.Net) { //网络版 //网络通,现在网络数据库计划表中新增计划,然后下载到本地 FrmPlan frmPlan = new FrmPlan(0); frmPlan.ShowDialog(this._sender.MCRoot as Control); if (frmPlan.DialogResult == DialogResult.OK) { SimplePmtRecipe recipe = frmPlan.Recipe; int planNum = frmPlan.PlanNum; DateTime planDate = DateTime.Now; DateTime.TryParse(this._planDateControl.BaseControl.MCValue.ToString(), out planDate); int shiftID = 0; int.TryParse(this._pptShiftControl.BaseControl.MCValue.ToString(), out shiftID); int classID = 0; if (this._pptClassControl != null) { int.TryParse(this._pptClassControl.BaseControl.MCValue.ToString(), out classID); } //在网络数据库中添加计划 string planID = PlanCommon.AddPlan(Mesnac.Basic.DataSourceFactory.MCDbType.Server, base.CurrEquipCode, planDate, shiftID, classID, recipe.ObjID, recipe.RecipeVersionID, planNum, out errorList); //接收新添加的计划 PlanCommon.RecivePlan(planID, base.CurrEquipCode, planDate, shiftID); //下载配方数据 #region 下载该计划的配方数据 new BasicInfo.NetRecipe().GetRecipeByPlanID(planID); #endregion #region 广播当班计划信息 DbMCControl pptShiftControl = this.GetDbMCControlByKey(Mesnac.Basic.DataSourceFactory.MCDbType.Local, "PptShift").FirstOrDefault(); DbMCControl planDateControl = this.GetDbMCControlByKey(Mesnac.Basic.DataSourceFactory.MCDbType.Local, "[ppt_plan].[down_date]").FirstOrDefault(); PlanCommon.SendNetPlanMsg(base.CurrEquipCode, Convert.ToDateTime(planDateControl.BaseControl.MCValue), Convert.ToInt32(pptShiftControl.BaseControl.MCValue), PlanCommon.PlanLog.LastClassID, base.GetConfigValue("LastUserID", "0")); #endregion } frmPlan.Dispose(); } else { //单机版 FrmPlan frmPlan = new FrmPlan(0); frmPlan.ShowDialog(this._sender.MCRoot as Control); if (frmPlan.DialogResult == DialogResult.OK) { SimplePmtRecipe recipe = frmPlan.Recipe; int planNum = frmPlan.PlanNum; DateTime planDate = DateTime.Now; DateTime.TryParse(this._planDateControl.BaseControl.MCValue.ToString(), out planDate); int shiftID = 0; int.TryParse(this._pptShiftControl.BaseControl.MCValue.ToString(), out shiftID); int classID = 0; if (this._pptClassControl != null) { int.TryParse(this._pptClassControl.BaseControl.MCValue.ToString(), out classID); } //在本地数据库中添加计划 string planID = PlanCommon.AddPlan(Mesnac.Basic.DataSourceFactory.MCDbType.Local, base.CurrEquipCode, planDate, shiftID, classID, recipe.ObjID, recipe.RecipeVersionID, planNum, out errorList); } frmPlan.Dispose(); } } catch (Exception ex) { base.LogError(ex.Message); base.LogError(ex.StackTrace); } this._sender.MCEnabled = true; //显示错误 PlanCommon.ShowErrorList(errorList); } } #endregion #region 当班计划——“删除”本机台计划 /// /// 当班计划——“删除”本机台计划 /// public class DeletePlan : FeedingAction, IAction { #region 事件定义 /// /// 刷新计划事件 /// public static event EventHandler OnRefreshPlan; #endregion public void Run(RuntimeParameter runtime) { base.RunIni(runtime); base.LogDebug("当班计划——“删除”本机台计划"); DbMCControl clientGridControl = this.GetDbMCControlByKey(Mesnac.Basic.DataSourceFactory.MCDbType.Local, "ppt_plan").FirstOrDefault(); if (clientGridControl == null) { base.LogError("缺少本机台计划网格控件..."); return; } DataGridView clientGridView = clientGridControl.BaseControl as DataGridView; if (clientGridView == null) { base.LogError("本机台计划网格控件类型错误,控件无法转换为DataGridView..."); return; } if (clientGridView.SelectedRows.Count == 1) { string planID = clientGridView.SelectedRows[0].Cells["PlanID"].Value as string; DialogResult result = MessageBox.Show(String.Format(Language(112), planID), Language(1), MessageBoxButtons.YesNo, MessageBoxIcon.Question); if (result == DialogResult.Yes) { PlanStates planState = PlanCommon.GetPlanState(planID); if (planState == PlanStates.Completed) { ShowMsg(String.Format(Language(113), planID), Language(1), MessageBoxButtons.OK, MessageBoxIcon.Information); return; } if (planState == PlanStates.Producting) { ShowMsg(String.Format(Language(114), planID), Language(1), MessageBoxButtons.OK, MessageBoxIcon.Information); return; } //删除本地库计划 PlanCommon.DeletePlan(Basic.DataSourceFactory.MCDbType.Local, planID); if (base.NetType == NetTypes.Net) { if (planID.Trim().Length == 12 && planID.Substring(9, 1) == "L") //如果是本地添加的计划,则把网络库中对应的计划一起删除 { PlanCommon.DeletePlan(Basic.DataSourceFactory.MCDbType.Server, planID); } } #region 广播当班计划信息 DbMCControl pptShiftControl = this.GetDbMCControlByKey(Mesnac.Basic.DataSourceFactory.MCDbType.Local, "PptShift").FirstOrDefault(); DbMCControl planDateControl = this.GetDbMCControlByKey(Mesnac.Basic.DataSourceFactory.MCDbType.Local, "[ppt_plan].[down_date]").FirstOrDefault(); PlanCommon.SendNetPlanMsg(base.CurrEquipCode, Convert.ToDateTime(planDateControl.BaseControl.MCValue), Convert.ToInt32(pptShiftControl.BaseControl.MCValue), PlanCommon.PlanLog.LastClassID, base.GetConfigValue("LastUserID", "0")); #endregion //触发刷新计划事件 if (DeletePlan.OnRefreshPlan != null) { DeletePlan.OnRefreshPlan(null, System.EventArgs.Empty); } } } else { ShowMsg(Language(111), Language(1), MessageBoxButtons.OK, MessageBoxIcon.Information); } } } #endregion #region 当班计划——“上移”本机台计划 /// /// 当班计划——“上移”本机台计划 /// public class MoveUpPlan : FeedingAction, IAction { /// /// 移动计划事件 /// public static event EventHandler OnMovePlan; public virtual void Run(RuntimeParameter runtime) { base.RunIni(runtime); MovePlan(runtime, Language(103), "up"); } public void MovePlan(RuntimeParameter runtime, string msg, string updown) { List errorList = new List(); base.LogDebug("当班计划——“选择接收”网络计划"); DbMCControl shiftControl = this.GetDbMCControlByKey(Mesnac.Basic.DataSourceFactory.MCDbType.Local, "PptShift").FirstOrDefault(); DbMCControl planDateControl = this.GetDbMCControlByKey(Mesnac.Basic.DataSourceFactory.MCDbType.Local, "[ppt_plan].[down_date]").FirstOrDefault(); DbMCControl clientGridControl = this.GetDbMCControlByKey(Mesnac.Basic.DataSourceFactory.MCDbType.Local, "ppt_plan").FirstOrDefault(); //获取本机台计划网格控件 #region 控件存在验证 if (shiftControl == null) { base.LogError("缺少班次控件...(班次控件为组合框,数据源要绑定PptShift)"); return; } if (planDateControl == null) { base.LogError("缺少日期控件...(日期控件为日历,数据源要绑定down_date)"); return; } if (clientGridControl == null) { base.LogError("{当班计划——“选择接收”网络计划}缺少本机台计划网格控件..."); return; } #endregion string planIds = String.Empty; DataGridView clientGridView = clientGridControl.BaseControl as DataGridView; if (clientGridView == null) { base.LogError("本机台计划网格控件类型错误,控件无法转换为DataGridView..."); return; } if (clientGridView.SelectedRows.Count == 1) { string planId = clientGridView.SelectedRows[0].Cells["PlanID"].Value.ToString(); PlanStates planState = PlanCommon.GetPlanState(planId); //获取当前计划的前一个或后一个计划 string tempPlanId = String.Empty; if (updown.ToLower() == "up") { //上移,判断当前计划状态 if (planState == PlanStates.Completed) { ShowMsg(String.Format(Language(105), planId), Language(1), MessageBoxButtons.OK, MessageBoxIcon.Information); return; } if (planState == PlanStates.Producting) { ShowMsg(String.Format(Language(106), planId), Language(1), MessageBoxButtons.OK, MessageBoxIcon.Information); return; } tempPlanId = PlanCommon.GetPrevPlanID(planId, base.CurrEquipCode, Convert.ToDateTime(planDateControl.BaseControl.MCValue), Convert.ToInt32(shiftControl.BaseControl.MCValue)); //判断上一计划的状态 PlanStates tempPlanState = PlanCommon.GetPlanState(tempPlanId); if (tempPlanState == PlanStates.Completed) { ShowMsg(String.Format(Language(109), tempPlanId), Language(1), MessageBoxButtons.OK, MessageBoxIcon.Information); return; } if (tempPlanState == PlanStates.Producting) { ShowMsg(String.Format(Language(110), tempPlanId), Language(1), MessageBoxButtons.OK, MessageBoxIcon.Information); return; } } else { //下移,判断当前计划状态 if (planState == PlanStates.Completed) { ShowMsg(String.Format(Language(107), planId), Language(1), MessageBoxButtons.OK, MessageBoxIcon.Information); return; } if (planState == PlanStates.Producting) { ShowMsg(String.Format(Language(108), planId), Language(1), MessageBoxButtons.OK, MessageBoxIcon.Information); return; } tempPlanId = PlanCommon.GetNextPlanID(planId, base.CurrEquipCode, Convert.ToDateTime(planDateControl.BaseControl.MCValue), Convert.ToInt32(shiftControl.BaseControl.MCValue)); } if (String.IsNullOrEmpty(tempPlanId)) { ShowMsg(String.Format(msg, planId), Language(1), MessageBoxButtons.OK, MessageBoxIcon.Information); return; } PlanCommon.SwapActionOrder(planId, tempPlanId); //交换2个计划的ActionOrder #region 在本机台网格控件中显示本机台计划 //new RefreshClientPlan().Run(runtime); if (MoveUpPlan.OnMovePlan != null) { MoveUpPlan.OnMovePlan(runtime, System.EventArgs.Empty); } #endregion clientGridView.ClearSelection(); //清除原有选择项 foreach (DataGridViewRow row in clientGridView.Rows) { if (planId == row.Cells["PlanID"].Value as string) { row.Selected = true; break; } } #region 广播当班计划信息 DbMCControl pptShiftControl = this.GetDbMCControlByKey(Mesnac.Basic.DataSourceFactory.MCDbType.Local, "PptShift").FirstOrDefault(); PlanCommon.SendNetPlanMsg(base.CurrEquipCode, Convert.ToDateTime(planDateControl.BaseControl.MCValue), Convert.ToInt32(pptShiftControl.BaseControl.MCValue), PlanCommon.PlanLog.LastClassID, base.GetConfigValue("LastUserID", "0")); #endregion } } } #endregion #region 当班计划——“下移”本机台计划 /// /// 当班计划——“下移”本机台计划 /// public class MoveDownPlan : MoveUpPlan { public override void Run(RuntimeParameter runtime) { base.RunIni(runtime); base.MovePlan(runtime, Language(104), "down"); } } #endregion #region 当班计划——“暂存”本机台计划 /// /// 当班计划——“暂存”本机台计划 /// public class TempStorePlan : FeedingAction, IAction { public void Run(RuntimeParameter runtime) { base.RunIni(runtime); } } #endregion }