2026年5月6日 星期三

JSON介紹 - 什麼是 JSON

 JSON(JavaScript Object Notation)是一種輕量級的資料交換格式,常用來在不同系統之間傳遞資料。它的設計理念是「簡單、易讀、易解析」,既能讓人類直觀理解,也能被電腦快速處理。

1>✨ JSON 的特點

  • 純文字格式:資料以文字形式儲存,通常是 .json 檔案。

  • 結構清晰:由「鍵值對」組成,類似字典或物件。

  • 跨平台通用:不依賴特定程式語言,幾乎所有語言都能解析。

  • 常用於網路傳輸:例如 API 回傳資料時,最常見的格式就是 JSON

2> JSON範例
{
  "name": "Alice",
  "age": 25,
  "isStudent": true,
  "skills": ["Python", "JavaScript", "SQL"]
}
  • 字串:用雙引號 " " 包起來

  • 數字:直接寫,不需要引號

  • 布林值truefalse

  • 陣列:用 [] 包起來

  • 物件:用 {} 包起來裡面是鍵值對

3> JSON 的用途
  • API 資料交換:伺服器和前端之間傳遞資料。

  • 設定檔:許多應用程式用 JSON 來儲存設定。

  • 資料儲存:簡單的資料庫或檔案系統也會用 JSON。

V80E01A - 以 Ext.Tree.Panel 的簡單應用 - 新增節點 - 新增子節點

 目的: V80E01A  - 以 Ext.Tree.Panel & Ext.data.TreeStore 的簡單應用

處理說明: 
     1> 透過 Ext.Tree.Panel 產生  Tree
           var cmp_sub_TreePanel1 = get_cmp_treepanel1("sub_TreePanel1","AIDC",10, myTreeStore);
     2> 直接建 TreeNode - 透過 root
function get_cmp_treepanel1(par_id,par_title, par_flex, par_store) {
    if (checkisnull(par_flex)) {
        par_flex = 10;
    }
    var rtn_cmp =
    {
        xtype: 'treepanel', border: 0,
        id: par_id,
        title: par_title,
        flex: par_flex,
        store: par_store,  //若par_store有值,則會以 par_store 為主,並覆蓋如下 root 的設定
        rootVisible: true,                   
        root: {
            text: par_title,
            expanded: true,
            children: [
                {
                    text: '子節點 1',
                    leaf: true
                },
                {
                    text: '子節點 2',
                    expanded: true,
                    children: [
                        { text: '子節點 2-1', leaf: true },
                        { text: '子節點 2-2', leaf: true }
                    ]
                }
            ]
        }, // end of s_AMM單號

    };
    return rtn_cmp;
};
     3> 透過  Ext.data.TreeStore 建 TreeNode   - 透過 .store
  var myTreeStore =
    {
        xtype: 'treeStore',
        root: {
            text: '根節點A',
            expanded: true,
            children: [
                { text: '節點 A1', leaf: true },
                {
                    text: '節點 A2', expanded: true, children: [
                        { text: '節點 A2-1', leaf: true }
                    ]
                }
            ]
        }
    };
    var cmp_sub_TreePanel1 = get_cmp_treepanel1("sub_TreePanel1","AIDC",10, myTreeStore);

     4> 新增同層節點 先取得父節點 , 再由父節點.新增子節
                     function V80E01A_Add() {
                         var sub_TreePanel1 = Ext.getCmp("sub_TreePanel1");
                         var selectedNode = sub_TreePanel1.getSelectionModel().getSelection()[0];
                         if (selectedNode) {
                            var parentNode = selectedNode.parentNode;
                                  parentNode.insertChild(parentNode.indexOf(selectedNode) + 1, {
                                         text: '新同層節點',
                                         leaf: true
                                 });
                           // 如果要立即展開顯示
                          parentNode.expand();
                      }
                     };
     5> 新增子層節點 :
function V80E01A_AddSub() {
var sub_TreePanel1 = Ext.getCmp("sub_TreePanel1");
var selectedNode = sub_TreePanel1.getSelectionModel().getSelection()[0];
if (selectedNode) {
//若目前selectedNode為leaf , 則需先設為 false , 否則 appendChild 會無效
if (selectedNode.get('leaf')) {
   selectedNode.set('leaf', false);
};
selectedNode.appendChild({
text: '新子節點',
leaf: true
});
    // 如果要立即展開顯示            
    selectedNode.expand();
   }
};




