public async void Convert()
        {
            // 20190608 created, 現在要匯入批價檔

            #region Environment

            try
            {
                // 營造環境
                Process[] isAdvn = Process.GetProcessesByName("THCAdvancedBillingReport");
                if (isAdvn.Length == 0)     // 測試"日報表清單"是否有打開
                {
                    // 有無登入系統?
                    Thesis.LogIN();
                    // 如果沒有打開就打開"日報表清單"
                    AutoItX.Run(@"C:\Program Files (x86)\THESE\杏雲醫療資訊系統\THCAdvancedBillingReport.exe", @"C:\Program Files (x86)\THESE\杏雲醫療資訊系統\");
                    System.Threading.Thread.Sleep(300);
                }
                // [FrmMain] v1.0.0.67
                AutoItX.WinWaitActive("[FrmMain] v");
                // [NAME:btnDailyIncome]
                // 按下去
                AutoItX.ControlClick("[FrmMain] v", "", "[NAME:btnDailyIncome]");
                AutoItX.WinWaitActive("日收入報表A");
                // 日收入報表A
                // [NAME:chk允許完整筆數呈現]
                AutoItX.ControlClick("日收入報表A", "", "[NAME:chk允許完整筆數呈現]");
                // [NAME:chkIncludeInvalid]
                AutoItX.ControlClick("日收入報表A", "", "[NAME:chkIncludeInvalid]");

                BeginDate = $"{_begindate.Year}{(_begindate.Month + 100).ToString().Substring(1)}{(_begindate.Day + 100).ToString().Substring(1)}";
                EndDate   = $"{_enddate.Year}{(_enddate.Month + 100).ToString().Substring(1)}{(_enddate.Day + 100).ToString().Substring(1)}";
                string Execution = $"C:\\vpn\\exe\\changeBillDTP.exe {BeginDate}{EndDate}";
                AutoItX.Run(Execution, @"C:\vpn\exe\");

                log.Info($"執行changeBillDTP ");
            }
            catch (Exception ex)
            {
                Logging.Record_error(ex.Message);
                log.Error(ex.Message);
            }

            #endregion Environment

            // 資料都從excel檔讀進記憶體, 也寫入csv檔
            Dictionary <string, object[, ]> data = RetrievePIJIA();

            // 空值就結束, 沒有後面什麼事
            if (data is null)
            {
                return;
            }

            string strYM = $"{_begindate.Year - 1911}{(_begindate.Month + 100).ToString().Substring(1)}";
            List <Task <PIJIAresult> > tasks = new List <Task <PIJIAresult> >();

            #region 進行讀取資料

            // 20190609 created
            // 模仿匯入opd
            // add及update, update要清空CASENO, G
            // 20190612 重大修改,key值改為三個YM, bid, uid, 原因是bid在同一個月內重複太多了
            // 用varchar, 不要用varchar,不然比較時會出錯, VDATE空值仍會有8個空白
            try
            {
                // 開始回圈
                // 讀取每一筆檔案
                log.Info($"begin async process.");
                foreach (var d in data)
                {
                    // 20200519 程式碼移出, 程式不那麼臃腫, 較好維護
                    tasks.Add(WriteIntoSQL_async(d.Value, strYM));
                }
                PIJIAresult[] result = await Task.WhenAll(tasks);

                int total_NewPIJIA = (from p in result
                                      select p.NewPIJIA).Sum();
                int total_ChangePIJIA = (from p in result
                                         select p.ChangePIJIA).Sum();
                int total_AllPIJIA = (from p in result
                                      select p.AllPIJIA).Sum();

                log.Info($"end async process.");

                string output = $"共處理{total_AllPIJIA}筆資料, 其中{total_NewPIJIA}筆新批價, 修改{total_ChangePIJIA}筆批價.";
                log.Info(output);
                tb.ShowBalloonTip("完成", output, BalloonIcon.Info);
                Logging.Record_admin("PIJIA add/change", output);

                // 20200522 為何這裡有個return? 除掉就可以用後面的matching了
                //return;
            }
            catch (Exception ex)
            {
                Logging.Record_error(ex.Message);
            }

            #endregion 進行讀取資料

            // 20200519 移出程式碼, 不要顯得太臃腫
            Matching();
        }
Exemple #2
0
        public void Change()
        {
            // Dim output As DEP_return = Change_DEP(strYM)
            // MessageBox.Show("修改了" + output.m.ToString + "筆, 請匯入門診資料")
            string   savepath = @"C:\vpn\change_dep";
            int      change_N;
            DateTime minD;
            DateTime maxD;
            List <sp_change_depResult> ListChange;

            // 存放目錄,不存在就要建立一個
            if (!(System.IO.Directory.Exists(savepath)))
            {
                System.IO.Directory.CreateDirectory(savepath);
            }

            #region Making CSV

            try
            {
                // 呼叫SQL stored procedure
                using (CSDataContext dc = new CSDataContext())
                {
                    ListChange = dc.sp_change_dep(_strYM).ToList();
                }

                // 自動產生名字
                string savefile = $"\\change_dep_{_strYM}_{DateTime.Now.Year}{(DateTime.Now.Month + 100).ToString().Substring(1)}";
                savefile += $"{(DateTime.Now.Day + 100).ToString().Substring(1)}_{DateTime.Now.TimeOfDay}";
                savefile  = savefile.Replace(":", "").Replace(".", "");
                savepath += $"{savefile}.csv";

                // 製作csv檔 writing to csv
                System.IO.StreamWriter sw = new System.IO.StreamWriter(savepath);
                int i = 1;
                change_N = ListChange.Count;
                if (change_N == 0)
                {
                    tb.ShowBalloonTip("完成", "沒有什麼需要修改的", BalloonIcon.Info);
                    log.Info("change department: 沒有什麼需要修改的");
                    Logging.Record_admin("change department", "沒有什麼需要修改的");
                }
                else
                {
                    minD = DateTime.Parse("9999/12/31");
                    maxD = DateTime.Parse("0001/01/01");
                    foreach (var c in ListChange)
                    {
                        sw.Write(c.o); // 欄位名叫o
                        if (i < change_N)
                        {
                            sw.Write(sw.NewLine);
                        }
                        DateTime tempD = DateTime.Parse($"{c.o.Substring(0, 4)}/{c.o.Substring(4, 2)}/{c.o.Substring(6, 2)}");
                        // 找尋最大的值
                        if (tempD.CompareTo(maxD) > 0)
                        {
                            maxD = tempD;
                        }
                        // 找尋最小的值
                        if (tempD.CompareTo(minD) < 0)
                        {
                            minD = tempD;
                        }
                        i++;
                    }
                    // 20200518 放在foreach的loop迴圈裡是錯誤的, 我把它放出來了
                    string output = $"{minD:d}~{maxD:d}, 共{change_N}筆需要修改";
                    tb.ShowBalloonTip("需修改:", output, BalloonIcon.Info);
                    log.Info($"change department: {output}");
                    Logging.Record_admin("change department", output);
                    sw.Close();
                }
            }
            catch (System.Exception ex)
            {
                Logging.Record_error(ex.Message);
                log.Error(ex.Message);
                return;
            }

            #endregion Making CSV

            #region Environment

            try
            {
                // 營造環境
                if (AutoItX.WinExists("看診清單") == 1) //如果直接存在就直接叫用
                {
                    AutoItX.WinActivate("看診清單");
                }
                else
                {
                    Thesis.LogIN();
                    // 打開"看診清單"
                    AutoItX.Run(@"C:\Program Files (x86)\THESE\杏雲醫療資訊系統\THCClinic.exe", @"C:\Program Files (x86)\THESE\杏雲醫療資訊系統\");
                    AutoItX.WinWaitActive("看診清單");
                    AutoItX.WinActivate("看診清單");
                }
            }
            catch (Exception ex)
            {
                Logging.Record_error(ex.Message);
                log.Error(ex.Message);
                return;
            }

            #endregion Environment

            #region Execute change department

            try
            {
                string strD_o = string.Empty;
                string strV_o = string.Empty;
                string strR_o = string.Empty;

                foreach (var c in ListChange)
                {
                    string strD_n  = c.o.Substring(0, 8);
                    string strV_n  = c.o.Substring(8, 1);
                    string strR_n  = c.o.Substring(9, 2);
                    bool   changed = false;

                    string strNr  = c.o.Substring(11, 3);
                    string strDEP = c.o.Substring(14, 2);

                    // 先檢查是否換日, 如果有就換到新日期;
                    if (strD_n != strD_o)
                    {
                        // 製造3個AutoIT VB程式, 1. changeDP_DATE, 針對"看診清單", [NAME:dtpSDate]
                        // 一個參數, 格式YYYYMMDD
                        AutoItX.Run($"C:\\vpn\\exe\\changeDP_DATE.exe {strD_n}", @"C:\vpn\exe\");
                        log.Info($"Change Date from {strD_o} to {strD_n}.  Then sleep 1000ms.");
                        strD_o  = strD_n;
                        changed = true;
                        AutoItX.Sleep(1000);
                    }

                    // 再檢查是否換午別, 如果有就換到新的午別
                    if (strV_n != strV_o)
                    {
                        // 製造3個AutoIT VB程式, 2. changeDP_VIST, 針對"看診清單", [NAME:cmbVist]
                        // 一個參數, 格式V
                        AutoItX.Run($"C:\\vpn\\exe\\changeDP_VIST.exe {strV_n}", @"C:\vpn\exe\");
                        log.Info($"Change Vist from {strV_o} to {strV_n}. Then sleep 1000ms.");
                        strV_o  = strV_n;
                        changed = true;
                        AutoItX.Sleep(1000);
                    }

                    // 最後檢查是否換診間, 如果有就換到新的診間
                    if (strR_n != strR_o)
                    {
                        // 製造3個AutoIT VB程式, 3. changeDP_ROOM, 針對"看診清單", [NAME:cmbRmno]
                        // 一個參數, 格式RR
                        AutoItX.Run($"C:\\vpn\\exe\\changeDP_ROOM.exe {strR_n}", @"C:\vpn\exe\");
                        log.Info($"Change Date from {strR_o} to {strR_n}. Then sleep 1000ms.");
                        strR_o  = strR_n;
                        changed = true;
                        AutoItX.Sleep(1000);
                    }

                    if (changed)
                    {
                        AutoItX.ControlClick("看診清單", "", "[NAME:btnRefresh]");
                        log.Info($"Press Refresh button. [NAME:btnRefresh].");
                        AutoItX.WinWaitActive("看診清單");
                        changed = false;
                    }

                    // 按下新的號碼;
                    // Seq NO
                    // 輸入診號
                    AutoItX.ControlSend("看診清單", "", "[NAME:txbSqno]", strNr);
                    log.Info($"Enter {strNr}.");

                    // 按鈕
                    AutoItX.ControlClick("看診清單", "", "[NAME:btnGo]");
                    log.Info($"Press GO button. [NAME:btnGo].");

                    // 進入問診畫面
                    AutoItX.WinWaitActive("問診畫面");
                    AutoItX.Sleep(500);

                    // 製造一個AutoIT VB程式, changeDP_DEP, 針對"問診畫面"[NAME:cmbDept]
                    // 一個參數, 格式DD
                    AutoItX.Run($"C:\\vpn\\exe\\changeDP_DEP.exe {strDEP}", @"C:\vpn\exe\");

                    AutoItX.Sleep(500);
                    int idx = 0;

                    // 先問「此病患已批價, 是否繼續?」, THCClinic, 還可能問重大傷病, 超過8種藥物, 可能有重複用藥畫面
                    do
                    {
                        AutoItX.Send("{F9}");
                        AutoItX.Sleep(100);
                        idx++; // time out for 10 sec at most
                    } while (AutoItX.WinExists("THCClinic") == 0 && idx < 100);

                    // 下一個畫面「確定要重複開立收據」,
                    // 一定會有「已經批價」, 可能會有「重大傷病身分」, 可能會有「八種以上藥物]
                    // 可能會有「跨院重複開立醫囑提示」
                    idx = 0;
                    do
                    {
                        if (AutoItX.WinExists("THCClinic") == 1)
                        {
                            AutoItX.ControlClick("THCClinic", "", "[CLASSNN:Button1]");
                        }
                        if (AutoItX.WinExists("跨院重複開立醫囑提示") == 1)
                        {
                            AutoItX.ControlClick("跨院重複開立醫囑提示", "", "[NAME:OK_Button]");
                        }
                        AutoItX.Sleep(100);
                        idx++; // time out for 10 sec at most
                    } while (AutoItX.WinExists("These.CludCln.Accounting") == 0 && idx < 100);

                    // 是否重印收據
                    AutoItX.WinWaitActive("These.CludCln.Accounting");
                    AutoItX.ControlClick("These.CludCln.Accounting", "", "[CLASSNN:Button2]");
                    AutoItX.Sleep(1000);
                }

                Logging.Record_admin("change department", $"修改了{change_N}筆");
                tb.ShowBalloonTip("完成", $"修改了{change_N}筆, 請匯入門診資料.", BalloonIcon.Info);
            }
            catch (Exception ex)
            {
                Logging.Record_error(ex.Message);
                log.Error(ex.Message);
                return;
            }

            #endregion Execute change department
        }
        public void Convert()
        {
            log.Info("  Begin Convert.");

            string output;

            #region Environment

            try
            {
                // 營造環境
                log.Info("  Check 處方清單.");
                if (AutoItX.WinExists("處方清單") == 1) //如果直接存在就直接叫用
                {
                    AutoItX.WinActivate("處方清單");
                    log.Info("  處方清單 exists.");
                }
                else
                {
                    log.Info("  處方清單 doesn't exist.");
                    Thesis.LogIN();
                    // 打開"處方清單", 找不到control,只好用mouse去按
                    AutoItX.WinActivate("杏雲雲端醫療服務");
                    // 先maximize
                    AutoItX.WinSetState("杏雲雲端醫療服務", "", 3);  //0 close; 1 @SW_RESTORE; 2 @SW_MINIMIZE; 3 @SW_MAXIMIZE
                    AutoItX.MouseMove(280, 280);
                    AutoItX.MouseClick();
                    AutoItX.Sleep(500);
                    AutoItX.ControlClick("杏雲雲端醫療服務", "", "[NAME:btnPrescription]");
                    log.Info("  處方清單 opened.");
                    Thread.Sleep(10000);
                }

                // 打開備份
                AutoItX.WinWaitActive("處方清單");
                AutoItX.ControlClick("處方清單", "", "[NAME:btnBackup]");
                log.Info("  處方清單 exists.");
                AutoItX.WinActivate("處方清單備份選項");
                AutoItX.WinWaitActive("處方清單備份選項");
                AutoItX.ControlClick("處方清單備份選項", "", "[NAME:txbBackupPath]", "LEFT", 2);
                AutoItX.Send("{Tab}");
                AutoItX.Send("{Tab}");
                AutoItX.Send("{Enter}"); // first choice Desktop
                                         // 這裡的等待很重要, 太短來不及讀, 500可以, 100 不行, 200 一半一半, 250 100%
                AutoItX.Sleep(300);
                // 尋找XML, 若有就刪除
                output  = AutoItX.ControlGetText("處方清單備份選項", "", "[NAME:txbBackupPath]");
                output += $"\\{_begindate.Year}\\{_begindate.Year}{(_begindate.Month + 100).ToString().Substring(1)}.xml";
                if (System.IO.File.Exists(output))
                {
                    System.IO.File.Delete(output);
                }
                log.Info("  Kill xml files.");

                // AutoItX.ControlSend("處方清單備份選項", "", "[NAME:txbBackupPath]", "C:\vpn")
            }
            catch (Exception ex)
            {
                output = string.Empty;
                log.Error($"  Error. {ex.Message}");
                Logging.Record_error(ex.Message);
            }

            #endregion Environment

            #region Producing XML

            string BeginDate = $"{_begindate.Year}{(_begindate.Month + 100).ToString().Substring(1)}{(_begindate.Day + 100).ToString().Substring(1)}";
            string EndDate   = $"{_enddate.Year}{(_enddate.Month + 100).ToString().Substring(1)}{(_enddate.Day + 100).ToString().Substring(1)}";
            // changePresDTP 是用AutoIT VB寫成的, 功能專一是針對「處方清單備份選項」的起迄日 [NAME:dtpSDate], [NAME:dtpEDate]
            // 只有一個參數, 格式為YYYYMMDDYYYYMMDD, 前面8碼是起始日, 後面8碼是結束日
            string Execution = $"C:\\vpn\\exe\\changePresDTP.exe {BeginDate}{EndDate}";
            AutoItX.Run(Execution, @"C:\vpn\exe\");
            // 檢查XML做好了嗎?
            do
            {
                // log.Info("  Wait for xml to build.");
                // 好多紀錄啊, 大約4.9 秒
                Thread.Sleep(100);
            } while (!System.IO.File.Exists(output));
            // XML好了就把頁面關掉
            AutoItX.Sleep(500);
            AutoItX.ControlClick("處方清單備份選項", "", "[NAME:Cancel_Button]");
            AutoItX.Sleep(100);
            AutoItX.ControlClick("處方清單", "", "[NAME:BtnEXIT]");

            #endregion Producing XML

            OPDconvert o = new OPDconvert(output);
            o.Transform();

            log.Info("  End Convert.");
        }
Exemple #4
0
        public async Task Convert(Progress <ProgressReportModel> progress)
        {
            Microsoft.Office.Interop.Excel.Application MyExcel = new Microsoft.Office.Interop.Excel.Application();

            #region Environment

            // 殺掉所有的EXCEL
            foreach (Process p in Process.GetProcessesByName("EXCEL"))
            {
                p.Kill();
            }

            // 營造環境
            // 各類資料維護
            // 計價標準維護      (這就是我們的標的)
            if (AutoItX.WinExists("計價標準檔維護") == 1) //如果直接存在就直接叫用
            {
                AutoItX.WinActivate("計價標準檔維護");
            }
            else
            {
                if (AutoItX.WinExists("各類資料維護") == 1)
                {
                    AutoItX.WinActivate("各類資料維護");
                }
                else
                {
                    Thesis.LogIN();
                    // 從"杏雲雲端醫療服務"叫用"各類資料維護"
                    // 打開"處方清單", 找不到control,只好用mouse去按
                    AutoItX.WinActivate("杏雲雲端醫療服務");
                    // 先maximize
                    AutoItX.WinSetState("杏雲雲端醫療服務", "", 3);  //0 close; 1 @SW_RESTORE; 2 @SW_MINIMIZE; 3 @SW_MAXIMIZE
                    AutoItX.MouseClick("LEFT", AutoItX.WinGetPos("杏雲雲端醫療服務").X + 200, AutoItX.WinGetPos("杏雲雲端醫療服務").Y + 175);
                    AutoItX.Sleep(500);
                    AutoItX.ControlClick("杏雲雲端醫療服務", "", "[NAME:btnDBaseMaint]");
                }
                // 從"各類資料維護"叫用"計價標準檔維護"
                AutoItX.Sleep(10000);
                AutoItX.ControlSetText("各類資料維護", "", "[NAME:txbQuery]", "計價標準檔維護");
                // AutoItX.ControlSend("各類資料維護", "", "[NAME:txbQuery]", "計價標準檔維護")
                AutoItX.ControlClick("各類資料維護", "", "[NAME:btnQuery]");
                AutoItX.MouseClick("LEFT", AutoItX.WinGetPos("各類資料維護").X + 100, AutoItX.WinGetPos("各類資料維護").Y + 135, 2);
                log.Info("Click inquiry.");
                //AutoItX.Sleep(2000);
                //AutoItX.WinActivate("計價標準檔維護");
            }

            log.Info("Start to Click.");
            do
            {
                // 20200517 一直按到行為止
                // 20190610 模仿昨天成功的經驗
                // 打開EXCEL檔
                AutoItX.Send("{Alt}");
                AutoItX.Send("{Down}");
                AutoItX.Send("{Down}");
                AutoItX.Send("{Down}");
                AutoItX.Send("{Down}");
                AutoItX.Send("{Down}");
                AutoItX.Send("{Down}");
                // 20200319 修改程式,再往下一格
                AutoItX.Send("{Down}");
                AutoItX.Send("{Enter}");
                AutoItX.Sleep(10000);
            } while (Process.GetProcessesByName("EXCEL").Length == 0);
            log.Info("Excel exists now.");

            MyExcel = (Microsoft.Office.Interop.Excel.Application)Marshal.GetActiveObject("Excel.Application");
            do
            {
                AutoItX.Sleep(100);
            } while (!MyExcel.Visible);
            log.Info("Excel appears now.");

            #endregion Environment

            #region Saving XLSX files

            // ====================================================================================================================================
            // 製作自動檔名
            string temp_filepath = @"C:\vpn\odr";
            // 20190609 因為不小心多一個空格, 搞了好久除錯, 很辛苦啊
            // System.Runtime.InteropServices.COMException '發生例外狀況於 HRESULT: 0x800A03EC'
            // 存放目錄,不存在就要建立一個
            if (!System.IO.Directory.Exists(temp_filepath))
            {
                System.IO.Directory.CreateDirectory(temp_filepath);
            }
            // 自動產生名字
            string temp_file = $"\\odr_{DateTime.Now.Year}{(DateTime.Now.Month + 100).ToString().Substring(1)}";
            temp_file     += $"{(DateTime.Now.Day + 100).ToString().Substring(1)}_{DateTime.Now.TimeOfDay}";
            temp_file      = temp_file.Replace(":", "").Replace(".", "");
            temp_filepath += $"{temp_file}.xlsx";
            // wb.SaveAs(temp_filepath, Excel.XlFileFormat.xlCSV, vbNull, vbNull, False, False, Excel.XlSaveAsAccessMode.xlNoChange, vbNull, vbNull, vbNull, vbNull, vbNull)
            Microsoft.Office.Interop.Excel.Workbook wb = MyExcel.ActiveWorkbook;
            wb.SaveAs(temp_filepath, Microsoft.Office.Interop.Excel.XlFileFormat.xlOpenXMLWorkbook);
            Microsoft.Office.Interop.Excel.Worksheet ws = wb.ActiveSheet;

            #endregion Saving XLSX files

            // 丟出的是一個object [,]
            ODRconvert odr = new ODRconvert(ws.UsedRange.Value2);
            await odr.Transform(progress);

            #region Ending

            // 殺掉所有的EXCEL
            foreach (Process p in Process.GetProcessesByName("EXCEL"))
            {
                p.Kill();
            }
            AutoItX.WinClose("計價標準檔維護");
            AutoItX.WinClose("各類資料維護");

            #endregion Ending
        }
Exemple #5
0
        public async Task Convert(Progress <ProgressReportModel> progress)
        {
            Microsoft.Office.Interop.Excel.Application MyExcel = new Microsoft.Office.Interop.Excel.Application();

            #region Environment

            // 殺掉所有的EXCEL
            foreach (Process p in Process.GetProcessesByName("EXCEL"))
            {
                p.Kill();
            }
            // 營造環境
            Process[] isCust = Process.GetProcessesByName("THCustomerFilter"); // 處方清單
            if (isCust.Length == 0)                                            // 如果沒有打開
            {
                // 測試"看診清單"是否有打開
                Thesis.LogIN();
                // 打開"各類特殊 追蹤與紀錄查詢"
                AutoItX.Run(@"C:\Program Files (x86)\THESE\杏雲醫療資訊系統\THCustomerFilter.exe", @"C:\Program Files (x86)\THESE\杏雲醫療資訊系統\");
                System.Threading.Thread.Sleep(2000);
            }
            // 準備好
            AutoItX.WinActivate("各類特殊 追蹤與紀錄查詢");
            AutoItX.WinWaitActive("各類特殊 追蹤與紀錄查詢");
            AutoItX.ControlClick("各類特殊 追蹤與紀錄查詢", "", "[NAME:chk允許完整筆數呈現]");
            AutoItX.Sleep(1000);
            // [NAME:btn病歷號查詢]
            AutoItX.ControlClick("各類特殊 追蹤與紀錄查詢", "", "[NAME:btn病歷號查詢]");
            AutoItX.Sleep(1000);
            // 病歷號查詢
            // [NAME:TextBox]
            // [NAME:OKButton]
            AutoItX.ControlSend("病歷號查詢", "", "[NAME:TextBox]", "0000000001~9999999999");
            AutoItX.ControlClick("病歷號查詢", "", "[NAME:OKButton]");
            log.Info("Click inquiry.");
            //AutoItX.WinWaitActive("各類特殊 追蹤與紀錄查詢");
            //AutoItX.WinWaitActive("各類特殊 追蹤與紀錄查詢");
            //log.Info("WinWait ends.");
            //AutoItX.Sleep(20000);

            // 20190610 模仿昨天成功的經驗
            // [NAME:btn匯出EXCEL]
            // aut.WinWait("[dlgPrintMethodAsk]",, 1000)
            // aut.ControlClick("[dlgPrintMethodAsk]", "", "[NAME:OK_Button]")

            log.Info("Start to Click.");
            do
            {
                AutoItX.ControlClick("各類特殊 追蹤與紀錄查詢", "", "[NAME:btn匯出EXCEL]");
                AutoItX.Sleep(10000);
                log.Info("Click export one time.");
            } while (Process.GetProcessesByName("EXCEL").Length == 0);
            log.Info("Excel exists now.");

            // aut.Sleep(10000), 用等的,等10秒大多有效,但不能保證,且也許不用10秒,這樣就浪費了, 應該要個別化
            // 好在發現visibility可以有效等到整個檔案製作完成
            MyExcel = (Microsoft.Office.Interop.Excel.Application)Marshal.GetActiveObject("Excel.Application");
            do
            {
                AutoItX.Sleep(100);
            } while (!MyExcel.Visible);
            log.Info("Excel appears now.");

            #endregion Environment

            #region Saving XLSX files

            // ====================================================================================================================================
            // 製作自動檔名
            string temp_filepath = @"C:\vpn\pt";
            // 20190609 因為不小心多一個空格, 搞了好久除錯, 很辛苦啊
            // System.Runtime.InteropServices.COMException '發生例外狀況於 HRESULT: 0x800A03EC'
            // 存放目錄,不存在就要建立一個
            if (!System.IO.Directory.Exists(temp_filepath))
            {
                System.IO.Directory.CreateDirectory(temp_filepath);
            }
            // 自動產生名字
            string temp_file = $"\\pt_{DateTime.Now.Year}{(DateTime.Now.Month + 100).ToString().Substring(1)}";
            temp_file     += $"{(DateTime.Now.Day + 100).ToString().Substring(1)}_{DateTime.Now.TimeOfDay}";
            temp_file      = temp_file.Replace(":", "").Replace(".", "");
            temp_filepath += $"{temp_file}.xlsx";
            // wb.SaveAs(temp_filepath, Excel.XlFileFormat.xlCSV, vbNull, vbNull, False, False, Excel.XlSaveAsAccessMode.xlNoChange, vbNull, vbNull, vbNull, vbNull, vbNull)
            Microsoft.Office.Interop.Excel.Workbook wb = MyExcel.ActiveWorkbook;
            wb.SaveAs(temp_filepath, Microsoft.Office.Interop.Excel.XlFileFormat.xlOpenXMLWorkbook);
            Microsoft.Office.Interop.Excel.Worksheet ws = wb.ActiveSheet;

            #endregion Saving XLSX files

            // 丟出的是一個object [,]
            PTconvert pt = new PTconvert(ws.UsedRange.Value2);
            await pt.Transform(progress);


            #region Ending

            // 殺掉所有的EXCEL
            foreach (Process p in Process.GetProcessesByName("EXCEL"))
            {
                p.Kill();
            }
            AutoItX.WinClose("各類特殊 追蹤與紀錄查詢");

            #endregion Ending
        }