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

url特殊字元(#)的處理 -*.js encodeURIComponent , encodeURI的用法 -*.cs Uri.EscapeDataString Uri.UnescapeDataString 的用法

 目的:  encodeURIComponent , encodeURI的用法
實際範例: 參考 V60202 - get_SPPick(string SP = "", string WH="" ,)

 處理說明: 1>encodeURIComponent 

                        → 用於單一參數值,會編碼大部分特殊字元(包括 ?, &,#,=,庫房)

Ex: encodeURIComponent(17#) --> 17%23

2>encodeURL--> 用於整個 URL,只編碼不合法字元,但會保留 ?, &, #,=,字元

Ex: encodeURL(17#) --> 17# , 保留#
3> *.cs    Uri.UnescapeDataString  --> 它會把 %xx 格式的字元還原成原始文字
                           Ex: Uri.UnescapeDataString(17%23) -- 17#
                                  Uri.UnescapeDataString(%E5%BA%AB%E6%88%BF) -- 庫房
                  4> *.cs    Uri.escapeDataString  --> 它會把 原始文字 編碼成 %xx 格式
                           Ex: Uri.escapeDataString('17#') --  17%23
                                  Uri.escapeDataString('庫房') --  %E5%BA%AB%E6%88%BF

                  5>url參數傳至後端 [HttpPost]  --> 會自動解碼, %xx --> 字元(%23 --> #)
                        [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))
                       {
                           //WH: 17#      , Uri.UnescapeDataString(WH) --> 17#
                           //WH: 17%23, Uri.UnescapeDataString(WH)  --> 17#
                           WH = Uri.UnescapeDataString(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