2026年9月10日 星期四

V60202C- 匯入 – 多檔案選項

 目的:V60202C- 匯入 多檔案 - 選項

處理說明: 1>選項
    var cmp_rd_XLSIN = get_cmp_rdgrp1('匯入檔案 - 選項', 'sub_rd_XLSIN', 200);
    var cmp_rd_XLSIN1 = get_cmp_rd0('零件資料匯入', 'sub_rd_XLSIN', 250, '1',"0 5 0 5",250);
    var cmp_rd_XLSIN2 = get_cmp_rd0('存量警戒資料匯入', 'sub_rd_XLSIN', 250, '2', "0 5 0 5", 250);
    var cmp_rd_XLSIN3 = get_cmp_rd0('盤點資料匯入', 'sub_rd_XLSIN', 250, '3', "0 5 0 5", 250);
    var cmp_rd_XLSIN4 = get_cmp_rd0('批次快速進貨_匯入', 'sub_rd_XLSIN', 250, '4', "0 5 0 5", 250);
    cmp_rd_XLSIN.items.push(cmp_rd_XLSIN1, cmp_rd_XLSIN2, cmp_rd_XLSIN3, cmp_rd_XLSIN4);
    cmp_rd_XLSIN1.checked = true;

                  2> 選項.框線
                       var rtn_cmp =
    { //已完工, 未完工 --> 兩者不能同時勾選
        xtype: 'radiogroup', fieldLabel: par_caption,
        labelWidth: par_l_width, 
        layout: par_layout,        
        width: '100%',
        id: par_id,        
        items: [],
        style: {  //框線
            border: '1px solid gray',
            padding: '1px'
        },
    }



            3>依選項匯入檔案 //依照各自選項(par_TYPE) - 執行檔案匯入
                *.cs
                switch (Tmp_TYPE)
               {
                    case ("1"):
                   {
                      XLS2XLS_1(); ////TYPE1: 零件資料匯入
                      break;
                    }
                 case ("2"):
                    {
                        XLS2XLS_2();  //TYPE2: 存量警戒資料匯入
                            break;
                    }
                     :
              }

               void XLS2XLS_1()  {};
               void XLS2XLS_2()  {};


1>*.cs