1>*.js
function CALL_V80E01A() {
    console.log(" 1  顯示 AIDC 組織圖 ");
    //panel11 - 拆檢案專案日期選項
    var myTreeStore =
    {
        xtype: 'treeStore',
        root: {
            text: '根節點A',
            expanded: true,
            children: [
                { text: '節點 A1', leaf: true },
                {
                    text: '節點 A2', expanded: true, children: [
                        { text: '節點 A2-1', leaf: true }
                    ]
                }
            ]
        }
    };
    

    var cmp_sub_TreePanel1 = get_cmp_treepanel1("sub_TreePanel1","AIDC",10, myTreeStore);
       
    var sub_V80E01A_Flds = [
        {
            type: 'panel', bodyStyle: "background-color:transparent;", border: 5, padding: "1",
            layout: 'border',
            items: [
                {
                    xtype: 'panel', id: 'sub_panelAA1', region: 'center', 
                    height: 100,
                    //layout: { type: 'vbox', align: 'stretch' },
                    layout: { type: 'fit',},
                    items: [
                        cmp_sub_TreePanel1
                    ],
                },               
            ]
        }
    ];

    //2>顯示子畫面 - [列印子畫面]
    var Btns_V80E01A = [
        {
            xtype: 'button', text: '新增同層節點', id: 'AddBtn_V80E01A',
            listeners: {
                click: function (me, e, eOpts) {                    
                    V80E01A_Add();                    
                }
            }
        },
        {
            xtype: 'button', text: '新增子層節點', id: 'AddSubBtn_V80E01A',
            listeners: {
                click: function (me, e, eOpts) {
                    V80E01A_AddSub();
                }
            }
        },
        {
            xtype: 'button', text: '顯示 TreePanel.Store', id: 'ShowStoreBtn_V80E01A',
            listeners: {
                click: function (me, e, eOpts) {
                    V80E01A_ShowStore();
                }
            }
        },
        {
            xtype: 'button', text: '取消', id: 'CancelBtn_V80E01A',
            listeners: {
                click: function () {                    
                    //3>取消時,不重新顯示資料                    
                    this.up("window").close();
                    this.up("window").destroy();
                }
            }
        },
    ];

    //子畫面: mySubFormA
    //var win = getMyWindow("撿料完成", J_formFields_V80E01A, Btns_V80E01A, "F");
    var winAA1 = getMyWindow("顯示 AIDC 公司組織圖 ", sub_V80E01A_Flds, Btns_V80E01A, "AA");
    //win.onshow = Sub1_onShow(np1);
    winAA1.width = 500;
    winAA1.height =500;    
    winAA1.show();

    //將目前所選節點加入子節點
    function V80E01A_AddSub() {
        var sub_TreePanel1 = Ext.getCmp("sub_TreePanel1");
        var selectedNode = sub_TreePanel1.getSelectionModel().getSelection()[0];        
        if (selectedNode) {
            if (selectedNode.get('leaf')) {
                selectedNode.set('leaf', false);
            };
            selectedNode.appendChild({
                text: '新子節點',
                leaf: true
            });

            // 如果要立即展開顯示            
            selectedNode.expand();
        }
    };
    //將目前所選節點加入同層節點
    function V80E01A_Add() {
        var sub_TreePanel1 = Ext.getCmp("sub_TreePanel1");
        var selectedNode = sub_TreePanel1.getSelectionModel().getSelection()[0];

        if (selectedNode) {
            var parentNode = selectedNode.parentNode;
            parentNode.insertChild(parentNode.indexOf(selectedNode) + 1, {
                text: '新同層節點',
                leaf: true
            });
            // 如果要立即展開顯示
            parentNode.expand();
        }
    };

    function V80E01A_ShowStore() {
        var sub_TreePanel1 = Ext.getCmp("sub_TreePanel1");
        console.log("sub_TreePanel1.store", sub_TreePanel1.store);
    };

};  // end of  function CALL_V80E01A() {



2026年5月5日 星期二

V80E01A - 以 Ext.Tree.Panel 建立公司組織圖 - TreeView

 目的: V80E01A 以 Ext.Tree.Panel & Ext.data.TreeStore 建立公司組織圖

處理說明: 1>TreeView : 利用 [Ext.Tree.Panel] 元件
                  2>若 TreeView 要由後端資料庫取得節點資料,則透過 .store.proxy  取得後端資料
                       部門下層節點資料 SQL :  存取該部門下層 DEP 及該部門員工                  
                       (HR_DEPHIRCH/HR_DEP/HR_EMPLYM) , SQL如下
                  3> DoubleClick節點展開: 
                       Ext.Tree.Panel元件已設計好, DoubleClick 節點時,
                       會呼叫 proxy , 觸發 beforeload event 
                       只要重傳傳入參數(=部門ID) , 透過 proxy.url 重新取得下層節點SQL即可
                       該元件會依 proxy 傳回資料,自動建置該節點下層節點                        


