public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { string enuminfo = SafeConverter.SafeToStr(parameter); if (string.IsNullOrEmpty(enuminfo)) { return(value); } string sValue = SafeConverter.SafeToStr(value); string sText = sValue; string[] enuminfos = enuminfo.Split(';', ';'); foreach (var str in enuminfos) { string[] s = str.Split(':', ':'); if (s.Count() < 2) { continue; } if (sValue == s[0]) { sText = s[1]; } } return(sText); }
private void OnDataChange(object subscriptionhandle, object requesthandle, ItemValueResult[] values) { foreach (ItemValueResult value in values) { if (value.ClientHandle == null) { continue; } if (handle[0].Equals(value.ClientHandle)) { this.Dispatcher.BeginInvoke((Action) delegate() { tbValue.Text = SafeConverter.SafeToStr(value.Value); }); } if (handle[1].Equals(value.ClientHandle)) { this.Dispatcher.BeginInvoke((Action) delegate() { tbValue2.Text = SafeConverter.SafeToStr(value.Value); }); } } }
/// <summary> /// 使用EF框架获取数据,返回DataTable /// </summary> /// <param name="type"></param> /// <param name="strSql"></param> /// <param name="parameterNames"></param> /// <param name="parameterValues"></param> /// <returns></returns> public DataTable GetDataTableWithEF(Type type, string strSql, string[] parameterNames, string[] parameterValues) { var table = new DataTable("DataTableWithEF"); DbRawSqlQuery datas = dbContext.Database.SqlQuery(type, strSql, DBFactory.ChangeToDbParams(parameterNames, parameterValues)); foreach (var data in datas) { var row = table.NewRow(); foreach (var info in type.GetProperties()) { if (table.Rows.Count <= 0) { table.Columns.Add(info.Name); } var value = info.GetValue(data, null) ?? DBNull.Value; row[info.Name] = SafeConverter.SafeToStr(value); } table.Rows.Add(row); } return(table); }
/// <summary> /// 使用EF框架获取第一行第一列数据 /// </summary> /// <param name="strSql"></param> /// <param name="parameterNames"></param> /// <param name="parameterValues"></param> /// <returns></returns> public List <string> GetFirstRowWithEF(Type type, string strSql, string[] parameterNames, string[] parameterValues) { List <string> result = new List <string>(); if (type == null) { return(result); } DbRawSqlQuery datas = dbContext.Database.SqlQuery(type, strSql, DBFactory.ChangeToDbParams(parameterNames, parameterValues)); foreach (var data in datas) { foreach (var info in type.GetProperties()) { var value = info.GetValue(data, null) ?? DBNull.Value; result.Add(SafeConverter.SafeToStr(value)); } return(result); } return(result); }
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { int result = 0; int.TryParse(SafeConverter.SafeToStr(value), out result); return(result + 1); }
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { if (value == null) { return(""); } string[] operates = SafeConverter.SafeToStr(parameter).Split(' '); //字段 + 字段 if (operates.Count() < 3) { return(""); } string field1 = operates[0]; string operate = operates[1]; string field2 = operates[2]; string value1 = ""; string value2 = ""; PropertyInfo propertyInfo1 = value.GetType().GetProperty(field1); if (propertyInfo1 != null) { value1 = SafeConverter.SafeToStr(propertyInfo1.GetValue(value, null)); } PropertyInfo propertyInfo2 = value.GetType().GetProperty(field2); if (propertyInfo2 != null) { value2 = SafeConverter.SafeToStr(propertyInfo2.GetValue(value, null)); } string operate2 = ""; string value3 = ""; if (operates.Count() == 5) { operate2 = operates[1]; string field3 = operates[2]; PropertyInfo propertyInfo3 = value.GetType().GetProperty(field3); if (propertyInfo3 != null) { value3 = SafeConverter.SafeToStr(propertyInfo3.GetValue(value, null)); } } DataTable dt = new DataTable("ColumnOperateConverter"); try { return(dt.Compute(value1 + operate + value2 + operate2 + value3, ""));//将运算字符串转换成表达式运算 } catch (Exception) { return(""); } }
private void OutBound_OnSelectionChanged(object sender, SelectionChangedEventArgs e) { if (SafeConverter.SafeToStr(cmbOutBound.SelectedValue) == "1") //机床 { cmbOutPos.ItemsSource = ws.UseService(s => s.GetAmAssetMasterNs("USE_FLAG = 1")); } else { cmbOutPos.ItemsSource = null; } }
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { if (value == null) { return(""); } string formate = SafeConverter.SafeToStr(parameter); string sValue = SafeConverter.SafeToStr(value, formate); return(sValue); }
private void BarEditItem_OnEditValueChanged(object sender, RoutedEventArgs e) { string value = SafeConverter.SafeToStr((sender as BarEditItem).EditValue); if (string.IsNullOrEmpty(value)) { return; } if (cvMain.CurSelectedDragThumb != null) { cvMain.CurSelectedDragThumb.CtrlName = value; } }
private void BarEditItem7_OnEditValueChanged(object sender, RoutedEventArgs e) { string value = SafeConverter.SafeToStr((sender as BarEditItem).EditValue); if (string.IsNullOrEmpty(value)) { return; } foreach (DragThumb thumb in cvMain.SelectDragThumbs) { thumb.MonitorItem = SafeConverter.SafeToBool(value); } }
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { string[] parameters = SafeConverter.SafeToStr(parameter).Split(';', ';'); //外键表名称;关联外键表字段;外键表显示字段名 string sValue = SafeConverter.SafeToStr(value); if ((parameters.Count() < 3) || (string.IsNullOrEmpty(sValue))) { return(sValue); } string sText = LoadingStr; if (!bBackgroundGetValue) //尚未开启后台获取数据 { bBackgroundGetValue = true; ThreadPool.QueueUserWorkItem(s => { while (!CBaseData.AppClosing) { DateTime synchroTime = DateTime.Now.AddSeconds(GetValueSpan); try { List <CacheData> cacheDatas = CacheDatas.Where(c => c.LastSynchroTime <= synchroTime) .OrderByDescending(c => c.LastSynchroTime).ToList(); //按照上次更新的时间逆序排序 foreach (var cacheData in cacheDatas) { cacheData.RefreshDataFromDB(); //刷新数据 } } catch (Exception e) { Console.WriteLine(e); } Thread.Sleep(10); } });//开启后台提取数据 } sText = GetValueByTableField(parameters, sValue); if ((sText == sValue) && (Guid.TryParse(sText, out _))) { sText = ""; } return(sText); }
private void BarEditItem3_OnEditValueChanged(object sender, RoutedEventArgs e) { string value = SafeConverter.SafeToStr((sender as BarEditItem).EditValue); if (string.IsNullOrEmpty(value)) { return; } foreach (DragThumb thumb in cvMain.SelectDragThumbs) { thumb.Position = new Point(thumb.Position.X, double.Parse(value)); } }
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { if (value == null) { return(Visibility.Collapsed); } string checkValue = SafeConverter.SafeToStr(parameter); if (string.IsNullOrEmpty(checkValue)) //没有参数 { return(SafeConverter.SafeToBool(value) ? Visibility.Visible : Visibility.Collapsed); } else { string sValue = SafeConverter.SafeToStr(value); List <string> checks = checkValue.Split(';').ToList(); return((checks.Contains(sValue)) ? Visibility.Visible : Visibility.Collapsed); } }
/// <summary> /// 将Name值转换成枚举值 /// </summary> /// <typeparam name="T">枚举类型名称</typeparam> /// <param name="name">string值</param> /// <param name="defaultValue">默认值</param> /// <returns>枚举值</returns> public static T ParserEnumByName <T>(string name, T defaultValue) where T : struct, IConvertible { if (!typeof(T).IsEnum) { throw new ArgumentException("T必须是枚举类型"); } if (string.IsNullOrEmpty(name)) { return(defaultValue); } foreach (T item in Enum.GetValues(typeof(T))) { if (SafeConverter.SafeToStr(item).ToLower().Equals(name.Trim().ToLower())) { return(item); } } return(defaultValue); }
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { string[] parameters = SafeConverter.SafeToStr(parameter).Split(';', ';'); //外键表名称;关联外键表字段;外键表显示字段名 string sValue = SafeConverter.SafeToStr(value); if ((parameters.Count() < 3) || (string.IsNullOrEmpty(sValue))) { return(sValue); } string sText = LoadingStr; if (!bBackgroundGetValue) //尚未开启后台获取数据 { bBackgroundGetValue = true; ThreadPool.QueueUserWorkItem(s => { while (!CBaseData.AppClosing) { DateTime synchroTime = DateTime.Now.AddSeconds(GetValueSpan); try { List <ForeignValue> foreignValues = ForeignInfoValues.Where(c => c.LastSynchroTime <= synchroTime) .OrderByDescending(c => c.LastSynchroTime).ToList(); //按照上次更新的时间逆序排序 #region 多线程进行数据的提取 int threadCount = 20; //线程数 int step = (foreignValues.Count / threadCount) + 1; for (int i = 0; i < threadCount; i++) { var iStep = i; if (foreignValues.Count <= iStep * step) { break; } for (int j = 0; j < step; j++) { var index = iStep * step + j; if (index >= foreignValues.Count) { break; } foreignValues[index].LastSynchroTime = DateTime.Now; } ThreadPool.QueueUserWorkItem(t => { for (int j = 0; j < step; j++) { var index = iStep * step + j; if (index >= foreignValues.Count) { break; } string result = GetValueByTableField(foreignValues[index].Parameters, foreignValues[index].KeyValue); foreignValues[index].SetValue(result); } }); } #endregion } catch (Exception e) { Console.WriteLine(e); } Thread.Sleep(10); } });//开启后台提取数据 } string sKey = SafeConverter.SafeToStr(parameter) + ";" + sValue; //所有的作为关键字 ForeignValue foreignValue = ForeignInfoValues.FirstOrDefault(c => c.Name == sKey); if (foreignValue == null) //没有初始化,不包含外键的信息 { foreignValue = new ForeignValue(sKey, parameters, sValue); foreignValue.LastSynchroTime = DateTime.Now; sText = GetValueByTableField(foreignValue.Parameters, foreignValue.KeyValue); foreignValue.SetValue(sText); ForeignInfoValues.Add(foreignValue); } else { sText = ForeignInfoValues.FirstOrDefault(c => c.Name == sKey)?.Value; } #region 延时加载数据 - delete //int iMaxDelay = 200; //while (!CBaseData.AppClosing && iMaxDelay > 0) //延迟加载信息 //{ // sText = ForeignInfoValues.FirstOrDefault(c => c.Name == sKey)?.Value; // if (sText != LoadingStr) break; // iMaxDelay--; // Thread.Sleep(10); //} #endregion if ((sText == sValue) && (Guid.TryParse(sText, out _))) { sText = ""; } return(sText); }
//测试 private void BtnTest_Click(object sender, RoutedEventArgs e) { TbTestResult.Text = ""; RefreshCalculationText(); Type dynamicCode = null; //获取编译后代码,调用该类用 Dictionary <string, Dictionary <string, string> > FuncAndParamTagPKNO = new Dictionary <string, Dictionary <string, string> >(); //函数和对应参数的Tag的PKNO string className = "C" + Guid.NewGuid().ToString("N"); try { Cursor = Cursors.Wait; #region 形成执行的代码 string execCode = "using System; \r\n" + "using System.Text; \r\n" + "using System.Collections.Generic; \r\n" + "using BFM.Common.Base; \r\n\r\n"; execCode += "public class " + className + "\r\n" + "{ \r\n"; string basicFuc = "AutoCalculation"; int index = 1; FuncAndParamTagPKNO.Clear(); string exp = CalculationText; //表达式 string funcname = basicFuc + index.ToString(); //函数名称 Dictionary <string, string> paramTas = new Dictionary <string, string>(); //参数对应的标签的PKNO, param名称 List <string> funcParam = new List <string>(); //带类型的参数 string code = ""; foreach (var line in exp.Split(new string[] { "\r\n" }, StringSplitOptions.None)) { string ret = line; #region 替换标签值,将标签替换成参数名 string[] expTags = line.Split('{'); for (int i = 0; i < expTags.Length; i++) { string str = expTags[i]; int length = str.IndexOf('}'); if (length < 0) //没有找到 } { continue; } string tagPKNO = str.Substring(0, length); //{ } 内为PKNO string param = "{" + tagPKNO + "}"; if (paramTas.ContainsKey(tagPKNO)) //已经添加了该参数 { param = paramTas[tagPKNO]; } else { FmsAssetTagSetting tag = DeviceTags.FirstOrDefault(s => s.PKNO == tagPKNO); if (tag == null) { continue; } param = "param" + paramTas.Count; paramTas.Add(tagPKNO, param); string paramType = "string"; //string paramType = ((CalculationType == 2) || (tag.VALUE_TYPE > 0 && tag.VALUE_TYPE < 20)) // ? "double" // : "string"; funcParam.Add(paramType + " " + param); } ret = ret.Replace("{" + tagPKNO + "}", param); } #endregion if (string.IsNullOrEmpty(code)) { code = " " + ret; } else { code += Environment.NewLine + " " + ret; } } //C#脚本 //支持C#语法,最后返回值(Double/String) string resultType = "string"; //确定返回结果类型,将code语句转换成C#的语句 if (CalculationType == 1) //逻辑运算 { //(结果为1,0):({标签1}==1)&&({标签2}==1)&&({标签3}==0||{标签4}==0)&&({标签5}==1) code = code.Replace("AND", "&&").Replace("and", "&&").Replace("OR", "||").Replace("or", "||"); resultType = "bool"; } else if (CalculationType == 2) //数值运算 { //{标签1}+3+{标签2}+4 resultType = "double"; } else if (CalculationType == 3) //字符运算 { //{标签1}+"123" } else if (CalculationType == 12) //条件数值运算 { //{标签1}==3:{标签2}+1;{标签1}==4:{标签2}+2;{标签1}==5:{标签2}+3 resultType = "double"; List <string> exps = code.Split(';').ToList(); string temp = ""; foreach (var exp1 in exps) { if (exp1.Split(':').Length < 2) { continue; } temp += " if (" + exp1.Split(':')[0] + ") { return (" + exp1.Split(':')[1] + "); } \r\n"; } temp += " return 0; \r\n"; code = temp; } else if (CalculationType == 13) //条件字符运算 { //{标签1}==3:{标签1}+"123";{标签1}==4:{标签1}+"123" List <string> exps = code.Split(';').ToList(); string temp = ""; foreach (var exp1 in exps) { if (exp1.Split(':').Length < 2) { continue; } temp += " if (" + exp1.Split(':')[0] + ") { return (" + exp1.Split(':')[1] + ").ToString(); } \r\n"; } temp += " return \"\"; \r\n"; code = temp; } else if (CalculationType == 21) { resultType = "string";//{标签1};3 List <string> exps = code.Split(';').ToList(); string temp = ""; if (exps.Count >= 2) { int arrayIndex = SafeConverter.SafeToInt(exps[1].Trim(), 0); temp += " if ( " + exps[0].Trim() + ".Split('|').Length > " + arrayIndex + ") { return " + exps[0].Trim() + ".Split('|')[" + arrayIndex + "]; } \r\n"; } temp += " return \"\"; \r\n"; code = temp; } else if (CalculationType == 100) //C#脚本 { //支持C#语法,最后返回值(Double/String) resultType = "string"; } else //不支持的类型 { code = $" return \"计算类型[{CalculationType}],不支持的类型。\"; \r\n"; } execCode += DynamicCode.BuildExecFunc(funcname, resultType, code, funcParam); FuncAndParamTagPKNO.Add(funcname, paramTas); //添加 execCode += "}\r\n"; #endregion #region 编译代码 CodeDomProvider compiler = new CSharpCodeProvider(); CompilerParameters cp = new CompilerParameters() { GenerateExecutable = false, GenerateInMemory = true, }; cp.ReferencedAssemblies.Add("BFM.Common.Base.dll"); CompilerResults cr = compiler.CompileAssemblyFromSource(cp, execCode); if (cr.Errors.HasErrors) { WPFMessageBox.ShowError("测试失败,语法错误.\r\n" + execCode, "测试"); return; } dynamicCode = cr.CompiledAssembly.GetType(className); //获取 #endregion #region 获取值 index = 0; string funcName = FuncAndParamTagPKNO.Keys.ToList()[index]; var tagParms = FuncAndParamTagPKNO.Values.ToList()[index]; List <object> paramValues = new List <object>(); //参数值 foreach (var tagpkno in tagParms) //参数 { object value; FmsAssetTagSetting tagParam = DeviceTags.FirstOrDefault(s => s.PKNO == tagpkno.Key); if (tagParam != null) { value = SafeConverter.SafeToStr(tagParam.CUR_VALUE); //if ((CalculationType == 2) || (tagParam.VALUE_TYPE > 0 && tagParam.VALUE_TYPE < 20)) //{ // value = SafeConverter.SafeToDouble(tagParam.CUR_VALUE); //} //else //{ // value = SafeConverter.SafeToStr(tagParam.CUR_VALUE); //} } else { value = ""; } paramValues.Add(value); } object obj = dynamicCode.InvokeMember(funcName, BindingFlags.Public | BindingFlags.Static | BindingFlags.InvokeMethod, System.Type.DefaultBinder, null, paramValues.ToArray()); string newValue = ""; //新的计算结果 if (CalculationType == 1) //逻辑运算 { newValue = SafeConverter.SafeToBool(obj) ? "1" : "0"; } else { newValue = SafeConverter.SafeToStr(obj); } Console.WriteLine("测试结果:" + newValue); TbTestResult.Text = newValue; #endregion WPFMessageBox.ShowInfo("测试成功. \r\n测试结果为:" + newValue, "测试"); } catch (Exception ex) { Console.WriteLine(ex); WPFMessageBox.ShowError("测试失败,错误为:" + ex.Message, "测试"); } finally { Cursor = Cursors.Arrow; } }
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { string EnumIdentify = SafeConverter.SafeToStr(parameter); if (string.IsNullOrEmpty(EnumIdentify)) { return(value); } string sValue = SafeConverter.SafeToStr(value); string sText = sValue; if (LastConvertTime.AddMinutes(RefreshSpan) < DateTime.Now) // { OldValue.Clear(); LastConvertTime = DateTime.Now; } SysEnumMain main = null; List <SysEnumItems> items = new List <SysEnumItems>(); foreach (SysEnumMain keyMain in OldValue.Keys) { if (keyMain.ENUM_IDENTIFY == EnumIdentify) { main = keyMain; items = OldValue[keyMain]; break; } } if (main == null) //重新提取数据 { main = ws.UseService(s => s.GetSysEnumMains($"ENUM_IDENTIFY = '{EnumIdentify}'")).FirstOrDefault(); items = ws.UseService(s => s.GetSysEnumItemss($"ENUM_IDENTIFY = '{EnumIdentify}'")) .OrderBy(c => c.ITEM_INDEX) .ToList(); if (main != null) { OldValue.Add(main, items); } } else //有缓存数据 { if (items.Count <= 0) //没有数据,重新提取一遍 { items = ws.UseService(s => s.GetSysEnumItemss($"ENUM_IDENTIFY = '{EnumIdentify}'")) .OrderBy(c => c.ITEM_INDEX) .ToList(); OldValue[main] = items; } } if ((main != null) && (items.Count > 0)) { SysEnumItems temp; switch (main.VALUE_FIELD) { case 1: //编号 temp = items.FirstOrDefault(c => c.ITEM_NO == sValue); if (temp != null) { sText = temp.ITEM_NAME; } break; case 2: //代码 temp = items.FirstOrDefault(c => c.ITEM_CODE == sValue); if (temp != null) { sText = temp.ITEM_NAME; } break; case 3: //PKNO temp = items.FirstOrDefault(c => c.PKNO == sValue); if (temp != null) { sText = temp.ITEM_NAME; } break; default: //名称 temp = items.FirstOrDefault(c => c.ITEM_NAME == sValue); if (temp != null) { sText = temp.ITEM_NAME; } break; } } return(sText); }
/// <summary> /// 同步读取数据 /// </summary> /// <param name="dataAddress">WebApi地址,第一位为类型,第二位为地址,后面位参数</param> /// <returns></returns> public OperateResult <string> SyncReadData(string dataAddress) { #region 检验 if (string.IsNullOrEmpty(dataAddress)) { return(new OperateResult <string>("传入的参数都不能为空")); } if (client == null) { return(new OperateResult <string>("WebApi 接口设备,没有正确初始化")); } #endregion string[] values = dataAddress.Split('|'); //WebApi地址,第一位为类型,第二位为地址,后面位参数 try { int count = values.Count() - 2; if (count <= 0) { count = 0; } object[] param = new object[count]; string sType = "GET"; string address = dataAddress; if (param.Length > 1) { sType = SafeConverter.SafeToStr(param[0]).ToUpper(); address = SafeConverter.SafeToStr(param[1]); } for (int i = 2; i < values.Count(); i++) { param[i - 2] = values[i]; //参数 } string url = string.Format(address, param); HttpResponseMessage result = null; //结果 HttpContent content = new StringContent(""); content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json") { CharSet = "utf-8" }; if (sType == "GET") { result = client.GetAsync(url).Result; } else if (sType == "PUT") { result = client.PutAsync(url, content).Result; } else if (sType == "POST") { result = client.PostAsync(url, content).Result; } else if (sType == "DELETE") { result = client.DeleteAsync(url).Result; } if (result != null) { string resultContent = result.Content.ReadAsStringAsync().Result; return(OperateResult.CreateSuccessResult <string>(resultContent)); } return(new OperateResult <string>("")); } catch (Exception ex) { string error = $"---读取 WebApi 地址({dataAddress}) ) 失败,错误为({ex.Message.ToString()})"; Console.WriteLine(error); return(new OperateResult <string>(error)); } }
//移除 private void btnToolsUnBindDevice_Click(object sender, System.Windows.RoutedEventArgs e) { //移除刀 string detailPKNO = SafeConverter.SafeToStr(ClassHelper.GetPropertyValue(gridToolsFinal.SelectedItem, "PKNO")); TmsDeviceToolsPos deviceToolsPos = wsTMS.UseService(s => s.GetTmsDeviceToolsPosById(detailPKNO)); if (deviceToolsPos == null) { return; } #region 移除刀 if (deviceToolsPos.TOOLS_STATE == 0) { MessageBox.Show($"刀位[{deviceToolsPos.TOOLS_POS_NO}]为空,不能移除", "移除刀具", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } else if (deviceToolsPos.TOOLS_STATE == 1) { if (MessageBox.Show($"刀位[{deviceToolsPos.TOOLS_POS_NO}]已在刀位,确定要移除吗?", "移除刀具", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning) != DialogResult.OK) { return; } deviceToolsPos.TOOLS_STATE = 3; //刀具一处 deviceToolsPos.UPDATED_BY = CBaseData.LoginName; deviceToolsPos.LAST_UPDATE_DATE = DateTime.Now; deviceToolsPos.UPDATED_INTROD += "【" + DateTime.Now + "】刀具移除. "; wsTMS.UseService(s => s.UpdateTmsDeviceToolsPos(deviceToolsPos)); } else if (deviceToolsPos.TOOLS_STATE == 3) //已经移除 { if (MessageBox.Show($"刀位[{deviceToolsPos.TOOLS_POS_NO}]已经是移除状态,确定要!取消移除!吗?", "移除刀具", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning) != DialogResult.OK) { return; } deviceToolsPos.TOOLS_STATE = 1; //刀具在位 deviceToolsPos.UPDATED_BY = CBaseData.LoginName; deviceToolsPos.LAST_UPDATE_DATE = DateTime.Now; deviceToolsPos.UPDATED_INTROD += "【" + DateTime.Now + "】取消移除. "; wsTMS.UseService(s => s.UpdateTmsDeviceToolsPos(deviceToolsPos)); } else if (deviceToolsPos.TOOLS_STATE == 2) //已排入 { if (MessageBox.Show($"刀位[{deviceToolsPos.TOOLS_POS_NO}]已排入等待装刀,确定要!取消排入!吗?", "移除刀具", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning) != DialogResult.OK) { return; } deviceToolsPos.TOOLS_STATE = 0; //刀具为空 deviceToolsPos.NEW_TOOLS_PKNO = ""; //刀具PKNO deviceToolsPos.UPDATED_BY = CBaseData.LoginName; deviceToolsPos.LAST_UPDATE_DATE = DateTime.Now; deviceToolsPos.UPDATED_INTROD += "【" + DateTime.Now + "】取消排入. "; wsTMS.UseService(s => s.UpdateTmsDeviceToolsPos(deviceToolsPos)); } else if (deviceToolsPos.TOOLS_STATE == 10) { if (MessageBox.Show($"刀位[{deviceToolsPos.TOOLS_POS_NO}]已经是更换刀具,确定要!取消更换!吗?", "移除刀具", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning) != DialogResult.OK) { return; } deviceToolsPos.TOOLS_STATE = 1; //刀具在位 deviceToolsPos.NEW_TOOLS_PKNO = ""; //清空刀号 deviceToolsPos.UPDATED_BY = CBaseData.LoginName; deviceToolsPos.LAST_UPDATE_DATE = DateTime.Now; deviceToolsPos.UPDATED_INTROD += "【" + DateTime.Now + "】取消更换刀具. "; wsTMS.UseService(s => s.UpdateTmsDeviceToolsPos(deviceToolsPos)); } #endregion GetPage(); }
private void BtnAutoChange_Click(object sender, RoutedEventArgs e) { TmsToolsMaster mToolsMasterUp = GridControlInvTool.SelectedItem as TmsToolsMaster; //库存 TmsDeviceToolsPos mTmsDeviceToolsPos = GridControlDeviceTool.SelectedItem as TmsDeviceToolsPos; //机床刀位信息 if (mToolsMasterUp == null) { return; } if (mTmsDeviceToolsPos == null) { return; } AmAssetMasterN asset = ComAsset.SelectedItem as AmAssetMasterN; if (asset == null) { WPFMessageBox.ShowError("请选择机床信息!", "自动换刀管理"); return; } TmsToolsMaster mToolsMasterDown = ws.UseService(s => s.GetTmsToolsMasterById(mTmsDeviceToolsPos.TOOLS_PKNO)); if (mToolsMasterDown == null) { WPFMessageBox.ShowError("选中的需要换下的机床刀具信息不存在,请核实!", "自动换刀管理"); return; } MesJobOrder jobOrder = null; WmsInventory inv = null; List <MesProcessCtrol> processCtrols = new List <MesProcessCtrol>(); #region 形成工单 jobOrder = new MesJobOrder() { PKNO = CBaseData.NewGuid(), COMPANY_CODE = CBaseData.BelongCompPKNO, LINE_PKNO = CBaseData.CurLinePKNO, LINE_TASK_PKNO = "", //产线任务PKNO ITEM_PKNO = "", // TODO:暂无 JOB_ORDER_NO = TableNOHelper.GetNewNO("MES_JOB_ORDER.JOB_ORDER_NO", "J"), BATCH_NO = "自动换刀", ROUTING_DETAIL_PKNO = "", JOB_ORDER_TYPE = 2, //工单类型 1:原料入库;2:加工;3:成品出库;4:转换 TASK_QTY = 1, COMPLETE_QTY = 0, ONLINE_QTY = 0, ONCE_QTY = 0, RUN_STATE = 10, //直接生产 CREATION_DATE = DateTime.Now, CREATED_BY = CBaseData.LoginNO, LAST_UPDATE_DATE = DateTime.Now, //最后修改日期 USE_FLAG = 1, REMARK = "", }; #endregion #region 增加参数 Dictionary <string, string> ParamValues = new Dictionary <string, string>(); ParamValues.Add("{机床刀号}", mTmsDeviceToolsPos.TOOLS_POS_NO); //机床刀号 ParamValues.Add("{卸下刀具编号}", mToolsMasterDown.TOOLS_CODE.PadRight(25)); //卸下刀具编号 ParamValues.Add("{装上刀具编号}", mToolsMasterUp.TOOLS_CODE.PadRight(25)); //装上刀具编号 ParamValues.Add("{装上刀具PKNO}", mToolsMasterUp.PKNO); //装上刀具PKNO ParamValues.Add("{卸下刀具PKNO}", mToolsMasterDown.PKNO); //卸下刀具PKNO ParamValues.Add("{长度形状补偿}", SafeConverter.SafeToStr(mToolsMasterUp.COMPENSATION_SHAPE_LENGTH)); //长度形状补偿 - 装上 ParamValues.Add("{半径形状补偿}", SafeConverter.SafeToStr(mToolsMasterUp.COMPENSATION_SHAPE_DIAMETER)); //半径形状补偿 - 装上 ParamValues.Add("{卸下刀位PKNO}", mTmsDeviceToolsPos.PKNO); //卸下刀位PKNO ParamValues.Add("{装上刀位PKNO}", mTmsDeviceToolsPos.PKNO); //装上刀位PKNO ParamValues.Add("{装刀机床PKNO}", asset?.PKNO); //装刀机床PKNO #endregion string sFormulaCode = "换刀-" + asset.ASSET_CODE; List <FmsActionFormulaDetail> formulaDetails = wsFms.UseService(s => s.GetFmsActionFormulaDetails($"FORMULA_CODE = '{sFormulaCode}' AND USE_FLAG= 1")) .OrderBy(c => c.PROCESS_INDEX) .ToList(); foreach (var detail in formulaDetails) //配方 { MesProcessCtrol process = new MesProcessCtrol() { #region 标准信息 PKNO = CBaseData.NewGuid(), COMPANY_CODE = CBaseData.BelongCompPKNO, ITEM_PKNO = "", //成品PKNO TODO:暂无 JOB_ORDER_PKNO = jobOrder.PKNO, JOB_ORDER = jobOrder.JOB_ORDER_NO, SUB_JOB_ORDER_NO = "", ROUTING_DETAIL_PKNO = "", // #endregion PROCESS_CTROL_NAME = detail.FORMULA_DETAIL_NAME, //名称 PROCESS_DEVICE_PKNO = ProcessParamReplace.Replace(detail.PROCESS_DEVICE_PKNO, ParamValues), //生产设备 PROCESS_PROGRAM_NO = ProcessParamReplace.Replace(detail.PROCESS_PROGRAM_NO, ParamValues), //加工程序号 PROCESS_PROGRAM_CONTENT = detail.PROCESS_PROGRAM_CONTENT, //加工程序内容 PROCESS_INDEX = detail.PROCESS_INDEX, //工序顺序 BEGIN_ITEM_PKNO = ProcessParamReplace.Replace(detail.BEGIN_ITEM_PKNO, ParamValues), //生产前项目PKNO FINISH_ITEM_PKNO = ProcessParamReplace.Replace(detail.FINISH_ITEM_PKNO, ParamValues), //生产后项目PKNO BEGIN_POSITION = ProcessParamReplace.Replace(detail.BEGIN_POSITION, ParamValues), //生产前位置 FINISH_POSITION = ProcessParamReplace.Replace(detail.FINISH_POSITION, ParamValues), //生产后位置 PALLET_NO = detail.PALLET_NO, //托盘号 PROCESS_ACTION_TYPE = detail.PROCESS_ACTION_TYPE, //工序动作类型 PROCESS_ACTION_PKNO = detail.PROCESS_ACTION_PKNO, //工序动作控制PKNO PROCESS_ACTION_PARAM1_VALUE = ProcessParamReplace.Replace(detail.PROCESS_ACTION_PARAM1_VALUE, ParamValues), //工序动作参数1 PROCESS_ACTION_PARAM2_VALUE = ProcessParamReplace.Replace(detail.PROCESS_ACTION_PARAM2_VALUE, ParamValues), //工序动作参数2 CUR_PRODUCT_CODE_PKNO = "", //当前生产加工的产品编码PKNO PROCESS_QTY = 1, //加工数量(上线数量) COMPLETE_QTY = 0, //完成数量 QUALIFIED_QTY = 0, //合格数量 PROCESS_STATE = 1, //准备完成 CREATION_DATE = DateTime.Now, //创建日期 CREATED_BY = CBaseData.LoginNO, //创建人 LAST_UPDATE_DATE = DateTime.Now, //最后修改日期 USE_FLAG = detail.USE_FLAG, //启用标识 REMARK = "", //备注 }; processCtrols.Add(process); } Cursor = Cursors.Wait; wsPLM.UseService(s => s.AddMesJobOrder(jobOrder)); foreach (MesProcessCtrol processCtrol in processCtrols) { wsPLM.UseService(s => s.AddMesProcessCtrol(processCtrol)); } Cursor = Cursors.Arrow; MessageBox.Show("换刀下单成功."); GridControlInvTool.ItemsSource = ws.UseService(s => s.GetTmsToolsMasters("USE_FLAG > 0 AND TOOLS_POSITION = 1")).OrderBy(n => n.CREATION_DATE).ToList();; }
/// <summary> /// 根据 直接 表达式 转换成 Lambda 表达式 /// </summary> /// <typeparam name="T">表达式方法类型</typeparam> /// <param name="propertyName">字段名</param> /// <param name="propertyValue">比较值</param> /// <param name="expression">直接表达式</param> /// <returns></returns> public static Expression <Func <T, bool> > GetExpressionByString <T>(string propertyName, object propertyValue, string expression) { expression = expression.Trim().ToLower(); string value = SafeConverter.SafeToStr(propertyValue); //转String if ((value.Length > 1) && (value[0] == '\'')) { value = value.Substring(1); if ((value.Length > 1) && (value[value.Length - 1] == '\'')) { value = value.Substring(0, value.Length - 1); } propertyValue = value; } //格式化类型 Type type = typeof(T); PropertyInfo propertyInfo = type.GetProperty(propertyName); //获取指定名称的属性 if (propertyInfo == null) { throw new Exception("条件中的字段名不存在,请检查。"); } propertyValue = SafeConverter.SafeToObject(propertyInfo.PropertyType, propertyValue); string lambadaExpression = $"{propertyName}{expression}@0"; object[] values = new object[] { propertyValue }; return(System.Linq.Dynamic.DynamicExpression.ParseLambda <T, bool>(lambadaExpression, values)); #region 获取Lambda表达式 - 之前的方法,已删除 //if ((expression == "=") || (expression == "==")) //{ // return CreateEqual<T>(propertyName, propertyValue); //} //else if (expression == "!=") //{ // return CreateNotEqual<T>(propertyName, propertyValue); //} //else if (expression == "like") //{ // return GetContains<T>(propertyName, propertyValue); //} //else if (expression == "notlike") //{ // return GetNotContains<T>(propertyName, propertyValue); //} //else if (expression == ">") //{ // return CreateGreaterThan<T>(propertyName, propertyValue); //} //else if (expression == ">=") //{ // return CreateGreaterThanOrEqual<T>(propertyName, propertyValue); //} //else if (expression == "<") //{ // return CreateLessThan<T>(propertyName, propertyValue); //} //else if (expression == "<=") //{ // return CreateLessThanOrEqual<T>(propertyName, propertyValue); //} //else //{ // return False<T>(); //} //#endregion //#region 获取Lambda表达式 //if ((expression == "=") || (expression == "==")) //{ // return CreateEqual<T>(propertyName, propertyValue); //} //else if (expression == "!=") //{ // return CreateNotEqual<T>(propertyName, propertyValue); //} //else if (expression == "like") //{ // return GetContains<T>(propertyName, propertyValue); //} //else if (expression == "notlike") //{ // return GetNotContains<T>(propertyName, propertyValue); //} //else if (expression == ">") //{ // return CreateGreaterThan<T>(propertyName, propertyValue); //} //else if (expression == ">=") //{ // return CreateGreaterThanOrEqual<T>(propertyName, propertyValue); //} //else if (expression == "<") //{ // return CreateLessThan<T>(propertyName, propertyValue); //} //else if (expression == "<=") //{ // return CreateLessThanOrEqual<T>(propertyName, propertyValue); //} //else //{ // return False<T>(); //} #endregion }
/// <summary> /// 自动计算标签值 /// 采用动态代码执行方式,编译一次,采用参数传入的方式执行 /// </summary> private void ThreadAutoCalculation() { Type dynamicCode = null; //获取编译后代码,调用该类用 List <FmsTagCalculation> TagCalculations = null; //计算规则 Dictionary <string, Dictionary <string, string> > FuncAndParamTagPKNO = new Dictionary <string, Dictionary <string, string> >(); //函数和对应参数的Tag的PKNO while (!CBaseData.AppClosing) { #region 暂停 if (bPause) { System.Threading.Thread.Sleep(200); continue; } #endregion try { int index; if (bRefreshAutoCal) //刷新计算规则 { WcfClient <IFMSService> wsThis = new WcfClient <IFMSService>(); TagCalculations = wsThis.UseService(s => s.GetFmsTagCalculations("USE_FLAG = 1")); bRefreshAutoCal = false; if ((TagCalculations == null) || (!TagCalculations.Any())) { Thread.Sleep(500); continue; } string className = "C" + Guid.NewGuid().ToString("N"); #region 形成执行的代码 string execCode = "using System; \r\n" + "using System.Text; \r\n" + "using System.Collections.Generic; \r\n" + "using BFM.Common.Base; \r\n\r\n"; execCode += "public class " + className + "\r\n" + "{ \r\n"; string basicFuc = "AutoCalculation"; index = 1; FuncAndParamTagPKNO.Clear(); foreach (FmsTagCalculation calculation in TagCalculations) { FmsAssetTagSetting tagResult = GetTagSettingById(calculation.RESULT_TAG_PKNO); //结果 string exp = calculation.CALCULATION_EXPRESSION; //表达式 string funcname = basicFuc + index.ToString(); //函数名称 Dictionary <string, string> paramTas = new Dictionary <string, string>(); //参数对应的标签的PKNO, param List <string> funcParam = new List <string>(); //带类型的参数 string code = ""; string resultType = "string"; //将标签替换成参数名 foreach (var line in exp.Split(new string[] { "\r\n" }, StringSplitOptions.None)) { string ret = line; #region 替换标签值,将标签替换成参数名 string[] expTags = line.Split('{'); for (int i = 0; i < expTags.Length; i++) { string str = expTags[i]; int length = str.IndexOf('}'); if (length < 0) //没有找到 } { continue; } string tagPKNO = str.Substring(0, length); //{ } 内为PKNO string param = "{" + tagPKNO + "}"; if (paramTas.ContainsKey(tagPKNO)) //已经添加了该参数 { param = paramTas[tagPKNO]; } else { FmsAssetTagSetting tag = GetTagSettingById(tagPKNO); if (tag == null) { continue; } param = "param" + paramTas.Count; paramTas.Add(tagPKNO, param); string paramType = "string"; //所有参数传入都是string型 //string paramType = // ((calculation.CALCULATION_TYPE == 2) || // (tag.VALUE_TYPE > 0 && tag.VALUE_TYPE < 20)) // ? "double" // : "string"; funcParam.Add(paramType + " " + param); } ret = ret.Replace("{" + tagPKNO + "}", param); } #endregion if (string.IsNullOrEmpty(code)) { code = " " + ret; } else { code += Environment.NewLine + " " + ret; } } //确定返回结果类型,将code语句转换成C#的语句 if (calculation.CALCULATION_TYPE == 1) //逻辑运算 { //(结果为1,0):({标签1}==1)&&({标签2}==1)&&({标签3}==0||{标签4}==0)&&({标签5}==1) code = code.Replace("AND", "&&").Replace("and", "&&").Replace("OR", "||").Replace("or", "||"); resultType = "bool"; } else if (calculation.CALCULATION_TYPE == 2) //数值运算 { //{标签1}+3+{标签2}+4 resultType = "double"; } else if (calculation.CALCULATION_TYPE == 3) //字符运算 { //{标签1}+"123" } else if (calculation.CALCULATION_TYPE == 12) //条件数值运算 { //{标签1}==3:{标签2}+1;{标签1}==4:{标签2}+2;{标签1}==5:{标签2}+3 resultType = "double"; List <string> exps = code.Split(';').ToList(); string temp = ""; foreach (var exp1 in exps) { if (exp1.Split(':').Length < 2) { continue; } temp += " if (" + exp1.Split(':')[0] + ") { return (" + exp1.Split(':')[1] + "); } \r\n"; } temp += " return 0; \r\n"; code = temp; } else if (calculation.CALCULATION_TYPE == 13) //条件字符运算 { //{标签1}==3:{标签1}+"123";{标签1}==4:{标签1}+"123" List <string> exps = code.Split(';').ToList(); string temp = ""; foreach (var exp1 in exps) { if (exp1.Split(':').Length < 2) { continue; } temp += " if (" + exp1.Split(':')[0] + ") { return (" + exp1.Split(':')[1] + ").ToString(); } \r\n"; } temp += " return \"\"; \r\n"; code = temp; } else if (calculation.CALCULATION_TYPE == 100) //C#脚本 { //支持C#语法,最后返回值(Double/String) resultType = "string"; } else //不支持的类型 { code = $" return \"计算类型[{calculation.CALCULATION_TYPE}],不支持的类型。\"; \r\n"; } execCode += DynamicCode.BuildExecFunc(funcname, resultType, code, funcParam); //增加一个函数 index++; FuncAndParamTagPKNO.Add(funcname, paramTas); //添加 } execCode += "}\r\n"; #endregion #region 编译代码 CodeDomProvider compiler = new CSharpCodeProvider(); CompilerParameters cp = new CompilerParameters() { GenerateExecutable = false, GenerateInMemory = true, }; cp.ReferencedAssemblies.Add("BFM.Common.Base.dll"); CompilerResults cr = compiler.CompileAssemblyFromSource(cp, execCode); if (cr.Errors.HasErrors) { NetLog.Error("DeviceMonitor.ThreadAutoCalculation Invaild Code: :" + execCode); } dynamicCode = cr.CompiledAssembly.GetType(className); //获取 #endregion } if ((TagCalculations == null) || (!TagCalculations.Any()) || (dynamicCode == null) || (FuncAndParamTagPKNO.Count <= 0)) { Thread.Sleep(500); continue; } #region 获取值 index = 0; foreach (FmsTagCalculation calculation in TagCalculations) { FmsAssetTagSetting tagResult = GetTagSettingById(calculation.RESULT_TAG_PKNO); //结果 if (tagResult == null) { continue; } if (FuncAndParamTagPKNO.Count < index) { break; } string funcName = FuncAndParamTagPKNO.Keys.ToList()[index]; var tagParms = FuncAndParamTagPKNO.Values.ToList()[index]; List <object> paramValues = new List <object>(); //参数值 foreach (var tagpkno in tagParms) //参数 { object value = null; FmsAssetTagSetting tagParam = GetTagSettingById(tagpkno.Key); if (tagParam != null) { value = SafeConverter.SafeToStr(tagParam.CUR_VALUE); //if ((calculation.CALCULATION_TYPE == 2) || (tagParam.VALUE_TYPE > 0 && tagParam.VALUE_TYPE < 20)) //{ // value = SafeConverter.SafeToDouble(tagParam.CUR_VALUE); //} //else //{ // value = SafeConverter.SafeToStr(tagParam.CUR_VALUE); //} } else { value = ""; } paramValues.Add(value); } object obj = dynamicCode.InvokeMember(funcName, BindingFlags.Public | BindingFlags.Static | BindingFlags.InvokeMethod, System.Type.DefaultBinder, null, paramValues.ToArray()); string newValue = ""; //新的计算结果 #region 更新结果 if (calculation.CALCULATION_TYPE == 1) //逻辑运算 { newValue = SafeConverter.SafeToBool(obj) ? "1" : "0"; } else { newValue = SafeConverter.SafeToStr(obj); } SaveData(tagResult.PKNO, newValue); //保存更新值 #endregion index++; } #endregion } catch (Exception e) { NetLog.Error("DeviceMonitor.ThreadAutoCalculation error:", e); } Thread.Sleep(100); } }
//排刀 private void bToolsBindDevice_Click(object sender, System.Windows.RoutedEventArgs e) { //排刀 string detailPKNO = SafeConverter.SafeToStr(ClassHelper.GetPropertyValue(gridToolsFinal.SelectedItem, "PKNO")); TmsDeviceToolsPos deviceToolsPos = wsTMS.UseService(s => s.GetTmsDeviceToolsPosById(detailPKNO)); if (deviceToolsPos == null) { return; } TmsToolsMaster toolsMaster = gridToolsInv.SelectedItem as TmsToolsMaster; if (toolsMaster == null) { MessageBox.Show($"请选择相应的库存刀具!", "排入刀具", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } TmsDeviceToolsPos check = wsTMS .UseService(s => s.GetTmsDeviceToolsPoss($"USE_FLAG = 1 AND DEVICE_PKNO = '{deviceToolsPos.DEVICE_PKNO}'")) .FirstOrDefault(c => c.TOOLS_PKNO == toolsMaster.PKNO || c.NEW_TOOLS_PKNO == toolsMaster.PKNO); #region 排刀 if (deviceToolsPos.TOOLS_STATE == 0) //空刀位 { if (check != null) { MessageBox.Show($"该刀具[{toolsMaster.TOOLS_CODE}]已经是{(check.TOOLS_STATE == 1 ? "在位" : "已排入")}状态,不能再排入!", "排入刀具", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } deviceToolsPos.TOOLS_STATE = 2; //已排入 //deviceToolsPos.TOOLS_PKNO = toolsMaster.PKNO; deviceToolsPos.NEW_TOOLS_PKNO = toolsMaster.PKNO; deviceToolsPos.UPDATED_BY = CBaseData.LoginName; deviceToolsPos.LAST_UPDATE_DATE = DateTime.Now; deviceToolsPos.UPDATED_INTROD += "【" + DateTime.Now + "】排入刀具. "; wsTMS.UseService(s => s.UpdateTmsDeviceToolsPos(deviceToolsPos)); } else if (deviceToolsPos.TOOLS_STATE == 1) //刀具在位 { MessageBox.Show($"刀位[{deviceToolsPos.TOOLS_POS_NO}]不为空,不能再排入刀。", "排入刀具", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } else if (deviceToolsPos.TOOLS_STATE == 2) //已排入 { if (MessageBox.Show($"刀位[{deviceToolsPos.TOOLS_POS_NO}]已经是排入状态,确定要!取消排入!吗?", "排入刀具", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning) != DialogResult.OK) { return; } deviceToolsPos.TOOLS_STATE = 0; //=>空 //deviceToolsPos.TOOLS_PKNO = ""; deviceToolsPos.NEW_TOOLS_PKNO = ""; deviceToolsPos.UPDATED_BY = CBaseData.LoginName; deviceToolsPos.LAST_UPDATE_DATE = DateTime.Now; deviceToolsPos.UPDATED_INTROD += "【" + DateTime.Now + "】取消排入. "; wsTMS.UseService(s => s.UpdateTmsDeviceToolsPos(deviceToolsPos)); } else if (deviceToolsPos.TOOLS_STATE == 2) //已经移除 => 更换 { if (check != null) { MessageBox.Show($"该刀具[{toolsMaster.TOOLS_CODE}]已经是{(check.TOOLS_STATE == 1 ? "在位" : "已排入")}状态,不能再排入!", "排入刀具", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } deviceToolsPos.TOOLS_STATE = 10; //=>更换 deviceToolsPos.NEW_TOOLS_PKNO = toolsMaster.PKNO; //刀具PKNO deviceToolsPos.UPDATED_BY = CBaseData.LoginName; deviceToolsPos.LAST_UPDATE_DATE = DateTime.Now; deviceToolsPos.UPDATED_INTROD += "【" + DateTime.Now + "】取消更换. "; wsTMS.UseService(s => s.UpdateTmsDeviceToolsPos(deviceToolsPos)); } else if (deviceToolsPos.TOOLS_STATE == 10) { if (MessageBox.Show($"刀位[{deviceToolsPos.TOOLS_POS_NO}]已经是更换刀具,确定要!取消更换!吗?", "排入刀具", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning) != DialogResult.OK) { return; } deviceToolsPos.TOOLS_STATE = 1; //刀具在位 deviceToolsPos.NEW_TOOLS_PKNO = ""; //清空刀号 deviceToolsPos.UPDATED_BY = CBaseData.LoginName; deviceToolsPos.LAST_UPDATE_DATE = DateTime.Now; deviceToolsPos.UPDATED_INTROD += "【" + DateTime.Now + "】取消更换刀具. "; wsTMS.UseService(s => s.UpdateTmsDeviceToolsPos(deviceToolsPos)); } #endregion GetPage(); }