[HttpPost]
        public void XLS2XLS()
        {
            HttpContext c = HttpContext.Current;
            NameValueCollection nvc = c.Request.Form;
            //匯入檔案名稱: par_FName
            string Tmp_TYPE = nvc["TYPE"]; //1/2/3/4: 零件資料匯入格式/存量警戒資料匯入格式/盤點資料匯入格式/批次快速進貨_匯入格式
            string Tmp_FName = nvc["FName"];
            string Tmp_SAPDB = nvc["SAPDB"];
            //string Tmp_SAPDB = "ERPI"; //預設值
            string Tmp_TYPENAME = "";
            string documentPath = HttpContext.Current.Server.MapPath("~") + "document\\";  // 取得實實的路徑            
            //匯出檔案名稱:  par_FName+"_匯入結案.xlsx"
            string Tmp_oFName = Path.GetFileNameWithoutExtension(Tmp_FName) + "_匯入結果.xlsx"; //"V1060301_匯入結果說明.xlsx";
            string Tmp_oFName1 = documentPath + Tmp_oFName;

            Workbook wk = null;
            MemoryStream mstream = new MemoryStream();

            HttpRequest Request = HttpContext.Current.Request;
            var response = this.Request.CreateResponse();
            string file_Name = Tmp_FName;
            string FILEDT = DateTime.Now.ToString("yyyy/MM/dd");
            string Tmp_RtnMsg = "";
            string Tmp_RtnMsg1 = "";
            string Tmp_Sql = "", Tmp_Str = "";
            bool Tmp_isOk=true;
            int Tmp_cnt = 0;
            int Tmp_curpos = 0;

            List<string> SQLStringList_A = new List<string>();
            HttpCookie MyCookie;  //將訊息傳至前端
            
            string fileType = Request.Files[0].ContentType;
            Stream file_Strm = Request.Files[0].InputStream;
            file_Name = Path.GetFileName(Request.Files[0].FileName);  //只取檔名
            int fileSize = Request.Files[0].ContentLength;
            byte[] fileRcrd = new byte[fileSize];

            try
            {
                //匯入
                wk = new Workbook();
                wk.LoadFromStream(file_Strm);
                Worksheet sheet1 = wk.Worksheets[0];//獲取第一個工作表


                //依照各自選項(par_TYPE)  - 執行檔案匯入
                switch (Tmp_TYPE)
            {
                case ("1"):
                    {
                        XLS2XLS_1();  ////TYPE1: 零件資料匯入
                            break;
                    }
                case ("2"):
                    {
                        XLS2XLS_2();  //TYPE2: 存量警戒資料匯入
                            break;
                    }
                case ("3"):
                    {
                        XLS2XLS_3();    //TYPE3: 盤點資料匯入
                            break;
                    }
                case ("4"):
                    {
                        XLS2XLS_4();  //TYPE4: 批次快速進貨_匯入
                            break;
                    }
            }
                if (Tmp_isOk == false)
                {
                    //匯入檔案失敗
                    Tmp_Str = "檔案(" + Tmp_FName + ")匯入失敗<br>"
                                    + Tmp_RtnMsg
                                    +"<br>";
                    MyCookie = new HttpCookie("Rtn_Msg", HttpUtility.UrlEncode(Tmp_Str));
                    HttpContext.Current.Response.Cookies.Add(MyCookie);
                    HttpContext.Current.Response.End();
                    return;
                }   
                    else
                    {
                    wk.SaveToStream(mstream, FileFormat.Version2007);
                    wk.SaveToFile(Tmp_oFName1, FileFormat.Version2007);
                    HttpContext.Current.Response.AddHeader("Content-Disposition", "attachment;filename=\"" + HttpUtility.UrlEncode((string)Tmp_oFName, System.Text.Encoding.UTF8) + "\"");
                    HttpContext.Current.Response.ContentEncoding = System.Text.Encoding.UTF8;
                    HttpContext.Current.Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
                    HttpContext.Current.Response.BinaryWrite(mstream.ToArray());
                    Tmp_RtnMsg = "檔案[" + Tmp_FName + "]匯入完成!!<br>"
                                                 + "匯入結果請參閱附檔<br>"
                                                 + "(" + Tmp_oFName + ")<br>"; ;                        
                        MyCookie = new HttpCookie("Rtn_Msg", HttpUtility.UrlEncode(Tmp_RtnMsg));
                        HttpContext.Current.Response.Cookies.Add(MyCookie);
                        //HttpContext.Current.ApplicationInstance.CompleteRequest();
                        HttpContext.Current.Response.End();
                        return;
                    }

                //TYPE2: 存量警戒資料匯入格式
                void XLS2XLS_2()
                {
                    //新增[匯入結果說明]欄位 - 於最後一欄位
                    int Tmp_Result_col = 5;
                    Tmp_TYPENAME = "存量警戒資料匯入";
                    sheet1.Range[myfunc.GetExcelPos(Tmp_Result_col, 0)].Value = "匯入結果說明";
                    int RowsCount = sheet1.LastRow;
                    //更新資料庫欄位值
                    /*共 28 欄
                    物料號碼,庫房,儲存位置,
                       類別,規格,存量等級,數量,單位,
                       供應商,WBS,批次,廠商批號,接收批號,
                       屆期日,代用料號,代用件號,容量,顏色,
                       色號,待溫,成化,AB二劑包裝,使用專案,
                        使用位置,領用日期,單套用量,起始機號,備註
                     */
                    string Tmp_MATNR, Tmp_WH;
                    string Tmp_QTY, Tmp_UNIT;
                    string Tmp_DEG,Tmp_ITM;
                    int Tmp_cnt;

                    //STEP1>  檢核  XLS 欄位名稱資料是否正確                                            
                    Tmp_MATNR = sheet1.Range[myfunc.GetExcelPos(0, 0)].Value;
                    Tmp_WH = sheet1.Range[myfunc.GetExcelPos(1, 0)].Value;                    
                    Tmp_QTY = sheet1.Range[myfunc.GetExcelPos(2, 0)].Value;
                    Tmp_UNIT = sheet1.Range[myfunc.GetExcelPos(3, 0)].Value;

                    //xls 欄位名稱有問題
                    /*
                    /*共 4 欄
                    物料號碼,庫房,安全存量,單位,                    
                    string Tmp_MATNR, Tmp_WH;
                    string Tmp_QTY, Tmp_UNIT;
                     */

                    //物料號碼,庫房,儲存位置,
                    //string Tmp_MATNR, Tmp_WH, Tmp_SP;                    
                    if (Tmp_MATNR != "物料號碼")
                        Tmp_RtnMsg = Tmp_RtnMsg + "第1欄欄位標題(" + Tmp_MATNR + "):應為[物料號碼];";
                    if (Tmp_WH != "庫房")
                        Tmp_RtnMsg = Tmp_RtnMsg + "第2欄欄位標題(" + Tmp_WH + "):應為[庫房];";
                    if (Tmp_QTY != "安全存量")
                        Tmp_RtnMsg = Tmp_RtnMsg + "第3欄欄位標題(" + Tmp_QTY + "):應為[安全存量];";
                    if (Tmp_UNIT != "單位")
                        Tmp_RtnMsg = Tmp_RtnMsg + "第4欄欄位標題(" + Tmp_UNIT + "):應為[單位];";                    

                    if (Tmp_RtnMsg.Length > 0)
                    {
                        Tmp_isOk = false;
                        Tmp_RtnMsg = "欄位名稱必需如下:<br>"
                                                 + Tmp_RtnMsg;
                        MyCookie = new HttpCookie("Rtn_Msg", HttpUtility.UrlEncode(Tmp_RtnMsg));
                        HttpContext.Current.Response.Cookies.Add(MyCookie);
                        //HttpContext.Current.Server.ClearError();                
                        HttpContext.Current.ApplicationInstance.CompleteRequest();
                        return;
                    };  // end of if (Tmp_RtnMsg.Length>0)


                    //STEP2 > 檢核 xls 欄位值                    
                    int Tmp_index;
                    Tmp_isOk = true;
                    for (int i = 0; i < RowsCount; i++)
                    {
                        Tmp_RtnMsg = "";
                        Tmp_curpos = i + 1;
                        //* string Tmp_MATNR, Tmp_WH, Tmp_QTY,Tmp_UNIT;
                        Tmp_MATNR = sheet1.Range[myfunc.GetExcelPos(0, i + 1)].Value;
                        Tmp_WH = sheet1.Range[myfunc.GetExcelPos(1, i + 1)].Value;
                        Tmp_QTY = sheet1.Range[myfunc.GetExcelPos(2, i + 1)].Value;
                        Tmp_UNIT = sheet1.Range[myfunc.GetExcelPos(3, i + 1)].Value;
                        //若件號空白,表示無資料了,
                        if (myfunc.checkisnull(Tmp_MATNR))
                        {
                            break;
                        }                       

                        //檢核必填欄位
                        //件號/庫房 / 數量
                        if (myfunc.checkisnull(Tmp_MATNR))
                            Tmp_RtnMsg = Tmp_RtnMsg + "[物料編號]不可空白;<br>";
                        if (myfunc.checkisnull(Tmp_WH))
                            Tmp_RtnMsg = Tmp_RtnMsg + "[庫房]不可空白;<br>";
                        if (myfunc.checkisnull(Tmp_QTY))
                            Tmp_RtnMsg = Tmp_RtnMsg + "[安全存量]不可空白;<br>";
                        if (myfunc.checkisnull(Tmp_UNIT))
                            Tmp_RtnMsg = Tmp_RtnMsg + "[單位]不可空白;<br>";
                        //件號必需存在  [零件檔(AMM_COMP)] 
                        Tmp_Sql = " SELECT   COUNT(*) "
                                       + "  FROM    AMM_COMP  "
                                       + "  WHERE   1=1 "
                                       + "  AND         MATNR=" + myfunc.AA(Tmp_MATNR);
                        Tmp_cnt = myfunc.str2int(myfunc.SqlValue(Tmp_Sql));
                        if (Tmp_cnt==0)
                            Tmp_RtnMsg = Tmp_RtnMsg + "物料編號("+Tmp_MATNR+")必需存在[零件存量檔(AMM_COMP)]<br>";
                        //件號+庫房在  [零件存量警戒值檔(AMM_WARM)] 不可重複
                        Tmp_Sql = " SELECT   COUNT(*) "
                                       + "  FROM    AMM_WARM  "
                                       + "  WHERE   1=1 "
                                       + "  AND         MATNR=" + myfunc.AA(Tmp_MATNR)
                                       + "  AND         WH=" + myfunc.AA(Tmp_WH);
                        Tmp_cnt = myfunc.str2int(myfunc.SqlValue(Tmp_Sql));
                        if (Tmp_cnt > 0)
                            Tmp_RtnMsg = Tmp_RtnMsg + "物料編號(" + Tmp_MATNR + ")+庫房("+Tmp_WH+")已存在[零件安全存量檔(AMM_WARM)]<br>"
                                                                                 +"不可重複!!<br>"
                                                                                 +"敬請檢核!!<br>";
                        //若沒問題,才寫入[零件安全存量檔(AMM_WARM)]
                        if (myfunc.checkisnull(Tmp_RtnMsg))
                        {   
                            /*
                             MATNR, WH, QTY,UNIT;                             
                             */                            
                            Tmp_DEG = "2";
                            Tmp_ITM = get_NEXT_ITM(Tmp_MATNR);
                            Tmp_Sql = " INSERT  INTO  AMM_WARM "
                                                       + "( MATNR, WH,ITM,  "
                                                       + "   QTY, UNIT, DEG "                                                       
                                                       + ")"
                                                       + " VALUES "
                                                       + "(" + myfunc.AA(Tmp_MATNR) + "," + myfunc.AA(Tmp_WH) + "," + myfunc.AA(Tmp_ITM) + ","
                                                                + myfunc.AA(Tmp_QTY) + "," + myfunc.AA(Tmp_UNIT) + "," + myfunc.AA(Tmp_DEG)                                                               
                                                              + ")";
                            myfunc.SqlExec(Tmp_Sql);
                            Tmp_RtnMsg = Tmp_RtnMsg
                                                     + "新增<br>"
                                                    + "物料編號(" + Tmp_MATNR + "),庫房(" + Tmp_WH + ")<br>"
                                                    +"安全存量("+Tmp_QTY+")";                                                     
                        } //end of if (myfunc.checkisnull(Tmp_RtnMsg))
                        Tmp_RtnMsg = Tmp_RtnMsg;
                        Tmp_RtnMsg = Tmp_RtnMsg.Replace("<br>", "\r\n");
                        sheet1.Range[myfunc.GetExcelPos(Tmp_Result_col, i + 1)].Value = Tmp_RtnMsg;
                    }  // end of for (int i = 0; i < RowsCount; i++)
                }  // end of public void XLS2XLS_2()


2026年9月8日 星期二

V60202I – 進貨記錄查詢 – [資料顯示] – 無資料, -後端有傳回資料,但前端沒顯示資料 - 子畫面

 目的: V60202I – 進貨記錄查詢 – [資料顯示] – 無資料, -後端有傳回資料,但前端沒顯示資料

處理說明:1>sub_Grid1.model 設定錯誤, 多一 [] , 以致傳回的資料,無法對應相關欄位


1>*.js  --> 如下 sub_Grid1.model 多一 []
var sub_model_V60202I = [
[
{ name: "CPNO" },
{ name: "MATNR" },
{ name: "WH" },
{ name: "SP" },
{
name: "QTY",
convert: function (value, record) { return Ext.util.Format.round(value, 2); }
},
{ name: "UNIT" },
{ name: "CHKER" },
{
name: "CHKDT",
convert: function (value, record) { if (!value) { return value; } return Ext.Date.format(new Date(value), 'Y/m/d'); }
},
{
name: "GNDT",
convert: function (value, record) { if (!value) { return value; } return Ext.Date.format(new Date(value), 'Y/m/d'); }
},
{ name: "CHARG" },
{ name: "PROJ" },
{ name: "RMK" },

// caluField
{ name: "CHKER_" },  //盤點人員姓名
{ name: "QTY_" },       //剩餘數量
]
];


2026年9月6日 星期日

V60202A – 快速進貨 – 儲存位置 – 挑選資料 – 依畫面欄位值(WH,MATNR)過濾 - encodeURIComponent - 依欄位值

 目的:V60202A – 快速進貨 儲存位置 挑選資料 依畫面欄位值(WH,MATNR)過濾

處理說明: 1>[儲存位置] - 先依一般挑選 , 設定 url (不含 ?WH= &MATNR= 過濾) ,
                       因為畫面顯示時, WH,MATNR 尚無欄位值
                  2>[儲存位置]挑選時,依 WH,MATNR 欄位值
                      --> Runtime 設定 url (?WH=xxxx&MATNR=xxxx)
                            Ext.getCmp('sub_btn_SP').handler = null ;
                            Ext.getCmp('sub_btn_SP').on("click", function () {
                                     var Tmp_WH = Ext.getCmp("sub_WH").getValue();
                                     var Tmp_MATNR = Ext.getCmp("sub_MATNR").getValue();
                                     var Tmp_url = "../api/V60202AAPI/get_sub_SPPick";
                                     Tmp_url = Tmp_url + "?WH=" + encodeURIComponent(Tmp_WH) 
                                                                  + "&MATNR=" + encodeURIComponent(Tmp_MATNR);                             var win = EditPickx('儲存位置', Tmp_url,
                                            ['SP'], ['sub_SP'], J_models_V60202A_SP, J_columns_V60202A_SP);
                          win.show();
                     });

                   3> url 的參數值,若有特殊符號(#,?,&,=,..) , 則必需用encodeURIComponent(Tmp_WH)
                        將特殊符號改成 %xx, 再送至後端 



1>*.js
   //儲存位置 - SP
    var cmp_sub_SP = get_cmp_txt1('SP', 'sub_SP', 100, 130);
    var cmp_sub_pick_SP = get_pick_btn0('挑選儲存位置', 'sub_btn_SP',
        "../../api/V60202AAPI/get_sub_SPPick",
        ['SP'], ['sub_SP'],
        J_models_V60202A_SP, J_columns_V60202A_SP);
    cmp_sub_SP.items.push(cmp_sub_pick_SP);

  var win = getMyWindow("快速進貨", sub_V60202A_Flds, Btns_V60202A, "A");
    //win.onshow = Sub1_onShow(np1);
    win.width = 400;
    win.height =250;    
    win.show();

//設定[儲存位置]畫面 - 欄位挑選設定  - Runtim 設定 挑選的url 
    Ext.getCmp('sub_btn_SP').handler = null ;
    Ext.getCmp('sub_btn_SP').on("click", function () {
        var Tmp_WH = Ext.getCmp("sub_WH").getValue();
        var Tmp_MATNR = Ext.getCmp("sub_MATNR").getValue();
        var Tmp_url = "../api/V60202AAPI/get_sub_SPPick";
        Tmp_url = Tmp_url + "?WH=" + encodeURIComponent(Tmp_WH) + "&MATNR=" + encodeURIComponent(Tmp_MATNR);        
        var win = EditPickx('儲存位置', Tmp_url,
            ['SP'], ['sub_SP'], J_models_V60202A_SP, J_columns_V60202A_SP);
        win.show();
    });

V60202- 工作台零件管制 – 刪除MD- 刪除Master --> Detail 的刪除依照 Erwin的設定 - Restrict -Cascade

 目的:  V60202- 工作台零件管制 刪除MD- 刪除Master à Detail 的刪除依照 Erwin的設定

處理說明:1 >[刪除]鈕 - 刪除 Master , Detail 的刪除依ErWin設定處理(透過 Trigger 處理)

                 2>Erwin的  Parent-Child Delete 設定






2>ErWin 的Parent-Child relation設定








2026年9月4日 星期五

V60202 [新增]鈕  [存檔]鈕,存檔後,自動再新增一筆資料

目的: V6020 - [新增] à [存檔],存檔後,自動再新增一筆資料料

處理說明:  1> btn_save.onclick event 
             Ext.getCmp('btn_save').on("click", function () {        
                  //setFormValue 執行時 , gridstore 尚未 commitchanges(); --> 所以修改欄位值 ,無法反應
                  Ext.getCmp('btn_Show').fireHandler();
                  //[新增][存檔]後,自動再新增一筆空白資料
                if (pub_isadd) {
                   pub_WH = Ext.getCmp("WH").getValue(); // [庫存]欄位值保留
                   Ext.getCmp("btn_add").fireEvent('click');
                 }        
                 return true;
               }    );
        
               2>自訂[新增] 模式:  pub_isadd
                  var pub_isadd=false; 
                  Ext.getCmp('btn_add').on("click", function () {
                         pub_isadd = true;
                   }
                  Ext.getCmp('btn_edid').on("click", function () {
                         pub_isadd = false;
                   }
    




目的: [新增]鈕 --> [存檔]鈕,存檔後,顯示後端的訊息 - Cookie - modeltype

 目的: [新增] à [存檔],存檔後,顯示後端的訊息

處理說明: 1>因為要顯示後端的訊息, 所以必需使用 Cookie
                       HttpCookie MyCookie;
                       Tmp_Str = "本次進貨件號.[需管制曝露時數]='Y'<br>"
                                      + "會自動新增(" + Tmp_QTY.ToString() + ")筆曝露時數基本資料!!<br>";                             MyCookie = new HttpCookie("Rtn_Msg", HttpUtility.UrlEncode(Tmp_Str));
                       HttpContext.Current.Response.Cookies.Add(MyCookie);
                  2>前端在存檔時,必需有一timer ,偵測 Cookie 是否有值 
                       --> 必需設在 btn_save.beforeInsert  ,modelType 才會=1  
Ext.getCmp('btn_save').beforeInsert = function () {
        //先清除 Cookie
        Ext.util.Cookies.set("Rtn_Msg", "");
        var modelType = buttonModel.getModelType();
        //若[新增]模式,則執行完成,則顯示訊息
        if (modelType == 1) {
            var timer = setInterval(function () {
                //timer = null;     
                //若資料庫已更新完成, 則 Email 委約==6  &  Email 委約<>6
                var Tmp_Str = r_cookies('Rtn_Msg');
                console.log("cookies Rtn_Msg =", Tmp_Str);
                if (!checkisnull(Tmp_Str)) {
                    mysuccessalert(Tmp_Str);
                    clearInterval(timer);  //不再重覆執行                                     
                }
            }, 1000)  // end of timer
        }   // end of  if (modelType == 1) {
        var isCheck = MD_DB.doSave('Insert');
        return isCheck;
    };
--> 不可設在 btn_save.onclick , 因為 btn_save.click後, modelType 會被設為 0 , 非 1






2026年9月3日 星期四

V60202 – [儲存位置]- 依[庫房]欄位值,過濾[儲存位置] - url 特殊字元(#,?,&)處理 - encodeURIComponent - encode,decode - Uri.UnescapeDataString

目的:  V60202 – [儲存位置]- 依[庫房]欄位值,過濾[儲存位置]  - url 特殊字元(#,?,&)處理  -

處理說明: 1>url 若含有 # 送至後端會錯誤, 瀏覽器會把#當成url分隔符號,不會傳給伺服器
                       -->所以 '../get_SPPick?WH=17# , 送至後端,17# 變成 17 , #不會傳給後端
                       -->url(含中文字,Ex:庫房),瀏覽器會自動將中文字編成%xx,送至後端
                  2>*.js 參數編碼:  encodeURIComponent() 
                       --> 所有特殊字元(#,?,&,庫房),均會編碼(%xx)
                      var Tmp_url = "../api/V60202API/get_SPPick?WH=" 
                                           + encodeURIComponent(Tmp_WH);     
                  3>*.cs 後端[HttpPost]  
                      --> *.cs 參數會自動將 %xx 還原成原始字元(#,?,&,庫房)
                       [HttpPost]
                       //前端 WH: 17%23      --> 後端  WH: 17#
                        //前端 WH: 17%2523  --> 後端 WH: 17%23 
                                                              --> Uri.UnescapeDataString(17%23) -- 17#
                      public dynamic get_SPPick(string SP = "", string WH="" ,int isComplete = 0)
                     {                   


1>*.js
 Ext.getCmp('btn_SP').on("click", function () {
        var Tmp_WH = Ext.getCmp("WH").getValue();  //庫房可能含 17#
        //1>url='../get_SPPick?WH= 17#', 傳至後端,會 錯誤 ,   -->  url 需改成 17%23 傳至後端
        //17#  , encodeURIComponent(Tmp_WH)  --> 17%23
        var Tmp_url = "../api/V60202API/get_SPPick?WH=" + encodeURIComponent(Tmp_WH);                
        var win = EditPickx('儲存位置', Tmp_url, ['SP',], ['SP'], J_pickstore_SP, J_pickcolumns_SP);
        win.show();
    });

2>*.cs
[HttpPost]
        //前端 WH: 17%23      --> 後端  WH: 17#
        //前端 WH: 17%2523  --> 後端 WH: 17%23  ,前端以 %23編碼 --> 後端還原成 %23
        public dynamic get_SPPick(string SP = "", string WH="" ,int isComplete = 0)
        {
            
            string Tmp_Sql = " SELECT  DISTINCT SP , WH  "
                                       + "  FROM   AMM_COMP "
                                       + "  WHERE  1=1 "
                                       + "    AND      SP IS NOT NULL "
                                       + "    AND      STAT='A'   ";
            if (!myfunc.checkisnull(WH))
            {                
                Tmp_Sql = Tmp_Sql + " AND    WH=" + myfunc.AA(WH);
            }
                
            Tmp_Sql = Tmp_Sql + " ORDER  BY SP ";
            string n = funId + "s_SP";
            DataSet ds = setupPickDs(n, Tmp_Sql, new string[] { "AMM_COMP" });
            if (SP != null && !SP.Equals(""))
            {
                if (isComplete == 1)
                {
                    ds = getPickDsbyCondi(n, "SP='" + SP + "'");
                }
                else
                {
                    ds = getPickDsbyCondi(n, "SP  LIKE '%" + SP + "%'");
                }
            }
            return ds;
        }  // end of  get_SPPick