2>SQL如下:

SQL:
SELECT  'DEP' as TYPE,B.DPRTID as P_DEPID,A.DEPID as ID,A.DEPNM as NM        
FROM    HR_DEP A, HR_DEPHIRCH B      
WHERE   A.DEPID = B.DEPID      
AND     B.DPRTID = '800'    
union       
SELECT  'EMP' as TYPE,C.DEPID as P_DEPID,C.EMPLYID as ID,C.EMPLYNM as NM
FROM    HR_EMPLYM C     
WHERE  C.DEPID = '800'  
ORDER BY TYPE DESC,ID; 


1>*.js
function CALL_V80E01A() {
    console.log(" 1  顯示 AIDC 組織圖 ");
    //panel11 - 拆檢案專案日期選項
    var myTreeStore =
    {
        xtype: 'treeStore',
        proxy: {
            type: 'ajax',
            url: '../api/V80E01AAPI/get_sub_TreeData1',
            actionMethods: { read: 'POST' },   // 改成 POST
            reader: { type: 'json' },
        },
        root: {
            id:'AIDC',
            text: 'AIDC',
            expanded: true,
            children: [
                { text: '節點 A1', leaf: true },
                {
                    text: '節點 A2', expanded: true, children: [
                        { text: '節點 A2-1', leaf: true }
                    ]
                }
            ]
        }
    };
    
     var cmp_sub_TreePanel1 = get_cmp_treepanel1("sub_TreePanel1","AIDC",10, myTreeStore);
 //透過連接資料庫,取得 TreeView 節點資訊

var sub_TreePanel1 = Ext.getCmp("sub_TreePanel1");
function V80E01A_StoreProxy() {
        var np = {};
        np["cur_DEPID"] = "AIDC";
        sub_TreePanel1.store.getProxy().url = '../api/V80E01AAPI/get_sub_TreeData1',
        sub_TreePanel1.store.getProxy().extraParams = np; //分頁OK,篩選條件OK
        sub_TreePanel1.store.load();
    };


    sub_TreePanel1.on('beforeload', function (store, operation) {
        
        // operation.node 是目前要展開的節點
        var np = {};
        np["cur_DEPID"] = operation.node.data.id;
        if (operation.node.hasChildNodes())
            return;
        sub_TreePanel1.store.getProxy().extraParams = np;  //設定 extraParams ,重新會呼叫 URL
    });

2026年3月25日 星期三

V20305J – 零件需求登錄 – 後端字串太長, 送至前端無法顯示 - 編碼,解碼 - Encode,decode

 目的: V20305J – 零件需求登錄 後端字串太長, 送至前端無法顯示




1>V20305J*.cs  -c#
 Tmp_RtnMsg = "匯入檔案欄位名稱必需如下:<br>第2欄欄位名稱:[交修單號];"
                                                + "第3欄欄位名稱:[維修交修單號];第4欄欄位名稱:[工單號碼];"
                                                + "第5欄欄位名稱:[序號];第6欄欄位名稱:[展BOM件號];第7欄欄位名稱:[展BOM件號名稱];"
                                                + "第8欄欄位名稱:[圖號];第9欄欄位名稱:[索引];第10欄欄位名稱:  [上層件號];"
      + "第11欄欄位名稱:[SBOM件號];第12欄欄位名稱:[SBOM件號中文名稱];第13欄欄位名稱:[規範件號];"
                                                + "第14欄欄位名稱:[提料件號];第15欄欄位名稱:[每具數量];第16欄欄位名稱:[需求數量];"
                                                + "第17欄欄位名稱:[需求單位];第18欄欄位名稱:[更換情形];第19欄欄位名稱:[故障現象說明];"
      + "第20欄欄位名稱:[可修件(Y/N)];第21欄欄位名稱:[可修件更換原因說明];第22欄欄位名稱:[超量原因];"
                                                + "第23欄欄位名稱:[子件工單號碼];第24欄欄位名稱:[子件序號];第25欄欄位名稱:[特製件說明];"
      + "第26欄欄位名稱:[經常更換];第27欄欄位名稱:[配換率];第28欄欄位名稱:[QPEI];第29欄欄位名稱:[拆挪LRU交修單號];"
      + "第30欄欄位名稱:[拆挪子件序號];第31欄欄位名稱:[LCN];第32欄欄位名稱:[ALC];第33欄欄位名稱:[NHA_LCN];"
      + "第34欄欄位名稱:[NHA_ALC];第35欄欄位名稱:[EIAC];第36欄欄位名稱:[EI_LCN];第37欄欄位名稱:[EI_ALC];第38欄欄位名稱:[SBOM廠碼];"
                                                + "第39欄欄位名稱:[規範廠碼];第40欄欄位名稱:[SBOM單位];"
                                                +"第41欄欄位名稱:[技令號碼];"
                                                //+"第42欄欄位名稱:[WP];"
                                                //+"第43欄欄位名稱:[SBOM件號英文名稱];第44欄欄位名稱:[撥發單位];"
                                    ;
                        MyCookie.Value = HttpUtility.UrlEncode(Tmp_RtnMsg);
                        //MyCookie.Value = Tmp_RtnMsg;                        
                        HttpContext.Current.Response.Cookies.Add(MyCookie);
                        HttpContext.Current.Response.End();
                        return;
                    };

