示例#1
0
        private DataTable getSessionInfo(DataParse _dp)
        {
            DataTable tblSession = new DataTable();

            //Initialize tblSession
            tblSession.Columns.Add("Name", typeof(string));
            tblSession.Columns.Add("Value", typeof(string));

            //int strNameLength = 20;
            bool isHeadNull = false;
            var type = typeof(DataHeader);
            var fields = type.GetFields();
            //Array.ForEach(fields, f =>
            foreach (_FieldInfo fi in fields)
            {
                string name = fi.Name;
                DataRow dr = tblSession.NewRow();
                dr["Name"] = fi.Name;
                //check if header null
                if (name == "Product")
                {
                    if (fi.GetValue(_dp.Header) == null)
                    {
                        isHeadNull = true;
                    }
                }
                //if header null, use Test quantity to caculate yield
                if (isHeadNull)
                {
                    if (name == "TestQuantity")
                    {
                        dr["Value"] = _dp.TestedDevice;
                    }
                    else if (name == "PassQuantity")
                    {
                        dr["Value"] = _dp.PassedDevice;
                    }
                    else if (name == "FailQuantity")
                    {
                        dr["Value"] = _dp.FailedDevice;
                    }
                    else if (name == "Yield")
                    {
                        double pass = Convert.ToDouble(_dp.PassedDevice);
                        double total = Convert.ToDouble(_dp.TestedDevice);
                        dr["Value"] = Math.Round(pass / total * 100, 3) + "%";
                    }
                }
                //if header not null, use header info
                else
                {
                    if (name == "Yield")
                    {
                        dr["Value"] = fi.GetValue(_dp.Header) + "%";
                    }
                    else
                    {
                        dr["Value"] = fi.GetValue(_dp.Header);
                    }
                }
                tblSession.Rows.Add(dr);
            }

            return tblSession;
        }
示例#2
0
        /// <summary>
        /// // Paring data based on different file extension 
        /// </summary>
        /// <param name="strFileName"></param>
        /// <returns>Datatable[0] --> Header, Datatable[1] --> Data</returns>
        private async Task<DataTable[]> FetchDataTask(string[] strFileName)
        {
            #region *** Parsing data ***
            DataParse _DP = new DataParse();
            DataTable[] tblResult = new DataTable[2];
            DataTable tblHeadResult = new DataTable();
            DataTable tblDataResult = new DataTable();
            string strExtension = Path.GetExtension(strFileName[0]);

            if (strExtension.ToLower() == ".txt")
            {
                if (strFileName.Length == 1)
                    tblDataResult = _DP.GetDataFromTxt(strFileName[0]);
                else if (strFileName.Length > 1)
                    tblDataResult = _DP.GetDataFromTxt(strFileName);
            }
            else if (strExtension.ToLower() == ".std" || strExtension.ToLower() == ".stdf")
            {
                if (strFileName.Length == 1)
                {
                    using (FileStream fs = new FileStream(strFileName[0], FileMode.Open))
                    {
                        tblDataResult = await Task.Run(() => _DP.GetDataFromStdfviewer(fs));
                    }
                }
                else if (strFileName.Length > 1)
                {
                    tblDataResult = await Task.Run(() => _DP.GetDataFromStdfviewerTask(strFileName));
                }
            }
            else if (strExtension.ToLower() == ".gz")
            {
                if (strFileName.Length == 1)
                {
                    using (FileStream fs = new FileStream(strFileName[0], FileMode.Open))
                    {
                        using (GZipStream gzs = new GZipStream(fs, CompressionMode.Decompress))
                        {
                            tblDataResult = await Task.Run(() => _DP.GetDataFromStdfviewer(gzs));
                        }
                    }
                }
                else
                {
                    tblDataResult = await Task.Run(() => _DP.GetDataFromStdfviewerTask(strFileName));
                }
            }

            #endregion *** Parsing data ***

            intFrozenColumn = _DP.FreezeColumn;
            _DataParse = _DP;

            #region *** Caculate Header ***

            //int strNameLength = 20;
            bool isHeadNull = false;
            var type = typeof(DataHeader);
            var fields = type.GetFields();

            tblHeadResult.Columns.Add("Name", typeof(string));
            tblHeadResult.Columns.Add("Value", typeof(string));

            //Array.ForEach(fields, f =>
            foreach (_FieldInfo fi in fields)
            {
                string name = fi.Name;
                DataRow dr = tblHeadResult.NewRow();
                dr["Name"] = fi.Name;
                //check if header null
                if (name == "Product")
                {
                    if (fi.GetValue(_DP.Header) == null)
                    {
                        isHeadNull = true;
                    }
                }
                //if header null, use Test quantity to caculate yield
                if (isHeadNull)
                {
                    if (name == "TestQuantity")
                    {
                        dr["Value"] = _DP.TestedDevice;
                    }
                    else if (name == "PassQuantity")
                    {
                        dr["Value"] = _DP.PassedDevice;
                    }
                    else if (name == "FailQuantity")
                    {
                        dr["Value"] = _DP.FailedDevice;
                    }
                    else if (name == "Yield")
                    {
                        double pass = Convert.ToDouble(_DP.PassedDevice);
                        double total = Convert.ToDouble(_DP.TestedDevice);
                        dr["Value"] = Math.Round(pass / total * 100, 3) + "%";
                    }
                }
                //if header not null, use header info
                else
                {
                    if (name == "Yield")
                    {
                        dr["Value"] = fi.GetValue(_DP.Header) + "%";
                    }
                    else
                    {
                        dr["Value"] = fi.GetValue(_DP.Header);
                    }
                }
                tblHeadResult.Rows.Add(dr);
            }
            #endregion *** Caculate Header ***

            tblResult[0] = tblHeadResult;
            tblResult[1] = tblDataResult;
            return tblResult;
        }
