ProcessExportAllViewModel.cs 49 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936
  1. using Aitex.Core.RT.Log;
  2. using Aitex.Core.UI.ControlDataContext;
  3. using Aitex.Core.Util;
  4. using Caliburn.Micro;
  5. using Caliburn.Micro.Core;
  6. using MECF.Framework.Common.CommonData;
  7. using MECF.Framework.Common.ControlDataContext;
  8. using MECF.Framework.Common.DataCenter;
  9. using MECF.Framework.Common.Utilities;
  10. using MECF.Framework.UI.Client.CenterViews.Configs.SystemConfig;
  11. using MECF.Framework.UI.Client.CenterViews.DataLogs.ProcessHistory;
  12. using MECF.Framework.UI.Client.CenterViews.Dialogs;
  13. using MECF.Framework.UI.Client.ClientBase;
  14. using OpenSEMI.ClientBase;
  15. using SciChart.Charting.Visuals;
  16. using SciChart.Charting.Visuals.Annotations;
  17. using SciChart.Charting.Visuals.Axes;
  18. using SciChart.Charting.Visuals.RenderableSeries;
  19. using SciChart.Data.Model;
  20. using System;
  21. using System.Collections.Concurrent;
  22. using System.Collections.Generic;
  23. using System.Collections.ObjectModel;
  24. using System.Data;
  25. using System.Diagnostics;
  26. using System.Drawing;
  27. using System.Linq;
  28. using System.Text;
  29. using System.Threading;
  30. using System.Threading.Tasks;
  31. using System.Windows;
  32. using static MECF.Framework.Common.FAServices.DataVariables;
  33. using Action = System.Action;
  34. using Media = System.Windows.Media;
  35. namespace MECF.Framework.UI.Client.CenterViews.DataLogs.ProcessHistory
  36. {
  37. class ProcessExportAllViewModel<T> : ModuleUiViewModelBase where T : IComparable
  38. {
  39. private ProcessExportAllView view;
  40. private CancellationTokenSource _cancellationTokenSource;
  41. private event EventHandler Exporting;
  42. private const int MAX_PARAMETERS = 1000;
  43. public List<ProcessHistoryLot> RecipeDatas { get; set; }
  44. private ObservableCollection<ParameterNode> _ParameterNodes;
  45. public ObservableCollection<ParameterNode> ParameterNodes
  46. {
  47. get { return _ParameterNodes; }
  48. set { _ParameterNodes = value; NotifyOfPropertyChange("ParameterNodes"); }
  49. }
  50. private Dictionary<string, string> _processDetailDisplayDic = new Dictionary<string, string>();
  51. // public ObservableCollection<IRenderableSeries> SelectedData { get; set; }
  52. public ObservableCollection<ParameterNode> GetParameters()
  53. {
  54. ObservableCollection<ParameterNode> rootNode = new ObservableCollection<ParameterNode>();
  55. try
  56. {
  57. Dictionary<string, string> displayDic = QueryDataClient.Instance.Service.GetData("System.ProcessDetailDisplay") as Dictionary<string, string>;
  58. if (displayDic == null)
  59. return rootNode;
  60. List<string> dataList = new List<string>();
  61. foreach (var key in displayDic.Keys)
  62. {
  63. string[] item = key.Split('.');
  64. if (item != null)
  65. {
  66. if (item.Length == 2)
  67. {
  68. _processDetailDisplayDic.Add($"{item[1]}", displayDic[key]);
  69. dataList.Add($"{item[0]}.{item[1]}");
  70. }
  71. else if (item.Length == 3)
  72. {
  73. _processDetailDisplayDic.Add($"{item[1]} {item[2]}", displayDic[key]);
  74. dataList.Add($"{item[0]}.{item[1]}.{item[2]}");
  75. }
  76. //if (item[0] == "MFC") // MFC.MFCN1.Set
  77. //{
  78. // if (item.Length > 2)
  79. // {
  80. // _processDetailDisplayDic.Add($"{item[1]} {item[2]}", displayDic[key]);
  81. // dataList.Add($"{item[0]}.{item[1]}.{item[2]}");
  82. // }
  83. //}
  84. //else if (item[0] == "MFM") // MFM.MFMH2.Actual
  85. //{
  86. // if (item.Length > 2)
  87. // {
  88. // _processDetailDisplayDic.Add($"{item[1]} {item[2]}", displayDic[key]);
  89. // dataList.Add($"{item[0]}.{item[1]}.{item[2]}");
  90. // }
  91. //}
  92. //else if (item[0] == "Heater") // Heater.Paddle Set.TopZone
  93. //{
  94. // if (item.Length > 2)
  95. // {
  96. // _processDetailDisplayDic.Add($"{item[1]} {item[2]}", displayDic[key]);
  97. // dataList.Add($"{item[0]}.{item[1]}.{item[2]}");
  98. // }
  99. //}
  100. //else // APC.Position Actual
  101. //{
  102. // if (item.Length == 2)
  103. // {
  104. // _processDetailDisplayDic.Add($"{item[1]}", displayDic[key]);
  105. // dataList.Add($"{item[0]}.{item[1]}");
  106. // }
  107. // else if (item.Length == 3)
  108. // {
  109. // _processDetailDisplayDic.Add($"{item[1]}.{item[2]}", displayDic[key]);
  110. // dataList.Add($"{item[0]}.{item[1]}.{item[2]}");
  111. // }
  112. //}
  113. }
  114. }
  115. //_keyValuePairs.Add("ChamberPressure", "PM1.ChamberPressure");
  116. //_keyValuePairs.Add("Position.Set", "PM1.APC.PositionSetPoint");
  117. //_keyValuePairs.Add("Position.Actual", "PM1.APC.PositionFeedback");
  118. //_keyValuePairs.Add("Pressure.Set", "PM1.APC.PressureSetPoint");
  119. //_keyValuePairs.Add("Pressure.Actual", "PM1.APC.PressureFeedback");
  120. //dataList.Add($"MFC.{SystemConfigProvider.Instance.GetValueByName($"PM1.MFC.MFCD1.GasName")}.Set");
  121. //dataList.Add($"MFC.{SystemConfigProvider.Instance.GetValueByName($"PM1.MFC.MFCD1.GasName")}.Actual");
  122. //dataList.Add($"MFC.{SystemConfigProvider.Instance.GetValueByName($"PM1.MFC.MFCJ1.GasName")}.Set");
  123. //dataList.Add($"MFC.{SystemConfigProvider.Instance.GetValueByName($"PM1.MFC.MFCJ1.GasName")}.Actual");
  124. //dataList.Add($"MFC.{SystemConfigProvider.Instance.GetValueByName($"PM1.MFC.MFCM1.GasName")}.Set");
  125. //dataList.Add($"MFC.{SystemConfigProvider.Instance.GetValueByName($"PM1.MFC.MFCM1.GasName")}.Actual");
  126. //dataList.Add($"MFC.{SystemConfigProvider.Instance.GetValueByName($"PM1.MFC.MFCM2.GasName")}.Set");
  127. //dataList.Add($"MFC.{SystemConfigProvider.Instance.GetValueByName($"PM1.MFC.MFCM2.GasName")}.Actual");
  128. //dataList.Add($"MFC.{SystemConfigProvider.Instance.GetValueByName($"PM1.MFC.MFCN1.GasName")}.Set");
  129. //dataList.Add($"MFC.{SystemConfigProvider.Instance.GetValueByName($"PM1.MFC.MFCN1.GasName")}.Actual");
  130. //dataList.Add($"MFC.{SystemConfigProvider.Instance.GetValueByName($"PM1.MFC.MFCN2.GasName")}.Set");
  131. //dataList.Add($"MFC.{SystemConfigProvider.Instance.GetValueByName($"PM1.MFC.MFCN2.GasName")}.Actual");
  132. //dataList.Add($"MFC.{SystemConfigProvider.Instance.GetValueByName($"PM1.MFC.MFCN3.GasName")}.Set");
  133. //dataList.Add($"MFC.{SystemConfigProvider.Instance.GetValueByName($"PM1.MFC.MFCN3.GasName")}.Actual");
  134. //dataList.Add($"MFC.{SystemConfigProvider.Instance.GetValueByName($"PM1.MFC.MFCNR.GasName")}.Set");
  135. //dataList.Add($"MFC.{SystemConfigProvider.Instance.GetValueByName($"PM1.MFC.MFCNR.GasName")}.Actual");
  136. //dataList.Add($"MFC.{SystemConfigProvider.Instance.GetValueByName($"PM1.MFC.MFCNX.GasName")}.Set");
  137. //dataList.Add($"MFC.{SystemConfigProvider.Instance.GetValueByName($"PM1.MFC.MFCNX.GasName")}.Actual");
  138. //dataList.Add($"MFC.{SystemConfigProvider.Instance.GetValueByName($"PM1.MFC.MFCNY.GasName")}.Set");
  139. //dataList.Add($"MFC.{SystemConfigProvider.Instance.GetValueByName($"PM1.MFC.MFCNY.GasName")}.Actual");
  140. //dataList.Add($"MFM.{SystemConfigProvider.Instance.GetValueByName($"PM1.MFM.MfmD1.Name")}.Set");
  141. //dataList.Add($"MFM.{SystemConfigProvider.Instance.GetValueByName($"PM1.MFM.MfmD1.Name")}.Actual");
  142. //_keyValuePairs.Add($"{SystemConfigProvider.Instance.GetValueByName($"PM1.MFC.MFCD1.GasName")}.Set", "PM1.MfcD1.SetPoint");
  143. //_keyValuePairs.Add($"{SystemConfigProvider.Instance.GetValueByName($"PM1.MFC.MFCD1.GasName")}.Actual", "PM1.MfcD1.Feedback");
  144. //_keyValuePairs.Add($"{SystemConfigProvider.Instance.GetValueByName($"PM1.MFC.MFCJ1.GasName")}.Set", "PM1.MfcJ1.SetPoint");
  145. //_keyValuePairs.Add($"{SystemConfigProvider.Instance.GetValueByName($"PM1.MFC.MFCJ1.GasName")}.Actual", "PM1.MfcJ1.Feedback");
  146. //_keyValuePairs.Add($"{SystemConfigProvider.Instance.GetValueByName($"PM1.MFC.MFCM1.GasName")}.Set", "PM1.MfcM1.SetPoint");
  147. //_keyValuePairs.Add($"{SystemConfigProvider.Instance.GetValueByName($"PM1.MFC.MFCM1.GasName")}.Actual", "PM1.MfcM1.Feedback");
  148. //_keyValuePairs.Add($"{SystemConfigProvider.Instance.GetValueByName($"PM1.MFC.MFCM2.GasName")}.Set", "PM1.MfcM2.SetPoint");
  149. //_keyValuePairs.Add($"{SystemConfigProvider.Instance.GetValueByName($"PM1.MFC.MFCM2.GasName")}.Actual", "PM1.MfcM2.Feedback");
  150. //_keyValuePairs.Add($"{SystemConfigProvider.Instance.GetValueByName($"PM1.MFC.MFCN1.GasName")}.Set", "PM1.MfcN1.SetPoint");
  151. //_keyValuePairs.Add($"{SystemConfigProvider.Instance.GetValueByName($"PM1.MFC.MFCN1.GasName")}.Actual", "PM1.MfcN1.Feedback");
  152. //_keyValuePairs.Add($"{SystemConfigProvider.Instance.GetValueByName($"PM1.MFC.MFCN2.GasName")}.Set", "PM1.MfcN2.SetPoint");
  153. //_keyValuePairs.Add($"{SystemConfigProvider.Instance.GetValueByName($"PM1.MFC.MFCN2.GasName")}.Actual", "PM1.MfcN2.Feedback");
  154. //_keyValuePairs.Add($"{SystemConfigProvider.Instance.GetValueByName($"PM1.MFC.MFCN3.GasName")}.Set", "PM1.MfcN3.SetPoint");
  155. //_keyValuePairs.Add($"{SystemConfigProvider.Instance.GetValueByName($"PM1.MFC.MFCN3.GasName")}.Actual", "PM1.MfcN3.Feedback");
  156. //_keyValuePairs.Add($"{SystemConfigProvider.Instance.GetValueByName($"PM1.MFC.MFCNR.GasName")}.Set", "PM1.MfcNR.SetPoint");
  157. //_keyValuePairs.Add($"{SystemConfigProvider.Instance.GetValueByName($"PM1.MFC.MFCNR.GasName")}.Actual", "PM1.MfcNR.Feedback");
  158. //_keyValuePairs.Add($"{SystemConfigProvider.Instance.GetValueByName($"PM1.MFC.MFCNX.GasName")}.Set", "PM1.MfcNX.SetPoint");
  159. //_keyValuePairs.Add($"{SystemConfigProvider.Instance.GetValueByName($"PM1.MFC.MFCNX.GasName")}.Actual", "PM1.MfcNX.Feedback");
  160. //_keyValuePairs.Add($"{SystemConfigProvider.Instance.GetValueByName($"PM1.MFC.MFCNY.GasName")}.Set", "PM1.MfcNY.SetPoint");
  161. //_keyValuePairs.Add($"{SystemConfigProvider.Instance.GetValueByName($"PM1.MFC.MFCNY.GasName")}.Actual", "PM1.MfcNY.Feedback");
  162. //_keyValuePairs.Add($"{SystemConfigProvider.Instance.GetValueByName($"PM1.MFM.MfmD1.Name")}.Set", "PM1.MfmD1._setpoint");
  163. //_keyValuePairs.Add($"{SystemConfigProvider.Instance.GetValueByName($"PM1.MFM.MfmD1.Name")}.Actual", "PM1.MfmD1.Feedback");
  164. //for (int i = 11; i <= 16; i++)
  165. //{
  166. // dataList.Add($"MFC.{SystemConfigProvider.Instance.GetValueByName($"PM1.MFC.MFC{i}.GasName")}.Set");
  167. // dataList.Add($"MFC.{SystemConfigProvider.Instance.GetValueByName($"PM1.MFC.MFC{i}.GasName")}.Actual");
  168. // _keyValuePairs.Add($"{SystemConfigProvider.Instance.GetValueByName($"PM1.MFC.MFC{i}.GasName")}.Set", $"PM1.Mfc{i}.SetPoint");
  169. // _keyValuePairs.Add($"{SystemConfigProvider.Instance.GetValueByName($"PM1.MFC.MFC{i}.GasName")}.Actual", $"PM1.Mfc{i}.Feedback");
  170. //}
  171. //for (int i = 1; i < 10; i += 2)
  172. //{
  173. // dataList.Add($"Heater.Inner {SystemConfigProvider.Instance.GetValueByName($"PM1.Heater.Heater{i}.DisplayName")}.Set");
  174. // dataList.Add($"Heater.Inner {SystemConfigProvider.Instance.GetValueByName($"PM1.Heater.Heater{i}.DisplayName")}.Actual");
  175. // _keyValuePairs.Add($"Inner {SystemConfigProvider.Instance.GetValueByName($"PM1.Heater.Heater{i}.DisplayName")}.Set", $"PM1.Heater{i}.TempSetPoint");
  176. // _keyValuePairs.Add($"Inner {SystemConfigProvider.Instance.GetValueByName($"PM1.Heater.Heater{i}.DisplayName")}.Actual", $"PM1.Heater{i}.TempFeedback");
  177. //}
  178. //for (int i = 2; i <= 10; i += 2)
  179. //{
  180. // dataList.Add($"Heater.Outer {SystemConfigProvider.Instance.GetValueByName($"PM1.Heater.Heater{i}.DisplayName")}.Set");
  181. // dataList.Add($"Heater.Outer {SystemConfigProvider.Instance.GetValueByName($"PM1.Heater.Heater{i}.DisplayName")}.Actual");
  182. // _keyValuePairs.Add($"Outer {SystemConfigProvider.Instance.GetValueByName($"PM1.Heater.Heater{i}.DisplayName")}.Set", $"PM1.Heater{i}.TempSetPoint");
  183. // _keyValuePairs.Add($"Outer {SystemConfigProvider.Instance.GetValueByName($"PM1.Heater.Heater{i}.DisplayName")}.Actual", $"PM1.Heater{i}.TempFeedback");
  184. //}
  185. Dictionary<string, ParameterNode> indexer = new Dictionary<string, ParameterNode>();
  186. foreach (string dataName in dataList)
  187. {
  188. string[] nodeName = dataName.Split('.');
  189. ParameterNode parentNode = null;
  190. string pathName = "";
  191. for (int i = 0; i < nodeName.Length; i++)
  192. {
  193. pathName = (i == 0 || i == 1) ? nodeName[i] : (pathName + " " + nodeName[i]);
  194. if (!indexer.ContainsKey(pathName))
  195. {
  196. indexer[pathName] = new ParameterNode() { Name = pathName, ChildNodes = new ObservableCollection<ParameterNode>(), ParentNode = parentNode };
  197. if (parentNode == null)
  198. {
  199. rootNode.Add(indexer[pathName]);
  200. }
  201. else
  202. {
  203. parentNode.ChildNodes.Add(indexer[pathName]);
  204. }
  205. }
  206. parentNode = indexer[pathName];
  207. }
  208. }
  209. SortParameterNode(rootNode, "Heater", 0);
  210. SortParameterNode(rootNode, "MFC", 1);
  211. SortParameterNode(rootNode, "Pressure", 2);
  212. SortParameterNode(rootNode, "Boat", 3);
  213. SortParameterNode(rootNode, "HeaterBand", 4);
  214. SortParameterNode(rootNode, "Valve", 5);
  215. }
  216. catch (Exception ex)
  217. {
  218. LOG.Write(ex);
  219. }
  220. return rootNode;
  221. }
  222. void SortParameterNode(ObservableCollection<ParameterNode> rootNode, string Name, int Index)
  223. {
  224. if (rootNode[Index].Name != Name)
  225. {
  226. for (int i = 0; i < rootNode.Count; i++)
  227. {
  228. rootNode[i].Selected = true;
  229. if (rootNode[i].Name == Name)
  230. {
  231. ParameterNode node = rootNode[i];
  232. rootNode.RemoveAt(i);
  233. rootNode.Insert(Index, node);
  234. }
  235. }
  236. }
  237. }
  238. private IRange _timeRange;
  239. public IRange VisibleRangeTime
  240. {
  241. get { return _timeRange; }
  242. set
  243. {
  244. _timeRange = value;
  245. NotifyOfPropertyChange(nameof(VisibleRangeTime));
  246. }
  247. }
  248. private IRange _VisibleRangeValue;
  249. public IRange VisibleRangeValue
  250. {
  251. get { return _VisibleRangeValue; }
  252. set { _VisibleRangeValue = value; NotifyOfPropertyChange(nameof(VisibleRangeValue)); }
  253. }
  254. private AnnotationCollection _annotations;
  255. public AnnotationCollection Annotations
  256. {
  257. get => _annotations;
  258. set
  259. {
  260. _annotations = value;
  261. InvokePropertyChanged(nameof(Annotations));
  262. }
  263. }
  264. //private PeriodicJob _thread;
  265. private List<StepInfo> _stepInfo = new List<StepInfo>();
  266. public List<StepInfo> StepInfo
  267. {
  268. get { return _stepInfo; }
  269. set { _stepInfo = value; this.NotifyOfPropertyChange(nameof(StepInfo)); }
  270. }
  271. private bool _isBusy = false;
  272. private string _busyIndicatorMessage;
  273. /// <summary>
  274. /// 设置或返回忙信息。
  275. /// </summary>
  276. public string BusyIndicatorContent
  277. {
  278. get => _busyIndicatorMessage;
  279. set
  280. {
  281. _busyIndicatorMessage = value;
  282. NotifyOfPropertyChange(nameof(BusyIndicatorContent));
  283. }
  284. }
  285. /// <summary>
  286. /// 设置或返回视图是否正忙。
  287. /// </summary>
  288. public bool IsBusy
  289. {
  290. get => _isBusy;
  291. set
  292. {
  293. _isBusy = value;
  294. NotifyOfPropertyChange(nameof(IsBusy));
  295. }
  296. }
  297. public ProcessExportAllViewModel(List<ProcessHistoryLot> recipes)
  298. {
  299. DisplayName = "Process Export";
  300. RecipeDatas = recipes;
  301. ParameterNodes = GetParameters();
  302. if (recipes == null || recipes.Count == 0)
  303. {
  304. return;
  305. }
  306. //SelectedData = new ObservableCollection<IRenderableSeries>();
  307. var now = DateTime.Now;
  308. VisibleRangeTime = new DateRange(DateTime.Now.AddMinutes(60), DateTime.Now.AddMinutes(-60));
  309. VisibleRangeValue = new DoubleRange(0, 10);
  310. Annotations = new AnnotationCollection();
  311. // _thread = new PeriodicJob(200, MonitorData, "ProcessExport", true);
  312. RecipeDatas.ToList().ForEach(recipe =>
  313. {
  314. QueryStep(recipe.StartTime, recipe.EndTime);
  315. });
  316. if (StepInfo != null && StepInfo.Count > 0)
  317. {
  318. StepStartTime = StepInfo.FirstOrDefault().StartTime;
  319. StepEndTime = StepInfo.LastOrDefault().EndTime;
  320. }
  321. else
  322. {
  323. if (recipes.Count > 0)
  324. {
  325. StepStartTime = recipes[0].StartTime;
  326. StepEndTime = recipes[0].EndTime;
  327. }
  328. }
  329. }
  330. public bool IsStepVisiable => RecipeDatas.Count == 1;
  331. public DateTime StepStartTime { get; set; }
  332. public DateTime StepEndTime { get; set; }
  333. private bool _isAdding;
  334. private static object _lockSelection = new object();
  335. private ConcurrentBag<QueryIndexer> _lstTokenTimeData = new ConcurrentBag<QueryIndexer>();
  336. public class QueryIndexer
  337. {
  338. public TimeChartDataLine DataLine { get; set; }
  339. public List<string> DataList { get; set; }
  340. public DateTime TimeToken { get; set; }
  341. }
  342. public class TimeChartDataLine : ChartDataLine<T>
  343. {
  344. public string Module { get; set; }
  345. public DateTime StartTime { get; set; }
  346. public DateTime EndTime { get; set; }
  347. public TimeChartDataLine(string dataName, string module, DateTime startTime, DateTime endTime) : base(dataName)
  348. {
  349. StartTime = startTime;
  350. EndTime = endTime;
  351. Module = module;
  352. }
  353. }
  354. private string _resolution;
  355. private AutoRange _autoRange;
  356. public AutoRange ChartAutoRange
  357. {
  358. get { return _autoRange; }
  359. set
  360. {
  361. _autoRange = value;
  362. NotifyOfPropertyChange(nameof(ChartAutoRange));
  363. }
  364. }
  365. public void QueryStep(DateTime starTime, DateTime endTime)//, string recipeName去掉查询recipeName名称,有嵌套调用
  366. {
  367. starTime = starTime.AddMinutes(-1);
  368. endTime = endTime.AddMinutes(1);
  369. string sql = $"SELECT * FROM \"process_data\" where (\"process_begin_time\" >= '{starTime:yyyy/MM/dd HH:mm:ss.fff}' and \"process_end_time\" <= '{endTime:yyyy/MM/dd HH:mm:ss.fff}') order by \"process_begin_time\" DESC;";
  370. DataTable dbData = QueryDataClient.Instance.Service.QueryData(sql);
  371. if (dbData != null && dbData.Rows.Count > 0)
  372. {
  373. List<ProcessDataLot> ProcessDataLotList = new List<ProcessDataLot>();
  374. for (int i = 0; i < dbData.Rows.Count; i++)
  375. {
  376. ProcessDataLot item = new ProcessDataLot();
  377. item.GUID = dbData.Rows[i]["guid"].ToString();
  378. item.RecipeName = dbData.Rows[i]["recipe_name"].ToString();
  379. item.ProcessStatus = dbData.Rows[i]["process_status"].ToString();
  380. item.WaferDataGUID = dbData.Rows[i]["wafer_data_guid"].ToString();
  381. item.ProcessIn = dbData.Rows[i]["process_in"].ToString();
  382. if (!dbData.Rows[i]["process_begin_time"].Equals(DBNull.Value))
  383. {
  384. item.ProcessBeginTime = (DateTime)dbData.Rows[i]["process_begin_time"];
  385. }
  386. if (!dbData.Rows[i]["process_end_time"].Equals(DBNull.Value))
  387. {
  388. item.ProcessEndTime = (DateTime)dbData.Rows[i]["process_end_time"];
  389. }
  390. ProcessDataLotList.Add(item);
  391. }
  392. // Annotations.Add(VerLine(Media.Brushes.Blue, ProcessDataLotList[0].ProcessBeginTime, Media.Brushes.Blue, $"{ProcessDataLotList[0].RecipeName}"));
  393. //Annotations.Add(VerLine(Media.Brushes.Blue, ProcessDataLotList[0].ProcessEndTime, Media.Brushes.Blue, $"Recipe End"));
  394. string sql2 = $"SELECT * FROM \"recipe_step_data\" where";
  395. sql2 += $" \"recipe_step_data\".\"process_data_guid\" = '{ProcessDataLotList[0].GUID.ToString()}'";
  396. sql2 += " order by \"step_begin_time\" ASC;";
  397. using (var table = QueryDataClient.Instance.Service.QueryData(sql2))
  398. {
  399. if (!(table == null || table.Rows.Count == 0))
  400. {
  401. for (int i = 0; i < table.Rows.Count; i++)
  402. {
  403. var item = table.Rows[i];
  404. string startStepTime = "";
  405. string endStepTime = "";
  406. double stepTime = 0;
  407. string subRecipeStepNumber = "";
  408. string subRecipeStepTime = "";
  409. string subRecipeStepName = "";
  410. string subRecipeLoopInfo = "";
  411. string tempCorrection = "";
  412. string tempPid = "";
  413. if (!item["step_begin_time"].Equals(DBNull.Value))
  414. startStepTime = ((DateTime)item["step_begin_time"]).ToString("yyyy/MM/dd HH:mm:ss.fff");
  415. if (!item["step_end_time"].Equals(DBNull.Value))
  416. {
  417. endStepTime = ((DateTime)item["step_end_time"]).ToString("yyyy/MM/dd HH:mm:ss.fff");
  418. }
  419. if (!item["step_time"].Equals(DBNull.Value))
  420. {
  421. stepTime = (float)item["step_time"];
  422. }
  423. if (!item["sub_recipe_step_time"].Equals(DBNull.Value))
  424. {
  425. subRecipeStepTime = item["sub_recipe_step_time"].ToString();
  426. }
  427. if (!item["sub_recipe_step_number"].Equals(DBNull.Value))
  428. {
  429. subRecipeStepNumber = item["sub_recipe_step_number"].ToString();
  430. }
  431. if (!item["sub_recipe_step_name"].Equals(DBNull.Value))
  432. {
  433. subRecipeStepName = item["sub_recipe_step_name"].ToString();
  434. }
  435. if (!item["sub_recipe_loop_info"].Equals(DBNull.Value))
  436. {
  437. subRecipeLoopInfo = item["sub_recipe_loop_info"].ToString();
  438. }
  439. if (!item["temp_correction"].Equals(DBNull.Value))
  440. {
  441. tempCorrection = item["temp_correction"].ToString().Replace(",", ":");
  442. }
  443. if (!item["temp_pid"].Equals(DBNull.Value))
  444. {
  445. tempPid = item["temp_pid"].ToString().Replace(",", ":");
  446. }
  447. string stepNo = item["step_number"].ToString();
  448. string stepName = item["step_name"].ToString();
  449. if (DateTime.TryParse(startStepTime, out DateTime StartTime) && DateTime.TryParse(endStepTime, out DateTime EndTime))
  450. {
  451. //Annotations.Add(VerLine(Media.Brushes.AliceBlue, StartTime, Media.Brushes.Blue, $"{stepNo}"));
  452. if (EndTime < StartTime.AddSeconds(stepTime))
  453. {
  454. EndTime = StartTime.AddSeconds(stepTime);
  455. }
  456. _stepInfo.Add(new StepInfo()
  457. {
  458. StartTime = StartTime,
  459. EndTime = EndTime,
  460. StepName = stepName,
  461. StepTime = stepTime,
  462. StepNo = stepNo,
  463. StepEndTime = StartTime.AddSeconds(stepTime),
  464. SubRecipeStepNumber = subRecipeStepNumber,
  465. SubRecipeStepTime = subRecipeStepTime,
  466. SubRecipeStepName = subRecipeStepName,
  467. SubRecipeLoopInfo = subRecipeLoopInfo,
  468. TempCorrection = tempCorrection,
  469. TempPid = tempPid,
  470. });
  471. }
  472. }
  473. }
  474. }
  475. }
  476. }
  477. protected override void OnViewLoaded(object view)
  478. {
  479. base.OnViewLoaded(view);
  480. useMaxRow = (int)QueryDataClient.Instance.Service.GetConfig("System.SetUp.ExportMaxRow");
  481. this.view = (ProcessExportAllView)view;
  482. }
  483. List<string> nodeOrigin = new List<string>();
  484. void GetNode(ParameterNode pNode, bool Selected)
  485. {
  486. foreach (var item in pNode.ChildNodes)
  487. {
  488. if (item.ChildNodes.Count > 0)
  489. {
  490. GetNode(item, Selected);
  491. }
  492. else
  493. {
  494. //if(item.Selected == true)
  495. {
  496. nodeOrigin.Add(item.Name);
  497. }
  498. }
  499. }
  500. }
  501. public static int DivideAndRoundUp(int dividend, int divisor)
  502. {
  503. int result = dividend / divisor;
  504. int remainder = dividend % divisor;
  505. if (remainder > 0)
  506. {
  507. result++;
  508. }
  509. return result;
  510. }
  511. private int useMaxRow = 25000;
  512. string csv = ",";
  513. public async void ExportAll()
  514. {
  515. try
  516. {
  517. nodeOrigin.Clear();
  518. if (StepStartTime.Year == 1 || StepEndTime.Year == 1)
  519. {
  520. MessageBox.Show("No data is available in the selected period!", "Export", MessageBoxButton.OK, MessageBoxImage.Warning);
  521. return;
  522. }
  523. foreach (var node in ParameterNodes)
  524. {
  525. if (node.Selected == true)
  526. {
  527. GetNode(node, node.Selected);
  528. }
  529. }
  530. if (nodeOrigin.Count == 0)
  531. {
  532. MessageBox.Show($"Please select the data you want to export.", "Export", MessageBoxButton.OK,
  533. MessageBoxImage.Warning);
  534. return;
  535. }
  536. Microsoft.Win32.SaveFileDialog dlg = new Microsoft.Win32.SaveFileDialog();
  537. dlg.DefaultExt = ".csv"; // Default file extension
  538. dlg.Filter = "Excel数据表格文件(*.csv)|*.csv"; // Filter files by extension
  539. dlg.FileName = $"{DisplayName}_{string.Join(",", RecipeDatas.Select(x => x.RecipeName).ToArray())}_{DateTime.Now:yyyyMMdd_HHmmss}";
  540. Nullable<bool> result = dlg.ShowDialog();// Show open file dialog box
  541. if (result == true) // Process open file dialog box results
  542. {
  543. BusyIndicatorContent = "Exporting start ...";
  544. IsBusy = true;
  545. Exporting?.Invoke(this, System.EventArgs.Empty);
  546. _cancellationTokenSource = new CancellationTokenSource();
  547. //System.Data.DataSet ds = new System.Data.DataSet();
  548. //var sw = new Stopwatch();
  549. //sw.Restart();
  550. //BusyIndicatorContent = "Create table header start ...";
  551. //ds.Tables.Add(new System.Data.DataTable($"{DisplayName}_{DateTime.Now:yyyyMMdd_HHmmss}"));
  552. //ds.Tables[0].Columns.Add("Recipe Info");
  553. //ds.Tables[0].Columns[0].DataType = typeof(string);
  554. //ds.Tables[0].Columns.Add("Date");
  555. //ds.Tables[0].Columns[1].DataType = typeof(string);
  556. //ds.Tables[0].Columns.Add("Time");
  557. //ds.Tables[0].Columns[2].DataType = typeof(string);
  558. //ds.Tables[0].Columns.Add("Step ID");
  559. //ds.Tables[0].Columns[3].DataType = typeof(string);
  560. //ds.Tables[0].Columns.Add("Step Name");
  561. //ds.Tables[0].Columns[4].DataType = typeof(string);
  562. StringBuilder stringBuilder = new StringBuilder();
  563. stringBuilder.AppendLine($"Recipe Info{csv}Date{csv}Time{csv}Step ID{csv}Step Name");
  564. Dictionary<T, double[]> timeValue = new Dictionary<T, double[]>();
  565. await Task.Run(() =>
  566. {
  567. for (int i = 0; i < nodeOrigin.Count; i++)
  568. {
  569. //List<Tuple<T, double>> data = (nodeOrigin[i] as ChartDataLine<T>).Points;
  570. //foreach (var tuple in data)
  571. //{
  572. // if (!timeValue.ContainsKey(tuple.Item1))
  573. // timeValue[tuple.Item1] = new double[nodeOrigin.Count];
  574. // timeValue[tuple.Item1][i] = tuple.Item2;
  575. //}
  576. // ds.Tables[0].Columns.Add(nodeOrigin[i]);
  577. // ds.Tables[0].Columns[i + 5].DataType = typeof(double);
  578. }
  579. stringBuilder.AppendLine($"Recipe:{string.Join(",", RecipeDatas.Select(x => x.RecipeName).ToArray())}");
  580. stringBuilder.AppendLine($"Start Time{csv}{string.Join(",", RecipeDatas.Select(x => x.StartTime).ToArray())}{csv}{string.Join(",", RecipeDatas.Select(x => x.StartTime).ToArray())}");
  581. stringBuilder.AppendLine($"End Time{csv}{string.Join(",", RecipeDatas.Select(x => x.EndTime).ToArray())}{csv}{string.Join(",", RecipeDatas.Select(x => x.EndTime).ToArray())}");
  582. FileHelper.Instance.SaveText(dlg.FileName, stringBuilder.ToString());
  583. //var recipeInfoRow = ds.Tables[0].NewRow();
  584. //recipeInfoRow[0] = $"Recipe:{string.Join(",", RecipeDatas.Select(x => x.RecipeName).ToArray())}";
  585. //ds.Tables[0].Rows.Add(recipeInfoRow);
  586. //recipeInfoRow = ds.Tables[0].NewRow();
  587. //recipeInfoRow[0] = $"Start Time";
  588. //recipeInfoRow[1] = string.Join(",", RecipeDatas.Select(x => x.StartTime).ToArray());
  589. //recipeInfoRow[2] = string.Join(",", RecipeDatas.Select(x => x.StartTime).ToArray());
  590. //ds.Tables[0].Rows.Add(recipeInfoRow);
  591. //recipeInfoRow = ds.Tables[0].NewRow();
  592. //recipeInfoRow[0] = $"End Time";
  593. //recipeInfoRow[1] = string.Join(",", RecipeDatas.Select(x => x.EndTime).ToArray());
  594. //recipeInfoRow[2] = string.Join(",", RecipeDatas.Select(x => x.EndTime).ToArray());
  595. //ds.Tables[0].Rows.Add(recipeInfoRow);
  596. //var rowCaption = ds.Tables[0].NewRow();
  597. //for (int i = 0; i < ds.Tables[0].Columns.Count; i++)
  598. //{
  599. // rowCaption[i] = ds.Tables[0].Columns[i].Caption;
  600. //}
  601. //ds.Tables[0].Rows.Add(rowCaption);
  602. //for (int i = 0; i < ds.Tables[0].Columns.Count; i++)
  603. //{
  604. // ds.Tables[0].Columns[i].Caption = null;
  605. //}
  606. DateTime startTime = startTime = StepStartTime;
  607. QueryDataClientFromTable(dlg.FileName);
  608. }, _cancellationTokenSource.Token).ContinueWith(t =>
  609. {
  610. if (t.IsCanceled || t.IsFaulted)
  611. {
  612. IsBusy = false;
  613. return;
  614. }
  615. });
  616. if (_cancellationTokenSource?.Token.IsCancellationRequested == true)
  617. {
  618. IsBusy = false;
  619. return;
  620. }
  621. BusyIndicatorContent = "Data is written to Excel file ...";
  622. IsBusy = false;
  623. MessageBox.Show($"Export succeed, file save as {dlg.FileName}", "Export", MessageBoxButton.OK, MessageBoxImage.Information);
  624. Window window = Window.GetWindow(this.view);
  625. window.Close();
  626. }
  627. }
  628. catch (Exception ex)
  629. {
  630. LOG.Write(ex);
  631. MessageBox.Show("Write failed," + ex.Message, "export failed", MessageBoxButton.OK, MessageBoxImage.Warning);
  632. IsBusy = false;
  633. }
  634. }
  635. private void QueryDataClientFromTable(string fileName)
  636. {
  637. DateTime startTime = StepStartTime;
  638. DateTime endTime = StepEndTime;
  639. List<string> keys = new List<string>(nodeOrigin);
  640. List<string> pmList = new List<string>();
  641. List<string> systemList = new List<string>();
  642. if (keys != null && keys.Count > 0)
  643. {
  644. foreach (var dataKey in keys)
  645. {
  646. var dataId = _processDetailDisplayDic.ContainsKey(dataKey) ? _processDetailDisplayDic[dataKey] : dataKey;
  647. var module = dataId.Split('.').ToList()[0];
  648. if (module.ToLower() == "pm1")
  649. {
  650. pmList.Add(dataId);
  651. }
  652. else if (module.ToLower() == "system")
  653. {
  654. systemList.Add(dataId);
  655. // systemList.Add(string.Format("\"{0}\"", dataId));
  656. }
  657. }
  658. }
  659. if (StepStartTime.Date == StepEndTime.Date)
  660. {
  661. SaveDataToTable(fileName, pmList, systemList, startTime, endTime);
  662. }
  663. else
  664. {
  665. endTime = new DateTime(startTime.Year, startTime.Month, startTime.Day, 23, 59, 59);
  666. while (endTime < StepEndTime)
  667. {
  668. SaveDataToTable(fileName, pmList, systemList, startTime, endTime);
  669. startTime = new DateTime(startTime.Year, startTime.Month, startTime.Day, 0, 0, 0).AddDays(1);
  670. endTime = new DateTime(startTime.Year, startTime.Month, startTime.Day, 23, 59, 59);
  671. }
  672. SaveDataToTable(fileName, pmList, systemList, startTime, StepEndTime);
  673. }
  674. }
  675. private bool firstHeader = false;
  676. private Dictionary<string, string> GetReverseDict()
  677. {
  678. Dictionary<string, string> keyValuePairs = new Dictionary<string, string>();
  679. foreach (var kvp in _processDetailDisplayDic)
  680. {
  681. if (!keyValuePairs.ContainsKey(kvp.Value))
  682. keyValuePairs[kvp.Value] = kvp.Key.Trim().Contains(" ") ? kvp.Key.Trim().Substring(kvp.Key.Trim().LastIndexOf(" ") + 1) : kvp.Key;
  683. }
  684. return keyValuePairs;
  685. }
  686. private void SaveDataToTable(string fileName, List<string> pmList, List<string> systemList, DateTime startTime, DateTime endTime)
  687. {
  688. string stepID = "", stepName = "", subRecipeLoopInfo = "", subRecipeStepName = "", subRecipeStepNumber = "", tempCorrection = "", tempPid = "";
  689. DataTable pmDataTable = null;
  690. Dictionary<string, string> reverseDict = GetReverseDict();
  691. var columnsql = $"select column_name from information_schema.columns where table_name = '{startTime.ToString("yyyyMMdd")}.PM1'";
  692. var columnTable = QueryDataClient.Instance.Service.QueryData(columnsql);
  693. List<string> col = columnTable.Rows.Cast<DataRow>().Select(x => x.ItemArray[0].ToString()).ToList();
  694. pmList = pmList.Where(x => col.Any(y => y == x)).ToList();
  695. string pmsql = $"select time AS InternalTimeStamp, {string.Join(",", pmList.Select(x => string.Format("\"{0}\"", x)))}";
  696. DataTable systemDataTable = null;
  697. pmsql += string.Format(" from \"{0}\" where time > {1} and time <= {2} order by time asc",
  698. startTime.ToString("yyyyMMdd") + "." + "PM1", startTime.Ticks, endTime.Ticks);
  699. BusyIndicatorContent = "Example Query PM data ...";
  700. pmDataTable = QueryDataClient.Instance.Service.QueryData(pmsql);
  701. if (pmDataTable != null)
  702. {
  703. foreach (DataRow item in pmDataTable.Rows)
  704. {
  705. if (item.Table.Columns.Contains("PM1.APC.ModeFeedback"))
  706. {
  707. if (item.Table.Columns.Contains("PM1.APC.PressureSetPoint"))
  708. {
  709. if (item.Field<float>("PM1.APC.ModeFeedback") != 7 && item.Field<float>("PM1.APC.ModeFeedback") != 8)
  710. {
  711. item["PM1.APC.PressureSetPoint"] = 0;
  712. }
  713. }
  714. if (item.Table.Columns.Contains("PM1.APC.PositionSetPoint"))
  715. {
  716. if (item.Field<float>("PM1.APC.ModeFeedback") != 2)
  717. {
  718. item["PM1.APC.PositionSetPoint"] = 0;
  719. }
  720. }
  721. if (item.Table.Columns.Contains("PM1.APC.SlowRateSetPoint"))
  722. {
  723. if (item.Field<float>("PM1.APC.ModeFeedback") != 12)
  724. {
  725. item["PM1.APC.SlowRateSetPoint"] = 0;
  726. }
  727. }
  728. }
  729. }
  730. }
  731. var sysColumnsql = $"select column_name from information_schema.columns where table_name = '{startTime.ToString("yyyyMMdd")}.System'";
  732. var sysColumnTable = QueryDataClient.Instance.Service.QueryData(sysColumnsql);
  733. List<string> systemCol = sysColumnTable.Rows.Cast<DataRow>().Select(x => x.ItemArray[0].ToString()).ToList();
  734. systemList = systemList.Where(x => systemCol.Any(y => y == x)).ToList();
  735. string systemsql = $"select time AS InternalTimeStamp, {string.Join(",", systemList.Select(x => string.Format("\"{0}\"", x)))}";
  736. systemsql += string.Format(" from \"{0}\" where time > {1} and time <= {2} order by time asc",
  737. startTime.ToString("yyyyMMdd") + "." + "System", startTime.Ticks, endTime.Ticks);
  738. BusyIndicatorContent = "Example Query System data ...";
  739. systemDataTable = QueryDataClient.Instance.Service.QueryData(systemsql);
  740. int maxRow = 0;
  741. if ((pmDataTable == null || pmDataTable.Rows.Count == 0))
  742. {
  743. if (systemDataTable != null)
  744. {
  745. maxRow = systemDataTable.Rows.Count;
  746. }
  747. }
  748. else if ((systemDataTable == null || systemDataTable.Rows.Count == 0))
  749. {
  750. if (pmDataTable != null)
  751. {
  752. maxRow = pmDataTable.Rows.Count;
  753. }
  754. }
  755. else
  756. {
  757. maxRow = pmDataTable.Rows.Count > systemDataTable.Rows.Count ? systemDataTable.Rows.Count : pmDataTable.Rows.Count;
  758. }
  759. var subColNames = new List<DataColumn>() {
  760. new DataColumn("SubRecipeStepName"),
  761. new DataColumn("SubRecipeStepNumber"),
  762. new DataColumn("SubRecipeLoopInfo"),
  763. new DataColumn("TempCorrection"),
  764. new DataColumn("TempPid"),
  765. };
  766. BusyIndicatorContent = "Data is saved to excel Table ...";
  767. StringBuilder stringBuilder = new StringBuilder();
  768. if (!firstHeader)
  769. {
  770. firstHeader = true;
  771. var sssss = $"{csv}{csv}{csv}{csv}{csv}{string.Join($"{csv}", subColNames.Cast<DataColumn>())} {csv}{string.Join($"{csv}", systemDataTable.Columns.Cast<DataColumn>().Where(x => x.ColumnName != "internaltimestamp").Select(x => reverseDict.ContainsKey(x.ColumnName) ? reverseDict[x.ColumnName] : x.ColumnName))} {csv}{string.Join($"{csv}", pmDataTable.Columns.Cast<DataColumn>().Where(x => x.ColumnName != "internaltimestamp").Select(x => reverseDict.ContainsKey(x.ColumnName) ? reverseDict[x.ColumnName] : x.ColumnName))}";
  772. stringBuilder.AppendLine($"{csv}{csv}{csv}{csv}{csv}{string.Join($"{csv}", subColNames.Cast<DataColumn>())} {csv}{string.Join($"{csv}", systemDataTable.Columns.Cast<DataColumn>().Where(x => x.ColumnName != "internaltimestamp").Select(x => reverseDict.ContainsKey(x.ColumnName) ? reverseDict[x.ColumnName] : x.ColumnName))} {csv}{string.Join($"{csv}", pmDataTable.Columns.Cast<DataColumn>().Where(x => x.ColumnName != "internaltimestamp").Select(x => reverseDict.ContainsKey(x.ColumnName) ? reverseDict[x.ColumnName] : x.ColumnName))}");
  773. }
  774. for (int i = 0; i < maxRow; i++)
  775. {
  776. BusyIndicatorContent = $"Total data {maxRow} current {i + 1} ...";
  777. var pmRow = pmDataTable != null && pmDataTable.Rows.Count > 0 ? pmDataTable.Rows[i] : null;
  778. var systemRow = systemDataTable != null && systemDataTable.Rows.Count > 0 ? systemDataTable.Rows[i] : null;
  779. //float timeIndex = 0;
  780. //float.TryParse(item.Key.ToString(), out timeIndex);
  781. //DateTime dateTimeKey = startTime.AddMilliseconds(timeIndex * 1000); ;// DateTime.Parse(item.Key.ToString());
  782. DateTime dateTimeKey = new DateTime(systemRow != null ? (long)systemRow[0] : (long)pmRow[0]);
  783. var tempStepInfo = _stepInfo.OrderByDescending(x => x.StartTime).Where(x => x.StartTime <= dateTimeKey).FirstOrDefault();
  784. if (tempStepInfo != null)// && dateTimeKey > _stepInfo[iIndex].StartTime && x.StepEndTime >= dateTimeKey
  785. {
  786. stepID = tempStepInfo.StepNo;
  787. stepName = tempStepInfo.StepName;
  788. subRecipeStepName = tempStepInfo.SubRecipeStepName;
  789. subRecipeStepNumber = tempStepInfo.SubRecipeStepNumber;
  790. subRecipeLoopInfo = !string.IsNullOrEmpty(tempStepInfo.SubRecipeLoopInfo) ? tempStepInfo.SubRecipeLoopInfo.Replace("/", "|") : tempStepInfo.SubRecipeLoopInfo;
  791. tempCorrection = !string.IsNullOrEmpty(tempStepInfo.TempCorrection) ? tempStepInfo.TempCorrection : "";
  792. tempPid = !string.IsNullOrEmpty(tempStepInfo.TempPid) ? tempStepInfo.TempPid : "";
  793. }
  794. if (pmRow == null && systemRow != null)
  795. {
  796. stringBuilder.AppendLine($"{csv}{dateTimeKey.ToString("yyyy/MM/dd")}{csv}{dateTimeKey.ToString("HH:mm:ss:fff")}{csv}{stepID}{csv}{stepName}{csv}{subRecipeStepName}{csv}{subRecipeStepNumber}{csv}{subRecipeLoopInfo}{csv}{tempCorrection}{csv}{tempPid}{csv}{string.Join($"{csv}", systemRow.ItemArray.ToList().GetRange(1, systemRow.ItemArray.Count() - 1).Select(x => x.ToString()))}{csv}{string.Join($"{csv}", Enumerable.Repeat("", pmDataTable.Columns.Count).ToArray())}");
  797. }
  798. else if (pmRow != null && systemRow == null)
  799. {
  800. stringBuilder.AppendLine($"{csv}{dateTimeKey.ToString("yyyy/MM/dd")}{csv}{dateTimeKey.ToString("HH:mm:ss:fff")}{csv}{stepID}{csv}{stepName}{csv}{subRecipeStepName}{csv}{subRecipeStepNumber}{csv}{subRecipeLoopInfo}{csv}{tempCorrection}{csv}{tempPid}{csv}{string.Join($"{csv}", Enumerable.Repeat("", systemDataTable.Columns.Count).ToArray())}{csv}{string.Join($"{csv}", pmRow.ItemArray.ToList().GetRange(1, pmRow.ItemArray.Count() - 1).Select(x => x.ToString()))}");
  801. }
  802. else
  803. {
  804. stringBuilder.AppendLine($"{csv}{dateTimeKey.ToString("yyyy/MM/dd")}{csv}{dateTimeKey.ToString("HH:mm:ss:fff")}{csv}{stepID}{csv}{stepName}{csv}{subRecipeStepName}{csv}{subRecipeStepNumber}{csv}{subRecipeLoopInfo}{csv}{tempCorrection}{csv}{tempPid}{csv}{string.Join($"{csv}", systemDataTable.Rows[i].ItemArray.ToList().GetRange(1, systemDataTable.Rows[i].ItemArray.Count() - 1).Select(x => x.ToString()))}{csv}{string.Join($"{csv}", pmDataTable.Rows[i].ItemArray.ToList().GetRange(1, pmDataTable.Rows[i].ItemArray.Count() - 1).Select(x => x.ToString()))}");
  805. }
  806. if (i == maxRow - 1)
  807. {
  808. var str = stringBuilder.ToString();
  809. str = str.TrimEnd((new char[] { '\r', '\n' }));
  810. FileHelper.Instance.SaveNewLineDataToTxt(fileName, str, true);
  811. stringBuilder.Clear();
  812. }
  813. }
  814. }
  815. static string CheckAndReplace(string input)
  816. {
  817. if (input.StartsWith("PM1"))
  818. {
  819. return input.Substring(4);
  820. }
  821. if (input.StartsWith("System"))
  822. {
  823. return input.Substring(7);
  824. }
  825. return input;
  826. }
  827. /// <summary>
  828. /// 取消查询。
  829. /// </summary>
  830. public void CancelQuery()
  831. {
  832. Task.Run(() =>
  833. {
  834. if (_cancellationTokenSource?.Token.CanBeCanceled == true)
  835. {
  836. _cancellationTokenSource.Cancel();
  837. }
  838. Thread.Sleep(100);
  839. //_progQueryUpdate.Report(new ProgressUpdatingEventArgs(100, 100, ""));
  840. //_progChartSuspendUpdating.Report(false);
  841. });
  842. }
  843. }
  844. }