2>V20305J*.js
Ext.util.Cookies.set("Rtn_Msg", "");
    var Tmp_url = '../../api/V20305JAPI/INS_AMM_UOC_UOCD';
    me.up("form").submit({
        method: "POST",
        url: Tmp_url,  //更新資料庫單況            
        params: np,
        //standardSubmit: true,        
        //async: false,
    });  //end of Ext.Ajax.Request               
    
    var mask = new Ext.LoadMask(Ext.getBody(), {
        msg: '資料處理中, 請稍待...'
    });
    mask.show();//使用 mask 需手動呼叫show() 方法下                
    var timer = setInterval(function () {
        //var cookie_token = Ext.util.Cookies.get("Rtn_Msg");
        //Ext.util.Cookies.set("Rtn_Msg", "測試訊息");
        //後端傳回的訊息 Rtn_Msg , 若太長,則解碼(decodeURIComponent)後會變空白
        var Tmp_Str = r_cookies('Rtn_Msg');
        //var Tmp_Str = Ext.util.Cookies.get("Rtn_Msg");
        //Tmp_Str = decodeURIComponent(Tmp_Str);
        console.log("Tmp_Str", Tmp_Str);
        if (!checkisnull(Tmp_Str)) {
            clearInterval(timer);
            mask.hide();
            timer = null;            
            //var rtn_msg = r_cookies("Rtn_Msg");
            //Tmp_Str = decodeURIComponent(Tmp_Str);
            mysuccessalert(Tmp_Str);
            me.up("window").close();
            me.up("window").destroy();
        }
    }, 1000);  //等待 2000ms =1sec    

F12 即時讀取後端函式(INS_AMM_UOC_UOCD)的傳回值 - Response.Cookie 的欄位值

 目的: F12 讀取後端函式(INS_AMM_UOC_UOCD)的傳回值

           讀取  Response.Cookie 的欄位值  & Request.Cookie的欄位值 - F12 讀取欄位值

           













2026年2月28日 星期六

Blogger 無法讀取照片

 1》無法存取您的Google帳號



2》設定--〉App --> Chrome  --> [V]允許跨網站追蹤


2026年2月12日 星期四

V20108 – [匯出(人力資源)]鈕 – 設定 CELL 欄位邊框 - 水平置中/靠右

 目的: V20108 – [匯出(人力資源)] 設定 CELL 欄位邊框 & 水平靠右

處理說明: 1>設定欄位邊框
                      //cell.邊框 = 細線 & 黑色
                         CellRange cell = ws.Range[myfunc.GetExcelPos(k, cur_row)];
                         cell.Borders.LineStyle = LineStyleType.Thin;
                         cell.Borders.Color = Color.Black;
                     //cell.斜線 不顯示
                          cell.Borders[BordersLineType.DiagonalDown].LineStyle = LineStyleType.None; 
                          cell.Borders[BordersLineType.DiagonalUp].LineStyle = LineStyleType.None;
                 2>設定欄位右靠
                    ws.Range[myfunc.GetExcelPos(0, cur_row)].Text = "□";  //EMPID
ws.Range[myfunc.GetExcelPos(0, cur_row)].Style.HorizontalAlignment = HorizontalAlignType.Right;    //水平靠右  
HorizontalAlignType.Center;  //水平置中



1>*.cs

         ws.Range[myfunc.GetExcelPos(0, cur_row)].Text = "□";  //EMPID
ws.Range[myfunc.GetExcelPos(0, cur_row)].Style.HorizontalAlignment = HorizontalAlignType.Right;


  for (var k=0;k<=23;k++)
                        {
                            CellRange cell = ws.Range[myfunc.GetExcelPos(k, cur_row)];
                            cell.Borders.LineStyle = LineStyleType.Thin;
                            cell.Borders.Color = Color.Black;
                            cell.Borders[BordersLineType.DiagonalDown].LineStyle = LineStyleType.None; 
                            cell.Borders[BordersLineType.DiagonalUp].LineStyle = LineStyleType.None;
                        }