示例#3
0
        private void parsedataservice()
        {
            string strPathdata = Util.PathDataParsingService;
            strPathdata = @"c:\temp";

            string strPathdup = strPathdata + @"\duplicate";
            string strPatharchive = strPathdata + @"\archive";
            string strPathfailure = strPathdata + @"\failure";


            //FileInfo[] FI = _Util.GetFileInfoArray(stPathdata, "std");
            FileInfo[] FI = getFileInfo(strPathdata);

            //DataTable tblData = new DataTable();
            DataTable[] tblPasingService = new DataTable[6];
            DataTable tblPass = new DataTable();
            DataTable tblSession = new DataTable();
            DataTable tblCpk1 = new DataTable();

            DataParse _dp = new DataParse();

            try
            {

                if (!EventLog.SourceExists(sSource)) EventLog.CreateEventSource(sSource, sLog);

                foreach (FileInfo tmpFI in FI)
                {
                    sEvent = "Parsing start; " + DateTime.Now.Millisecond + "ms; " + tmpFI.Name;
                    EventLog.WriteEntry(sSource, sEvent, EventLogEntryType.Information);

                    File.SetAttributes(tmpFI.FullName, FileAttributes.Normal);

                    if (tmpFI.Extension == "std" || tmpFI.Extension == "stdf")
                    {
                        #region parsing std file
                        tblPasingService[0] = _dp.GetDataFromStdfviewer(tmpFI.FullName);
                        
                        tblPass = delFailureData(tblPasingService[0]);

                        if (tblPass.Rows.Count < 5)
                        {
                            if (!Directory.Exists(strPathfailure)) Directory.CreateDirectory(strPathfailure);
                            File.Move(tmpFI.FullName, strPathfailure + "\\" + tmpFI.Name);
                            sEvent = "No enough pass device data, skip parsing " + tmpFI.Name;
                            EventLog.WriteEntry(sSource, sEvent, EventLogEntryType.Warning);
                            continue;
                        }

                        tblSession = getSessionInfo(_dp);
                        tblCpk1 = _Analysis.CaculateCpk(tblPass, _dp.FreezeColumn);

                        sEvent = "Parsing finish; " + DateTime.Now.Millisecond + "ms; " + tmpFI.Name;
                        EventLog.WriteEntry(sSource, sEvent, EventLogEntryType.Information);

                        insert2database(tblSession, tblCpk1);

                        sEvent = "Data added to database; " + DateTime.Now.Millisecond + "ms; " + tmpFI.Name;
                        EventLog.WriteEntry(sSource, sEvent, EventLogEntryType.Information);
                        
                        #endregion parsing std file
                    }
                    else if (tmpFI.Extension == "csv")
                    {
                        #region parsing csv file
                        tblPasingService = _dp.GetDataFromAceTechCsv(tmpFI.FullName);

                        sEvent = "Parsing finish; " + DateTime.Now.Millisecond + "ms; " + tmpFI.Name;
                        EventLog.WriteEntry(sSource, sEvent, EventLogEntryType.Information);

                        for (int i = 0; i < 6; i++)
                        {
                            if (tblPasingService[i].Rows.Count < 5) continue;

                            tblPass = delFailureData(tblPasingService[i]);

                            tblSession = getSessionInfo(_dp);
                            tblCpk1 = _Analysis.CaculateCpk(tblPass, _dp.FreezeColumn);

                            insert2database(tblSession, tblCpk1);
                        }
                        sEvent = "Data added to database; " + DateTime.Now.Millisecond + "ms; " + tmpFI.Name;
                        EventLog.WriteEntry(sSource, sEvent, EventLogEntryType.Information);

                        #endregion parsing csv file
                    }


                    if (!File.Exists(strPatharchive + "\\" + tmpFI.Name))
                    {
                        if (!Directory.Exists(strPatharchive)) Directory.CreateDirectory(strPatharchive);
                        File.Move(tmpFI.FullName, strPatharchive + "\\" + tmpFI.Name);
                        //File.Delete(tmpFI.FullName);
                    }
                    else
                    {
                        if (!Directory.Exists(strPathdup)) Directory.CreateDirectory(strPathdup);
                        File.Move(tmpFI.FullName, strPathdup + "\\" + tmpFI.Name);


                        sEvent = "Duplicate file exist in archive folder, move to duplicate folder instead; " + DateTime.Now.Millisecond + "ms; " + tmpFI.Name;
                        EventLog.WriteEntry(sSource, sEvent, EventLogEntryType.Warning);
                    }
                
                }
            }
            catch (Exception ex)
            {
                sEvent = ex.Message + ";" + ex.HelpLink + ";" + ex.Source;
                EventLog.WriteEntry(sSource, sEvent, EventLogEntryType.Error);
                throw new Exception(ex.Message.ToString());
            }

        }
