ProcessExportAllViewModel.cs 51 KB

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