Exemple #1
0
        private string DefaultCommand2()
        {
            if (Variables == null)
            {
                throw new Exception("建立 Bar chart 指令時,未給定 Variables");
            }

            Mtb.Column[] vars = (Mtb.Column[])Variables;
            Mtb.Column[] gps  = null;
            if (GroupingVariables != null)
            {
                gps = (Mtb.Column[])GroupingVariables;
            }

            switch (BarsRepresent)// 以一次畫一張圖為目的,過濾掉不合法的輸入數量
            {
            case ChartRepresent.COUNT_OF_UNIQUE_VALUES:
            case ChartRepresent.A_FUNCTION_OF_A_VARIABLE:
            case ChartRepresent.ONE_WAY_TABLE:
                if (vars.Length > 1)
                {
                    throw new ArgumentException(
                              string.Format("BarsRepresent={0}時,不支援同時繪製多變數", BarsRepresent.ToString()));
                }
                break;
            }
            switch (BarsRepresent)// 判斷群組數是否合法
            {
            case ChartRepresent.ONE_WAY_TABLE:
            case ChartRepresent.TWO_WAY_TABLE:
                if (gps == null)
                {
                    throw new Exception("(Bar chart)使用 Summaried Data,至少給定一個分群欄位");
                }
                break;
            }


            StringBuilder cmnd = new StringBuilder(); // local macro 內容

            cmnd.AppendLine("macro");
            cmnd.AppendLine("chart y.1-y.n;");
            cmnd.AppendLine("group x.1-x.m;");
            cmnd.AppendLine("pane p.1-p.k;"); //如果使用者有指定 panel
            cmnd.AppendLine("datlab dlab.");  //如果使用者有自己指定 column for datlab

            cmnd.AppendLine("mcolumn y.1-y.n");
            cmnd.AppendLine("mcolumn x.1-x.m");
            cmnd.AppendLine("mcolumn p.1-p.k");
            cmnd.AppendLine("mcolumn yy ylab stkdlab dlab xx.1-xx.m");
            cmnd.AppendLine("mconstant nn");

            //準備使用於圖中的額外資料
            Datlab tmpDatlab = (Datlab)DataLabel.Clone();

            if (StackType == ChartStackType.Stack && DataLabel.Visible && AdjDatlabAtStackBar)
            {
                #region 建立 Adjust stack bar chart 要的 datlab
                switch (BarsRepresent)
                {
                case ChartRepresent.COUNT_OF_UNIQUE_VALUES:
                    cmnd.AppendLine("count y.1 nn");
                    cmnd.AppendLine("set yy");
                    cmnd.AppendLine("(1)nn");
                    cmnd.AppendLine("end");
                    cmnd.AppendLine("stat yy;");
                    cmnd.AppendLine("by y.1 x.1-x.m;");
                    cmnd.AppendLine("sums stkdlab.");
                    break;

                case ChartRepresent.A_FUNCTION_OF_A_VARIABLE:
                    cmnd.AppendLine("stat y.1;");
                    cmnd.AppendLine("by x.1-x.m;");
                    cmnd.AppendFormat("{0} stkdlab.\r\n",
                                      FuncType.ToString().ToLower() == "sum" ? "sums" : FuncType.ToString().ToLower());
                    break;

                case ChartRepresent.ONE_WAY_TABLE:
                    cmnd.AppendLine("copy y.1 stkdlab");
                    break;

                case ChartRepresent.TWO_WAY_TABLE:
                    cmnd.AppendLine("stack y.1-y.n yy.");
                    cmnd.AppendLine("count y.1 nn");
                    cmnd.AppendLine("tset ylab");
                    cmnd.AppendFormat("1({0})nn\r\n",
                                      string.Join(" &\r\n", vars.Select(x => "\"" + x.Name + "\"").ToArray()));
                    cmnd.AppendLine("end");
                    List <string[]> gpData = new List <string[]>();
                    for (int i = 0; i < gps.Length; i++)
                    {
                        Mtb.Column col = gps[i];
                        string[]   data;
                        switch (col.DataType)
                        {
                        case MtbDataTypes.DataUnassigned:
                            throw new ArgumentNullException("輸入的欄位沒有資料");

                        default:
                        case MtbDataTypes.DateTime:
                        case MtbDataTypes.Numeric:
                            data = ((double[])col.GetData()).Select(x => x.ToString()).ToArray();
                            break;

                        case MtbDataTypes.Text:
                            data = col.GetData();
                            break;
                        }
                        cmnd.AppendFormat("tset xx.{0}\r\n", i + 1);
                        cmnd.AppendFormat("{1}({0})1\r\n",
                                          string.Join(" &\r\n", data.Select(x => "\"" + x + "\"").ToArray()),
                                          vars.Length);
                        cmnd.AppendLine("end");
                        cmnd.AppendLine("vorder ylab xx.1-xx.m;");
                        cmnd.AppendLine("work.");
                        cmnd.AppendLine("stat yy;");
                        cmnd.AppendLine("by ylab xx.1-xx.m;");
                        cmnd.AppendLine("sums stkdlab.");
                    }
                    break;

                default:
                    break;
                }
                cmnd.AppendLine("text stkdlab stkdlab");
                #endregion

                tmpDatlab.LabelColumn = "stkdlab";
                tmpDatlab.Placement   = new double[] { 0, -1 };
            }
            else
            {
                if (DataLabel.LabelColumn != null)
                {
                    tmpDatlab.LabelColumn = "dlab";
                }
            }

            switch (BarsRepresent)
            {
            case ChartRepresent.COUNT_OF_UNIQUE_VALUES:
                cmnd.AppendLine("Chart y.1-y.n;");
                if (gps != null)
                {
                    cmnd.AppendLine("Group x.1-x.n;");
                }
                break;

            case ChartRepresent.A_FUNCTION_OF_A_VARIABLE:
                cmnd.AppendFormat("Chart {0}(y.1-y.n) &\r\n",
                                  FuncType.ToString());
                if (gps != null)
                {
                    cmnd.AppendLine("*x.1;");
                    if (gps.Length >= 2)
                    {
                        cmnd.AppendLine(" Group x.2-x.m;");
                    }
                }
                else
                {
                    cmnd.AppendLine(";");
                }

                break;

            case ChartRepresent.ONE_WAY_TABLE:
            case ChartRepresent.TWO_WAY_TABLE:
                cmnd.AppendLine("Chart (y.1-y.n)*x.1;");
                cmnd.AppendLine("Summarized;");
                if (BarsRepresent == ChartRepresent.TWO_WAY_TABLE)
                {
                    cmnd.AppendLine("Overlay;");
                    if (TableArrangement == ChartTableArrangementType.RowsOuterMost)
                    {
                        cmnd.AppendLine(" VLast;");
                    }
                    else
                    {
                        cmnd.AppendLine(" VFirst;");
                    }
                }
                if (gps.Length >= 2)
                {
                    cmnd.AppendLine(" Group x.2-x.m;");
                }
                break;
            }
            if (Transponse)
            {
                cmnd.AppendLine("trans;");
            }
            if (StackType == ChartStackType.Stack)
            {
                cmnd.AppendLine("stack;");
            }
            cmnd.Append(GetOptionCommand());
            cmnd.Append(YScale.GetCommand());
            cmnd.Append(XScale.GetCommand());
            cmnd.Append(tmpDatlab.GetCommand());

            /*
             * 對每一個 DataView 建立 Command
             * 這些處理是為了將 GroupingBy 屬性由原欄位換成 macro coded name
             */
            Component.DataView.DataView tmpDataview;
            string[] xStr = gps.Select((x, i) => "x." + (i + 1)).ToArray();

            foreach (Component.DataView.DataView dview in
                     new Component.DataView.DataView[] { Bar, Symbol, Connectline })
            {
                tmpDataview = (Component.DataView.DataView)dview.Clone();
                if (dview.GroupingBy != null)
                {
                    string[] g = MtbTools.ConvertToMacroCodedName(
                        (string[])tmpDataview.GroupingBy, gps, xStr, _ws);
                }
                //if (dview is Component.DataView.Bar)
                //{
                //    if(Bar.AssignAttributeByVariables)
                //}
                cmnd.Append(tmpDataview.GetCommand());
            }

            Component.MultiGraph.MPanel tmpPane = (Component.MultiGraph.MPanel)Panel.Clone();
            if (Panel.PaneledBy != null)
            {
                tmpPane.PaneledBy = "p.1-p.k";
            }
            cmnd.Append(tmpPane.GetCommand());
            cmnd.Append(Legend.GetCommand());
            if (NoMissing)
            {
                cmnd.AppendLine("nomiss;");
            }
            if (NoEmpty)
            {
                cmnd.AppendLine("noem;");
            }
            cmnd.Append(GetAnnotationCommand());
            cmnd.Append(GetRegionCommand());
            cmnd.AppendLine(".");
            cmnd.AppendLine("endmacro");
            return(cmnd.ToString());
        }
        /// <summary>
        /// 執行分析項目
        /// </summary>
        /// <param name="proj"></param>
        public override void Execute(Mtb.Project proj)
        {
            if (_rawdata == null || _rawdata.Rows.Count == 0)
            {
                return;
            }
            _rptLst = new List <IRptOutput>();                                             //重新建立一個分析結果列舉
            Mtb.Worksheet ws         = proj.Worksheets.Add(1);                             //新增工作表
            string        varName    = _rawdata.Rows[0].Field <string>("ITEM_NAME");       //Get item name
            string        unit       = _rawdata.Rows[0].Field <string>("UNIT");            //Get item unit
            string        item_index = _rawdata.Rows[0].Field <string>("FURN_ITEM_INDEX"); //Get item_index


            string[] colids;
            colids = Mtblib.Tools.MtbTools.CreateVariableStrArray(ws, _rawdata.Columns.Count, Mtblib.Tools.MtbVarType.Column);

            // Copy data to Minitab
            #region 複製資料到 Minitab Worksheet
            Mtblib.Tools.MtbTools.InsertDataTableToMtbWs(_rawdata, ws);

            //因為匯入的資料的 raw data, 趨勢圖要用小時資料繪製,需要另外計算
            var summ = from row in _rawdata.AsEnumerable()
                       group row by row["RPT_TIMEHOUR"] into g
                       select new
            {
                TIMESTAMP = g.Key,
                AVGVALUE  = g.Average(r => r["VALUE"] == DBNull.Value ? 1.23456E+30 : Convert.ToDouble(r["Value"].ToString())),
                _LCL      = g.Max(r => r["LCL"] == DBNull.Value ? 1.23456E+30 : Convert.ToDouble(r["LCL"].ToString())),
                _UCL      = g.Max(r => r["UCL"] == DBNull.Value ? 1.23456E+30 : Convert.ToDouble(r["UCL"].ToString())),
            };
            var icharData = summ.Select(x => new
            {
                x.TIMESTAMP,
                x.AVGVALUE,
                x._LCL,
                x._UCL,
                CL  = (x._LCL + x._UCL) / 2,
                OOC = (x._UCL <MISSINGVALUE && x.AVGVALUE> x._UCL) || (x._LCL < MISSINGVALUE && x.AVGVALUE < x._LCL) ? 1 : 0
            });
            colids = Mtblib.Tools.MtbTools.CreateVariableStrArray(ws, 6, Mtblib.Tools.MtbVarType.Column);
            ws.Columns.Item(colids[0]).SetData(icharData.Select(x => x.TIMESTAMP).ToArray());
            ws.Columns.Item(colids[1]).SetData(icharData.Select(x => x.AVGVALUE).ToArray());
            ws.Columns.Item(colids[2]).SetData(icharData.Select(x => x._LCL).ToArray());
            ws.Columns.Item(colids[3]).SetData(icharData.Select(x => x._UCL).ToArray());
            ws.Columns.Item(colids[4]).SetData(icharData.Select(x => x.CL).ToArray());
            ws.Columns.Item(colids[5]).SetData(icharData.Select(x => x.OOC).ToArray());
            ws.Columns.Item(colids[0]).Name = "TIMESTAMP";
            ws.Columns.Item(colids[1]).Name = "AVGVALUE";
            ws.Columns.Item(colids[2]).Name = "_LCL";
            ws.Columns.Item(colids[3]).Name = "_UCL";
            ws.Columns.Item(colids[4]).Name = "CL";
            ws.Columns.Item(colids[5]).Name = "OOC";

            #endregion



            Mtb.Column a = ws.Columns.Item(1);

            StringBuilder cmnd = new StringBuilder();

            string valueCol = ws.Columns.Item("AVGVALUE").SynthesizedName;
            string timeCol  = ws.Columns.Item("TIMESTAMP").SynthesizedName;
            string lclCol   = ws.Columns.Item("_LCL").SynthesizedName;
            string uclCol   = ws.Columns.Item("_UCL").SynthesizedName;
            string oocCol   = ws.Columns.Item("OOC").SynthesizedName;
            string clCol    = ws.Columns.Item("CL").SynthesizedName;


            double[] lclData = ws.Columns.Item(lclCol).GetData();
            double[] uclData = ws.Columns.Item(uclCol).GetData();
            string   gpath   = System.IO.Path.Combine(Environment.GetEnvironmentVariable("tmp"), "Minitab", string.Format("ichart_{0}.jpg", item_index));

            cmnd.AppendLine("notitle");
            cmnd.AppendLine("brief 0");
            cmnd.AppendFormat("date {0} {0};\r\n", timeCol);
            cmnd.AppendLine("format(dtyyyy-M-d H:mm).");

            #region 建立管制圖語法
            if (!lclData.Any(x => x < MISSINGVALUE) && !uclData.Any(x => x < MISSINGVALUE))
            {
                cmnd.AppendFormat("ichart {0};\r\n", valueCol);
                cmnd.AppendFormat("gsave \"{0}\";\r\n", gpath);
                cmnd.AppendLine("repl;");
                cmnd.AppendLine("jpeg;");
                cmnd.AppendLine("cline;");
                cmnd.AppendLine("lshow 0;");
                cmnd.AppendLine("climit;");
                cmnd.AppendLine("lshow 0;");
                cmnd.AppendLine("datlab;");
                cmnd.AppendLine("tcolor 0;");
                cmnd.AppendFormat("cenlen {0};\r\n", clCol);
                cmnd.AppendFormat("conlim {0}-{1};\r\n", lclCol, uclCol);
                cmnd.AppendFormat("trest {0};\r\n", oocCol);
            }
            else
            {
                cmnd.AppendFormat("tsplot {0} {1} {2} {3};\r\n", lclCol, uclCol, clCol, valueCol);
                cmnd.AppendFormat("gsave \"{0}\";\r\n", gpath);
                cmnd.AppendLine("repl;");
                cmnd.AppendLine("jpeg;");
                cmnd.AppendLine("over;");
                cmnd.AppendFormat("symb {0};\r\n", oocCol);
                cmnd.AppendLine("type &");
                double[] oocData = ws.Columns.Item(oocCol).GetData();

                if (oocData.Any(x => x == 0) && oocData.Any(x => x == 1))
                {
                    cmnd.AppendLine("0 0 0 0 0 0 &");
                }
                else
                {
                    cmnd.AppendLine("0 0 0 &");
                }
                if (oocData.Any(x => x == 0))
                {
                    cmnd.AppendLine("6 &");
                }
                if (oocData.Any(x => x == 1))
                {
                    cmnd.AppendLine("12 &");
                }

                cmnd.AppendLine(";");
                cmnd.AppendLine("size 1;");
                cmnd.AppendLine("color &");
                if (oocData.Any(x => x == 0) && oocData.Any(x => x == 1))
                {
                    cmnd.AppendLine("0 0 0 0 0 0 &");
                }
                else
                {
                    cmnd.AppendLine("0 0 0 &");
                }
                if (oocData.Any(x => x == 0))
                {
                    cmnd.AppendLine("1 &");                           //r17 color 64
                }
                if (oocData.Any(x => x == 1))
                {
                    cmnd.AppendLine("2 &");
                }
                cmnd.AppendLine(";");
                cmnd.AppendLine("conn;");
                cmnd.AppendLine("type 1 1 1 1;");
                cmnd.AppendLine("color 2 2 120 1;"); //r17 conn:64 cl: 9, climit:8
                //cmnd.AppendLine("graph;");
                //cmnd.AppendLine("color 22;");
                cmnd.AppendLine("nole;");
            }
            cmnd.AppendFormat("stamp {0};\r\n", timeCol);
            cmnd.AppendLine("scale 1;");
            cmnd.AppendFormat("tick 1:{0}/{1};\r\n", icharData.Count(),
                              icharData.Count() > 35 ? Math.Ceiling((double)icharData.Count() / 35) : 1);
            cmnd.AppendLine("axla 1;");
            cmnd.AppendLine("adis 0;");
            cmnd.AppendLine("axla 2;");
            cmnd.AppendLine("adis 0;");
            cmnd.AppendLine("graph 8 4;");
            cmnd.AppendFormat("title \"個別值管制圖 {0}({1})\";\r\n", varName, unit);
            cmnd.AppendFormat("footn \"更新時間: {0}\";\r\n", DateTime.Now);
            cmnd.AppendFormat("ZTag \"{0}\";\r\n", "_ICHART");
            cmnd.AppendLine(".");
            //刪除所有圖形
            //cmnd.AppendLine("gmana;");
            //cmnd.AppendLine("all;");
            //cmnd.AppendLine("close;");
            //cmnd.AppendLine("nopr.");

            #endregion

            string filepath;
            try
            {
                filepath = Mtblib.Tools.MtbTools.BuildTemporaryMacro("mychart.mtb", cmnd.ToString());
                proj.ExecuteCommand(string.Format("exec \"{0}\" 1", filepath), ws);
                this.Contents.Add(new RptOutput()
                {
                    OType           = MtbOType.GRAPH,
                    OutputInByteArr = File.ReadAllBytes(gpath), //將檔案轉為二進位陣列
                });
            }
            catch
            {
            }



            //取得管制界限資訊
            double     clvalue  = ws.Columns.Item(clCol).GetData(1, 1);
            double     lclvalue = ws.Columns.Item(lclCol).GetData(1, 1);
            double     uclvalue = ws.Columns.Item(uclCol).GetData(1, 1);
            double[]   oocId    = ws.Columns.Item(oocCol).GetData();
            var        tmp      = oocId.Zip(((DateTime[])ws.Columns.Item(timeCol).GetData()), (x, y) => new { Date = y, OOC = x });
            DateTime[] oocDate  = oocId.Zip(((DateTime[])ws.Columns.Item(timeCol).GetData()), (x, y) => new { Date = y, OOC = x }).
                                  Where(x => x.OOC == 1).Select(x => x.Date).ToArray();

            // 計算製程能力指標 --> 另外開 Worksheet 處理
            // 將標準差 = 0 或 NULL 且沒有對應到規格資訊的資料的移除掉
            DataTable subRawData = new DataTable();
            try
            {
                subRawData = _rawdata.Select("STDDEV >0 AND STDDEV is not null AND (LSL is not null OR USL is not null) ").OrderBy(r => r["RPT_DATETIME"]).CopyToDataTable();
            }
            catch
            {
                subRawData = null; //沒有符合條件的時候設為 NULL
            }

            List <double> PpkList = new List <double>();
            List <double> USLInfo = new List <double>();
            List <double> LSLInfo = new List <double>();
            if (subRawData == null)
            {
                PpkList.Add(MISSINGVALUE);
            }
            else
            {
                cmnd.Clear();
                Mtb.Worksheet subWs = proj.Worksheets.Add(1);
                proj.SetComActiveWorksheet(subWs);
                Mtblib.Tools.MtbTools.InsertDataTableToMtbWs(subRawData, subWs);
                Mtb.Column subRawDataCol = subWs.Columns.Item("VALUE");
                Mtb.Column lslCol        = subWs.Columns.Item("LSL");
                Mtb.Column uslCol        = subWs.Columns.Item("USL");
                Mtb.Column byValCol      = subWs.Columns.Item("BYVAL");

                colids = Mtblib.Tools.MtbTools.CreateVariableStrArray(subWs, 1, Mtblib.Tools.MtbVarType.Column);
                string PpkCol = colids[0];
                if (byValCol.GetNumDistinctRows() == 1) //只有一組規格
                {
                    double usl = uslCol.GetData(1, 1);
                    double lsl = lslCol.GetData(1, 1);
                    cmnd.AppendFormat("capa {0} 1;\r\n", subRawDataCol.SynthesizedName);
                    if (usl < MISSINGVALUE)
                    {
                        cmnd.AppendFormat("uspec {0};\r\n", usl);
                    }
                    if (lsl < MISSINGVALUE)
                    {
                        cmnd.AppendFormat("lspec {0};\r\n", lsl);
                    }
                    cmnd.AppendLine("nochart;");
                    cmnd.AppendLine("ztag \"_Capa\";");
                    cmnd.AppendFormat("ppk {0}.", PpkCol);
                    USLInfo.Add(usl);
                    LSLInfo.Add(lsl);
                }
                else
                {
                    string[] tmpColId = Mtblib.Tools.MtbTools.CreateVariableStrArray(subWs, 2, Mtblib.Tools.MtbVarType.Column);
                    cmnd.AppendFormat("stat {0} {1};\r\n", lslCol.SynthesizedName, uslCol.SynthesizedName);
                    cmnd.AppendFormat("by {0};\r\n", byValCol.SynthesizedName);
                    cmnd.AppendFormat("maxi {0} {1}.\r\n", tmpColId[0], tmpColId[1]);

                    // 要留意某一組內資料完全相同的狀況
                    cmnd.AppendFormat("mcapa {0};\r\n", subRawDataCol.SynthesizedName);
                    cmnd.AppendFormat("by {0};\r\n", byValCol.SynthesizedName);
                    cmnd.AppendLine("size 1;");
                    cmnd.AppendLine("brief 0;");
                    cmnd.AppendLine("ztag \"_Capa\";");
                    cmnd.AppendFormat("lspec {0};\r\n", tmpColId[0]);
                    cmnd.AppendFormat("uspec {0};\r\n", tmpColId[1]);
                    cmnd.AppendFormat("ppk {0}.\r\n", PpkCol);

                    DataTable _dt = Mtblib.Tools.MtbTools.Apply("LSL", Mtblib.Tools.Arithmetic.Max, new string[] { "BYVAL" }, subRawData);
                    LSLInfo.AddRange(_dt.AsEnumerable().Select(r => r.Field <double>("VALUE")));
                    _dt = Mtblib.Tools.MtbTools.Apply("USL", Mtblib.Tools.Arithmetic.Max, new string[] { "BYVAL" }, subRawData);
                    USLInfo.AddRange(_dt.AsEnumerable().Select(r => r.Field <double>("VALUE")));
                }

                try
                {
                    filepath = Mtblib.Tools.MtbTools.BuildTemporaryMacro("mycapa.mtb", cmnd.ToString());
                    proj.ExecuteCommand(string.Format("exec \"{0}\" 1", filepath), subWs);
                    PpkList.AddRange(subWs.Columns.Item(PpkCol).GetData());
                }
                catch
                {
                    PpkList.Add(MISSINGVALUE);
                }
            }



            //計算基本統計量
            Mtb.Column rawDataCol = ws.Columns.Item("VALUE");
            double     mean       = MISSINGVALUE;
            double     stdev      = MISSINGVALUE;
            double     maximum    = MISSINGVALUE;
            double     minimum    = MISSINGVALUE;
            try
            {
                mean    = ((double[])rawDataCol.GetData()).Where(x => x < MISSINGVALUE).Average();
                stdev   = ((double[])rawDataCol.GetData()).Where(x => x < MISSINGVALUE).StdDev();
                maximum = ((double[])rawDataCol.GetData()).Where(x => x < MISSINGVALUE).Max();
                minimum = ((double[])rawDataCol.GetData()).Where(x => x < MISSINGVALUE).Min();
            }
            catch
            {
            }

            //組合報表物件
            // Mean, Max, Min, LCL, UCL, LSL, USL, Ppk, Level
            string summPath = System.IO.Path.Combine(Environment.GetEnvironmentVariable("tmp"), "Minitab", string.Format("summ_{0}.txt", item_index));
            using (StreamWriter sw = new StreamWriter(summPath, false))
            {
                StringBuilder sb = new StringBuilder();
                sb.AppendFormat("平均數\t{0}\r\n", mean < MISSINGVALUE ? mean.ToString("N") : "*");
                sb.AppendFormat("標準差\t{0}\r\n", stdev < MISSINGVALUE ? stdev.ToString("N") : "*");
                sb.AppendFormat("最大值\t{0}\r\n", maximum < MISSINGVALUE ? maximum.ToString("N") : "*");
                sb.AppendFormat("最小值\t{0}\r\n", minimum < MISSINGVALUE ? minimum.ToString("N") : "*");
                sb.AppendFormat("Cpk\t{0}\r\n", string.Join(";", PpkList.Select(x => x < MISSINGVALUE ? x.ToString("N") : "*")));
                sb.AppendFormat("Level\t{0}\r\n", string.Join(";",
                                                              PpkList.Select(x => x == MISSINGVALUE ? "*" :
                                                                             x < 0.67 ? "E" :
                                                                             x >= 0.67 && x < 1 ? "D" :
                                                                             x >= 1 && x < 1.33 ? "C" :
                                                                             x >= 1.33 && x < 1.67 ? "B" : "A"
                                                                             )));
                sw.WriteLine(sb.ToString());
            }
            this.Contents.Add(
                new RptOutput()
            {
                OType           = MtbOType.PARAGRAPH,
                OutputInByteArr = File.ReadAllBytes(summPath),
            }
                );

            //刪除工作表和指令
            proj.Worksheets.Delete();
            proj.Commands.Delete();
        }
        public String OnDispatchCommand(Int32 iMenu)
        {
            // This method is called whenever a user selects one of your menu items.
            // The iMenu variable should be equivalent to the menu item index set in “GetMenuItems.”
            String command = String.Empty;

            DialogResult dialogResult = new DialogResult();

            switch (iMenu)
            {
            case 0:
                // Describe column(s):
                FormDescribe formDescribe = new FormDescribe(ref AddIn.gMtbApp);
                // Fill up list box in dialog with numeric columns in worksheet:
                formDescribe.checkedListBoxOfColumns.ClearSelected();
                Int32 lColumnCount = AddIn.gMtbApp.ActiveProject.ActiveWorksheet.Columns.Count;
                for (Int32 i = 1; i <= lColumnCount; i += 1)
                {
                    // Select only the numeric columns:
                    if (AddIn.gMtbApp.ActiveProject.ActiveWorksheet.Columns.Item(i).DataType == MtbDataTypes.Numeric)
                    {
                        formDescribe.checkedListBoxOfColumns.Items.Add(gMtbApp.ActiveProject.ActiveWorksheet.Columns.Item(i).SynthesizedName);
                    }
                }
                // Show the dialog:
                dialogResult = formDescribe.ShowDialog();
                if (dialogResult == DialogResult.OK)
                {
                    StringBuilder cmnd = new StringBuilder("Describe ");

                    Boolean bPrev = false;
                    for (Int32 i = 0; i < formDescribe.checkedListBoxOfColumns.CheckedItems.Count; i += 1)
                    {
                        if (bPrev)
                        {
                            cmnd.Append(" ");
                        }
                        cmnd.Append(formDescribe.checkedListBoxOfColumns.CheckedItems[i].ToString());
                        bPrev = true;
                    }
                    if (formDescribe.chkMean.Checked)
                    {
                        cmnd.Append("; Mean");
                    }
                    if (formDescribe.chkVariance.Checked)
                    {
                        cmnd.Append("; Variance");
                    }
                    if (formDescribe.chkSum.Checked)
                    {
                        cmnd.Append("; Sums");
                    }
                    if (formDescribe.chkNnonmissing.Checked)
                    {
                        cmnd.Append("; N");
                    }
                    if (formDescribe.chkHistogram.Checked)
                    {
                        cmnd.Append("; GHist");
                    }
                    if (formDescribe.chkBoxplot.Checked)
                    {
                        cmnd.Append("; GBoxplot");
                    }
                    cmnd.Append(".");
                    command = cmnd.ToString();
                }
                formDescribe.Close();
                break;

            case 1:
                // Rename active worksheet:
                FormRename formRename = new FormRename(ref AddIn.gMtbApp);
                String     sCurrent   = AddIn.gMtbApp.ActiveProject.ActiveWorksheet.Name;
                formRename.textBoxCurrent.Enabled = true;
                formRename.textBoxCurrent.Text    = sCurrent;
                formRename.textBoxCurrent.Enabled = false;
                // Show the dialog:
                dialogResult = formRename.ShowDialog();
                if (dialogResult == DialogResult.OK)
                {
                    AddIn.gMtbApp.ActiveProject.ActiveWorksheet.Name = formRename.textBoxNew.Text;
                }
                formRename.Close();
                break;

            case 2:
                break;

            case 3:
                // Open a DOS Window:
                String[]         fileNamePossibilities = { "cmd.exe", "command.com" };
                Process          process;
                ProcessStartInfo processStartInfo;
                foreach (String fileNamePossibility in fileNamePossibilities)
                {
                    process          = new Process();
                    processStartInfo = new ProcessStartInfo();
                    processStartInfo.UseShellExecute = true;
                    processStartInfo.FileName        = fileNamePossibility;
                    process.StartInfo = processStartInfo;
                    try
                    {
                        process.Start();
                        break;
                    }
                    catch (Exception e)
                    {
                        MessageBox.Show(e.Message, "My Menu");
                        MessageBox.Show("Cannot locate DOS executable or otherwise start a command prompt…", "My Menu");
                        continue;
                    }
                }
                break;

            case 4:
                // “Geometric Mean” and “Mean Absolute Difference” (stored in the worksheet):
                FormGeoMean formGeoMean = new FormGeoMean(ref AddIn.gMtbApp);
                // Fill up list box in dialog with numeric columns in worksheet:
                lColumnCount = AddIn.gMtbApp.ActiveProject.ActiveWorksheet.Columns.Count;
                Hashtable hashtableOfNumericColumns = new Hashtable();
                for (Int32 i = 1; i <= lColumnCount; i += 1)
                {
                    if (AddIn.gMtbApp.ActiveProject.ActiveWorksheet.Columns.Item(i).DataType == MtbDataTypes.Numeric)
                    {
                        String sSynthesizedColumnName = AddIn.gMtbApp.ActiveProject.ActiveWorksheet.Columns.Item(i).SynthesizedName;
                        String sColumnName            = AddIn.gMtbApp.ActiveProject.ActiveWorksheet.Columns.Item(i).Name;
                        // Add column name (if it exists):
                        if (sColumnName != sSynthesizedColumnName)
                        {
                            sSynthesizedColumnName += String.Concat("  ", sColumnName);
                        }
                        formGeoMean.comboBox.Items.Add(sSynthesizedColumnName);
                        hashtableOfNumericColumns.Add(sSynthesizedColumnName, AddIn.gMtbApp.ActiveProject.ActiveWorksheet.Columns.Item(i));
                    }
                }
                // Show the dialog:
                dialogResult = formGeoMean.ShowDialog();
                if (dialogResult == DialogResult.OK)
                {
                    // Get data from the column and pass it to the function to do calculations:
                    Object     selectedItem  = formGeoMean.comboBox.SelectedItem;
                    Mtb.Column mtbDataColumn = (Mtb.Column)hashtableOfNumericColumns[selectedItem];
                    // “FindGeoMean” takes an array of doubles and returns the geometric mean.
                    // “bSuccess” indicates if the calculations were completed.
                    Array   daData = mtbDataColumn.GetData();
                    Boolean bSuccess;
                    Object  dGeoMean = FindGeoMean(ref daData, out bSuccess);
                    if (bSuccess)
                    {
                        // Find the “Mean Absolute Difference”:
                        Object dMAD = FindMAD(ref daData);
                        // Store both values in the first available column:
                        Mtb.Column mtbStorageColumn = AddIn.gMtbApp.ActiveProject.ActiveWorksheet.Columns.Add();
                        mtbStorageColumn.SetData(ref dGeoMean, 1, 1);
                        mtbStorageColumn.SetData(ref dMAD, 2, 1);
                        mtbStorageColumn.Name = "MyResults";
                    }
                    else
                    {
                        // An error occurred:
                        AddIn.gMtbApp.ActiveProject.ExecuteCommand("NOTE ** Error ** Cannot compute statistics…");
                    }
                    formGeoMean.Close();
                }
                break;

            case 5:
                try
                {
                    BAPlot baPlot = new BAPlot(ref AddIn.gMtbApp);
                    dialogResult = baPlot.ShowDialog();
                    if (dialogResult == DialogResult.OK)
                    {
                    }
                    baPlot.Close();
                }
                catch (Exception e) {
                    MessageBox.Show(e.Message, "Error");
                }
                break;

            default:
                break;
            }

            return(command);
        }