示例#4
0
        } //end of tvDataList_Click
        
        // *** Open and Cache Test Data from AceTech
        private DataTable[] FetchAceTechCsvData(string strFileName)
        {
            DataParse _DP = new DataParse();
            DataTable[] tblResult = new DataTable[2];

            DataHeader m_Header = new DataHeader();
            DataTable tblHeadResult = new DataTable();
            DataTable tblDataResult = new DataTable();
            DataTable[] tblTestData = new DataTable[6];
            string[] ArrayKGU = null;

            try
            {
                tblTestData = _DP.GetDataFromAceTechCsv(strFileName);

                intFrozenColumn = _DP.FreezeColumn;
                _DataParse = _DP;

                if (_DP.a_Header.KGU)
                    ArrayKGU = _DP.a_Header.KGU_Number.Split(',');

                #region --- Cache Data ---

                #region --- Common Header ---
                m_Header.Handler = _DP.a_Header.Handler;
                m_Header.LotFinishDateTime = _DP.a_Header.LotEndDateTime;
                m_Header.LotID = _DP.a_Header.LotNumber;
                m_Header.LotStartDateTime = _DP.a_Header.LotStartDateTime;
                m_Header.OperatorID = _DP.a_Header.OperatorID;
                m_Header.Product = _DP.a_Header.Product;
                m_Header.ProgramRev = _DP.a_Header.ProgramRev;
                m_Header.SubLotID = _DP.a_Header.SubLotNumber;
                m_Header.TestBoard = _DP.a_Header.TestBoard;
                m_Header.Tester = _DP.a_Header.Tester;
                m_Header.LotQuantity = _DP.a_Header.LotQty;

                m_Header.TestSession = _DP.a_Header.TestSession;
                m_Header.TestQuantity = _DP.TestedDevice = _DP.a_Header.TestedQty_FT;
                m_Header.PassQuantity = _DP.PassedDevice = _DP.a_Header.PassedQty_FT;
                m_Header.FailQuantity = _DP.FailedDevice = _DP.a_Header.TestedQty_FT - _DP.a_Header.PassedQty_FT;
                m_Header.Yield = _DP.a_Header.Yield_FT;

                _DP.Header = m_Header;

                #endregion --- Common Header ---

                #region --- KGU ---
                if (_DP.a_Header.KGU)
                {
                    m_Header.TestSession = "KGU";
                    m_Header.TestQuantity = _DP.TestedDevice = ArrayKGU.Length;
                    m_Header.PassQuantity = _DP.PassedDevice = ArrayKGU.Length;
                    m_Header.FailQuantity = _DP.FailedDevice = 0;
                    m_Header.Yield = 100;

                    _DP.Header = m_Header;

                    tblData = tblTestData[0];

                    // Cache Data, Save tbldata to  tablCacheDat
                    // wait cache data to be finished
                    this.CacheDataAsync(CacheDataTask("KGU"));
                }
                #endregion --- KGU ---

                #region --- FT ---
                if (_DP.a_Header.FT)
                {
                    m_Header.TestSession = "FT";
                    m_Header.TestQuantity = _DP.TestedDevice = _DP.a_Header.TestedQty_FT;
                    m_Header.PassQuantity = _DP.PassedDevice = _DP.a_Header.PassedQty_FT;
                    m_Header.FailQuantity = _DP.FailedDevice = _DP.a_Header.TestedQty_FT - _DP.a_Header.PassedQty_FT;
                    m_Header.Yield = _DP.a_Header.Yield_FT;

                    _DP.Header = m_Header;

                    tblData = tblTestData[1];


                    // Cache Data, Save tbldata to  tablCacheDat
                    // wait cache data to be finished
                    this.CacheDataAsync(CacheDataTask("FT"));
                }
                #endregion --- FT ---

                #region --- RT1 ---
                if (_DP.a_Header.RT1)
                {
                    m_Header.TestSession = "RT1";
                    m_Header.TestQuantity = _DP.TestedDevice = _DP.a_Header.TestedQty_RT1;
                    m_Header.PassQuantity = _DP.PassedDevice = _DP.a_Header.PassedQty_RT1;
                    m_Header.FailQuantity = _DP.FailedDevice = _DP.a_Header.TestedQty_RT1 - _DP.a_Header.PassedQty_RT1;
                    m_Header.Yield = _DP.a_Header.Yield_RT1;

                    _DP.Header = m_Header;

                    tblData = tblTestData[2];


                    // Cache Data, Save tbldata to  tablCacheDat
                    // wait cache data to be finished
                    this.CacheDataAsync(CacheDataTask("RT1"));
                }
                #endregion --- RT1 ---

                #region --- RT2 ---
                if (_DP.a_Header.RT2)
                {
                    m_Header.TestSession = "RT2";
                    m_Header.TestQuantity = _DP.TestedDevice = _DP.a_Header.TestedQty_RT2;
                    m_Header.PassQuantity = _DP.PassedDevice = _DP.a_Header.PassedQty_RT2;
                    m_Header.FailQuantity = _DP.FailedDevice = _DP.a_Header.TestedQty_RT2 - _DP.a_Header.PassedQty_RT2;
                    m_Header.Yield = _DP.a_Header.Yield_RT2;

                    _DP.Header = m_Header;

                    tblData = tblTestData[3];


                    // Cache Data, Save tbldata to  tablCacheDat
                    // wait cache data to be finished
                    this.CacheDataAsync(CacheDataTask("RT2"));
                }
                #endregion --- RT1 ---

                #region --- EQC ---
                if (_DP.a_Header.EQC)
                {
                    m_Header.TestSession = "EQC";
                    m_Header.TestQuantity = _DP.TestedDevice = _DP.a_Header.TestedQty_EQC;
                    m_Header.PassQuantity = _DP.PassedDevice = _DP.a_Header.PassedQty_EQC;
                    m_Header.FailQuantity = _DP.FailedDevice = _DP.a_Header.TestedQty_EQC - _DP.a_Header.PassedQty_EQC;
                    m_Header.Yield = _DP.a_Header.Yield_EQC;

                    _DP.Header = m_Header;

                    tblData = tblTestData[4];

                    // Cache Data, Save tbldata to  tablCacheDat
                    // wait cache data to be finished
                    this.CacheDataAsync(CacheDataTask("EQC"));
                }
                #endregion --- EQC ---

                #region --- EQCV ---
                if (_DP.a_Header.EQCV)
                {
                    m_Header.TestSession = "EQCV";
                    m_Header.TestQuantity = _DP.TestedDevice = _DP.a_Header.TestedQty_EQCV;
                    m_Header.PassQuantity = _DP.PassedDevice = _DP.a_Header.PassedQty_EQCV;
                    m_Header.FailQuantity = _DP.FailedDevice = _DP.a_Header.TestedQty_EQCV - _DP.a_Header.PassedQty_EQCV;
                    m_Header.Yield = _DP.a_Header.Yield_EQCV;

                    _DP.Header = m_Header;

                    tblData = tblTestData[5];

                    // Cache Data, Save tbldata to  tablCacheDat
                    // wait cache data to be finished
                    this.CacheDataAsync(CacheDataTask("EQCV"));
                }
                #endregion --- EQCV ---

                #endregion --- Cache Data ---

                #region --- Merge Data ---

                m_Header.TestSession = _DP.a_Header.TestSession;
                m_Header.TestQuantity = _DP.TestedDevice = _DP.a_Header.TestedQty_FT;
                m_Header.PassQuantity = _DP.PassedDevice = _DP.a_Header.PassedQty_FT + _DP.a_Header.PassedQty_RT1 + _DP.a_Header.PassedQty_RT2;
                m_Header.FailQuantity = _DP.FailedDevice = _DP.TestedDevice - _DP.PassedDevice;
                m_Header.Yield = Math.Round((Convert.ToDouble(_DP.PassedDevice) / Convert.ToDouble(_DP.TestedDevice)) * 100, 2);

                _DP.Header = m_Header;

                int RowIndex = 1;

                if (_DP.a_Header.FT && _DP.a_Header.RT1 && _DP.a_Header.RT2)
                {
                    #region --- Merge Data FT & RT1 & RT2 ---
                    tblDataResult = tblTestData[1].Clone();
                    // FT Data
                    tblTestData[1].PrimaryKey = null;
                    foreach (DataRow dr in tblTestData[1].Rows)
                    {
                        // Header Limit
                        if (tblTestData[1].Rows.IndexOf(dr) <= 3) tblDataResult.ImportRow(dr);

                        int intCount = tblTestData[1].Columns.Count;
                        if (dr[intCount - 1].ToString().ToLower() == "pass")
                        {
                            dr[0] = RowIndex;
                            tblDataResult.ImportRow(dr);
                            RowIndex++;
                        }
                    }

                    // RT1 Data
                    tblTestData[2].PrimaryKey = null;
                    foreach (DataRow dr in tblTestData[2].Rows)
                    {
                        int intCount = tblTestData[2].Columns.Count;
                        if (dr[intCount - 1].ToString().ToLower() == "pass")
                        {
                            dr[0] = RowIndex;
                            tblDataResult.ImportRow(dr);
                            RowIndex++;
                        }
                    }

                    // RT2 Data
                    tblTestData[3].PrimaryKey = null;
                    foreach (DataRow dr in tblTestData[3].Rows)
                    {
                        if (tblTestData[3].Rows.IndexOf(dr) > 3)
                        {
                            dr[0] = RowIndex;
                            tblDataResult.ImportRow(dr);
                            RowIndex++;
                        }
                    }
                    #endregion --- Merge Data FT & RT1 & RT2 ---
                }
                else if (_DP.a_Header.FT && _DP.a_Header.RT1)
                {
                    #region --- Merge Data FT & RT1 ---
                    // FT Data
                    tblDataResult = tblTestData[1].Clone();
                    tblTestData[1].PrimaryKey = null;
                    foreach (DataRow dr in tblTestData[1].Rows)
                    {
                        // Header Limit
                        if (tblTestData[1].Rows.IndexOf(dr) <= 3) tblDataResult.ImportRow(dr);

                        int intCount = tblTestData[1].Columns.Count;
                        if (dr[intCount - 1].ToString().ToLower() == "pass")
                        {
                            dr[0] = RowIndex;
                            tblDataResult.ImportRow(dr);
                            RowIndex++;
                        }
                    }

                    // RT1 Data
                    tblTestData[3].PrimaryKey = null;
                    foreach (DataRow dr in tblTestData[2].Rows)
                    {
                        if (tblTestData[2].Rows.IndexOf(dr) > 3)
                        {
                            dr[0] = RowIndex;
                            tblDataResult.ImportRow(dr);
                            RowIndex++;
                        }
                    }
                    #endregion --- Merge Data FT & RT1 ---
                }
                else
                {
                    #region --- No Merge ---
                    if (_DP.a_Header.FT)
                    {
                        m_Header.TestSession = "FT";
                        m_Header.TestQuantity = _DP.TestedDevice = _DP.a_Header.TestedQty_FT;
                        m_Header.PassQuantity = _DP.PassedDevice = _DP.a_Header.PassedQty_FT;
                        m_Header.FailQuantity = _DP.FailedDevice = _DP.a_Header.TestedQty_FT - _DP.a_Header.PassedQty_FT;
                        m_Header.Yield = _DP.a_Header.Yield_FT;

                        _DP.Header = m_Header;

                        tblDataResult = tblTestData[1];
                    }
                    else if (_DP.a_Header.RT1)
                    {
                        m_Header.TestSession = "RT1";
                        m_Header.TestQuantity = _DP.TestedDevice = _DP.a_Header.TestedQty_RT1;
                        m_Header.PassQuantity = _DP.PassedDevice = _DP.a_Header.PassedQty_RT1;
                        m_Header.FailQuantity = _DP.FailedDevice = _DP.a_Header.TestedQty_RT1 - _DP.a_Header.PassedQty_RT1;
                        m_Header.Yield = _DP.a_Header.Yield_RT1;

                        _DP.Header = m_Header;

                        tblDataResult = tblTestData[2];
                    }
                    else if (_DP.a_Header.RT2)
                    {
                        m_Header.TestSession = "RT2";
                        m_Header.TestQuantity = _DP.TestedDevice = _DP.a_Header.TestedQty_RT2;
                        m_Header.PassQuantity = _DP.PassedDevice = _DP.a_Header.PassedQty_RT2;
                        m_Header.FailQuantity = _DP.FailedDevice = _DP.a_Header.TestedQty_RT2 - _DP.a_Header.PassedQty_RT2;
                        m_Header.Yield = _DP.a_Header.Yield_RT2;

                        _DP.Header = m_Header;

                        tblDataResult = tblTestData[3];
                    }
                    else if (_DP.a_Header.EQC)
                    {
                        m_Header.TestSession = "EQC";
                        m_Header.TestQuantity = _DP.TestedDevice = _DP.a_Header.TestedQty_EQC;
                        m_Header.PassQuantity = _DP.PassedDevice = _DP.a_Header.PassedQty_EQC;
                        m_Header.FailQuantity = _DP.FailedDevice = _DP.a_Header.TestedQty_EQC - _DP.a_Header.PassedQty_EQC;
                        m_Header.Yield = _DP.a_Header.Yield_EQC;

                        _DP.Header = m_Header;

                        tblDataResult = tblTestData[4];
                    }
                    else if (_DP.a_Header.EQCV)
                    {
                        m_Header.TestSession = "EQCV";
                        m_Header.TestQuantity = _DP.TestedDevice = _DP.a_Header.TestedQty_EQCV;
                        m_Header.PassQuantity = _DP.PassedDevice = _DP.a_Header.PassedQty_EQCV;
                        m_Header.FailQuantity = _DP.FailedDevice = _DP.a_Header.TestedQty_EQCV - _DP.a_Header.PassedQty_EQCV;
                        m_Header.Yield = _DP.a_Header.Yield_EQCV;

                        _DP.Header = m_Header;

                        tblDataResult = tblTestData[5];
                    }
                    #endregion --- No Merge ---
                }

                #endregion --- Merge Data ---

                #region --- KGU Analysis ---
                if (_DP.a_Header.KGU)
                {
                    m_Header = _DP.Header;

                    AceTechKGUVerify(tblTestData[0], ArrayKGU);
                    _DP.Header = m_Header;
                }
                #endregion --- KGU Analysis ---

                #region *** Caculate Header ***

                //int strNameLength = 20;
                bool isHeadNull = false;
                var type = typeof(DataHeader);
                var fields = type.GetFields();

                tblHeadResult.Columns.Add("Name", typeof(string));
                tblHeadResult.Columns.Add("Value", typeof(string));

                //Array.ForEach(fields, f =>
                foreach (_FieldInfo fi in fields)
                {
                    string name = fi.Name;
                    DataRow dr = tblHeadResult.NewRow();
                    dr["Name"] = fi.Name;
                    //check if header null
                    if (name == "Product")
                    {
                        if (fi.GetValue(_DP.Header) == null)
                        {
                            isHeadNull = true;
                        }
                    }
                    //if header null, use Test quantity to caculate yield
                    if (isHeadNull)
                    {
                        if (name == "TestQuantity")
                        {
                            dr["Value"] = _DP.TestedDevice;
                        }
                        else if (name == "PassQuantity")
                        {
                            dr["Value"] = _DP.PassedDevice;
                        }
                        else if (name == "FailQuantity")
                        {
                            dr["Value"] = _DP.FailedDevice;
                        }
                        else if (name == "Yield")
                        {
                            double pass = Convert.ToDouble(_DP.PassedDevice);
                            double total = Convert.ToDouble(_DP.TestedDevice);
                            dr["Value"] = Math.Round(pass / total * 100, 3) + "%";
                        }
                    }
                    //if header not null, use header info
                    else
                    {
                        if (name == "Yield")
                        {
                            dr["Value"] = fi.GetValue(_DP.Header) + "%";
                        }
                        else
                        {
                            dr["Value"] = fi.GetValue(_DP.Header);
                        }
                    }
                    tblHeadResult.Rows.Add(dr);
                }
                #endregion *** Caculate Header ***

                //tblData.Clear();
                tblResult[0] = tblHeadResult;
                tblResult[1] = tblDataResult;

                return tblResult;
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }