private void BgWorkerExport_DoWork(object sender, DoWorkEventArgs e)
        {
            bgWorkerExport.ReportProgress(1);
            try
            {
                // 取得預設樣板
                Workbook  wb  = new Workbook(new MemoryStream(Properties.Resources.Template));
                Worksheet wst = wb.Worksheets[0];


                // 取得學生基本資料
                List <StudentInfo> StudentInfoList = QueryData.GetStudentInfoList3();

                List <string> StudentIDList = new List <string>();
                foreach (StudentInfo si in StudentInfoList)
                {
                    StudentIDList.Add(si.StudentID);
                }

                // 取得地址資訊
                Dictionary <string, JHAddressRecord> AddressDict = new Dictionary <string, JHAddressRecord>();
                List <JHAddressRecord> tmpAddress = JHAddress.SelectByStudentIDs(StudentIDList);
                foreach (JHAddressRecord rec in tmpAddress)
                {
                    if (!AddressDict.ContainsKey(rec.RefStudentID))
                    {
                        AddressDict.Add(rec.RefStudentID, rec);
                    }
                }

                // 取得電話資料
                Dictionary <string, JHPhoneRecord> PhoneDict = new Dictionary <string, JHPhoneRecord>();
                List <JHPhoneRecord> tmpPhone = JHPhone.SelectByStudentIDs(StudentIDList);
                foreach (JHPhoneRecord rec in tmpPhone)
                {
                    if (!PhoneDict.ContainsKey(rec.RefStudentID))
                    {
                        PhoneDict.Add(rec.RefStudentID, rec);
                    }
                }

                bgWorkerExport.ReportProgress(20);

                // 取得監護人父母資訊
                Dictionary <string, JHParentRecord> ParentDict = new Dictionary <string, JHParentRecord>();
                List <JHParentRecord> tmpParent = JHParent.SelectByStudentIDs(StudentIDList);
                foreach (JHParentRecord rec in tmpParent)
                {
                    if (!ParentDict.ContainsKey(rec.RefStudentID))
                    {
                        ParentDict.Add(rec.RefStudentID, rec);
                    }
                }

                // 轉換各項類別對照值
                Dictionary <string, string> MappingTag1 = new Dictionary <string, string>();
                Dictionary <string, string> MappingTag2 = new Dictionary <string, string>();
                Dictionary <string, string> MappingTag3 = new Dictionary <string, string>();
                Dictionary <string, string> MappingTag4 = new Dictionary <string, string>();

                // 取得學生類別
                Dictionary <string, List <string> > StudentTagDict = QueryData.GetStudentTagName(StudentIDList);

                // 解析對照設定
                XElement elmRoot = XElement.Parse(_Configure.MappingContent);
                if (elmRoot != null)
                {
                    foreach (XElement elm in elmRoot.Elements("Group"))
                    {
                        string gpName = elm.Attribute("Name").Value;
                        if (gpName == "學生身分")
                        {
                            foreach (XElement elm1 in elm.Elements("Item"))
                            {
                                string tagName = elm1.Attribute("TagName").Value;
                                if (!MappingTag1.ContainsKey(tagName) && tagName.Length > 0)
                                {
                                    MappingTag1.Add(tagName, elm1.Attribute("Code").Value);
                                }
                            }
                        }

                        if (gpName == "身心障礙")
                        {
                            foreach (XElement elm1 in elm.Elements("Item"))
                            {
                                string tagName = elm1.Attribute("TagName").Value;
                                if (!MappingTag2.ContainsKey(tagName) && tagName.Length > 0)
                                {
                                    MappingTag2.Add(tagName, elm1.Attribute("Code").Value);
                                }
                            }
                        }

                        if (gpName == "學生報名身分設定")
                        {
                            foreach (XElement elm1 in elm.Elements("Item"))
                            {
                                string tagName = elm1.Attribute("TagName").Value;
                                if (!MappingTag3.ContainsKey(tagName) && tagName.Length > 0)
                                {
                                    MappingTag3.Add(tagName, elm1.Attribute("Code").Value);
                                }
                            }
                        }

                        if (gpName == "失業勞工子女")
                        {
                            foreach (XElement elm1 in elm.Elements("Item"))
                            {
                                string tagName = elm1.Attribute("TagName").Value;
                                if (!MappingTag4.ContainsKey(tagName) && tagName.Length > 0)
                                {
                                    MappingTag4.Add(tagName, elm1.Attribute("Code").Value);
                                }
                            }
                        }
                    }
                }


                // 取得語言認證學生id
                List <string> hasLanguageCertificateIDList = QueryData.GetLanguageCertificate(StudentIDList);

                bgWorkerExport.ReportProgress(40);

                // 取得成績相關資料
                Dictionary <string, List <JHSemesterScoreRecord> > SemesterScoreRecordDict = new Dictionary <string, List <JHSemesterScoreRecord> >();
                List <JHSemesterScoreRecord> tmpSemsScore = JHSemesterScore.SelectByStudentIDs(StudentIDList);
                foreach (JHSemesterScoreRecord rec in tmpSemsScore)
                {
                    if (!SemesterScoreRecordDict.ContainsKey(rec.RefStudentID))
                    {
                        SemesterScoreRecordDict.Add(rec.RefStudentID, new List <JHSemesterScoreRecord>());
                    }

                    SemesterScoreRecordDict[rec.RefStudentID].Add(rec);
                }

                // 取得功過紀錄
                // 功過對照表
                JHMeritDemeritReduceRecord DemeritReduceRecord = JHMeritDemeritReduce.Select();
                // 懲
                Dictionary <string, List <JHDemeritRecord> > DemeritRecordDict = new Dictionary <string, List <JHDemeritRecord> >();
                List <JHDemeritRecord> tmpDemeritRecord = JHDemerit.SelectByStudentIDs(StudentIDList);
                foreach (JHDemeritRecord rec in tmpDemeritRecord)
                {
                    if (rec.Cleared == "是")
                    {
                        continue;
                    }

                    if (rec.OccurDate > _Configure.EndDate)
                    {
                        continue;
                    }
                    else
                    {
                        if (!DemeritRecordDict.ContainsKey(rec.RefStudentID))
                        {
                            DemeritRecordDict.Add(rec.RefStudentID, new List <JHDemeritRecord>());
                        }

                        DemeritRecordDict[rec.RefStudentID].Add(rec);
                    }
                }
                // 獎
                Dictionary <string, List <JHMeritRecord> > MeritRecordDict = new Dictionary <string, List <JHMeritRecord> >();
                List <JHMeritRecord> tmpMeritRecord = JHMerit.SelectByStudentIDs(StudentIDList);
                foreach (JHMeritRecord rec in tmpMeritRecord)
                {
                    if (rec.OccurDate > _Configure.EndDate)
                    {
                        continue;
                    }
                    else
                    {
                        if (!MeritRecordDict.ContainsKey(rec.RefStudentID))
                        {
                            MeritRecordDict.Add(rec.RefStudentID, new List <JHMeritRecord>());
                        }

                        MeritRecordDict[rec.RefStudentID].Add(rec);
                    }
                }

                // 填入幹部資料
                StudentInfoList = QueryData.FillCad(StudentIDList, StudentInfoList);

                // 填入中低收入戶
                StudentInfoList = QueryData.FillIncomeType(StudentIDList, StudentInfoList);

                // 填入競賽成績
                StudentInfoList = QueryData.FillStudentCompetitionScore(StudentIDList, StudentInfoList, _Configure.EndDate);

                // 取得學生體適能資料並填入
                StudentInfoList = QueryData.FillStudentFitness(StudentIDList, StudentInfoList, _Configure.EndDate);

                // 填入 Excel 資料
                int wstRIdx = 1;


                bgWorkerExport.ReportProgress(70);

                // 幹部限制
                List <string> CadreName1 = _Configure.LoadCareNames();

                foreach (StudentInfo si in StudentInfoList)
                {
                    // 考區代碼 0, 12/屏東考區
                    wst.Cells[wstRIdx, 0].PutValue(12);
                    // 集報單位代碼 1,學校代碼
                    wst.Cells[wstRIdx, 1].PutValue(K12.Data.School.Code);
                    // 序號 2
                    wst.Cells[wstRIdx, 2].PutValue(wstRIdx);
                    // 學號 3
                    wst.Cells[wstRIdx, 3].PutValue(si.StudentNumber);
                    // 班級 4
                    wst.Cells[wstRIdx, 4].PutValue(si.ClassName);
                    // 座號 5
                    wst.Cells[wstRIdx, 5].PutValue(si.SeatNo);
                    // 學生姓名 6
                    wst.Cells[wstRIdx, 6].PutValue(si.StudentName);
                    // 身分證統一編號 7
                    wst.Cells[wstRIdx, 7].PutValue(si.IDNumber);

                    // 性別 8
                    wst.Cells[wstRIdx, 8].PutValue(si.GenderCode);

                    // 出生年(民國年) 9
                    wst.Cells[wstRIdx, 9].PutValue(si.BirthYear);
                    // 出生月 10
                    wst.Cells[wstRIdx, 10].PutValue(si.BirthMonth);
                    // 出生日 11
                    wst.Cells[wstRIdx, 11].PutValue(si.BirthDay);
                    // 畢業學校代碼 12
                    wst.Cells[wstRIdx, 12].PutValue(K12.Data.School.Code);

                    // 畢業年(民國年) 13
                    int gyear;
                    if (int.TryParse(K12.Data.School.DefaultSchoolYear, out gyear))
                    {
                        wst.Cells[wstRIdx, 13].PutValue(gyear + 1);
                    }

                    // 畢肄業 14
                    wst.Cells[wstRIdx, 14].PutValue(1);


                    // 就學區 17

                    // 低收入戶 18
                    if (si.incomeType1)
                    {
                        wst.Cells[wstRIdx, 18].PutValue(1);
                    }
                    else
                    {
                        wst.Cells[wstRIdx, 18].PutValue(0);
                    }

                    // 中低收入戶 19
                    if (si.incomeType2)
                    {
                        wst.Cells[wstRIdx, 19].PutValue(1);
                    }
                    else
                    {
                        wst.Cells[wstRIdx, 19].PutValue(0);
                    }

                    wst.Cells[wstRIdx, 15].PutValue("0");
                    wst.Cells[wstRIdx, 16].PutValue("0");
                    wst.Cells[wstRIdx, 20].PutValue("0");
                    wst.Cells[wstRIdx, 28].PutValue("0");

                    if (StudentTagDict.ContainsKey(si.StudentID))
                    {
                        foreach (string tagName in StudentTagDict[si.StudentID])
                        {
                            if (MappingTag1.ContainsKey(tagName))
                            {
                                // 學生身分 15
                                wst.Cells[wstRIdx, 15].PutValue(MappingTag1[tagName]);
                            }

                            if (MappingTag2.ContainsKey(tagName))
                            {
                                si.isSpecial = true;
                                // 身心障礙 16
                                wst.Cells[wstRIdx, 16].PutValue(MappingTag2[tagName]);
                            }

                            if (MappingTag3.ContainsKey(tagName))
                            {
                                // 學生報名身分 28
                                wst.Cells[wstRIdx, 28].PutValue(MappingTag3[tagName]);
                            }
                            if (MappingTag4.ContainsKey(tagName))
                            {
                                // 失業勞工子女 20
                                wst.Cells[wstRIdx, 20].PutValue(MappingTag4[tagName]);
                            }
                        }
                    }



                    // 資料授權 21
                    wst.Cells[wstRIdx, 21].PutValue(0);

                    string parentName = "";


                    // 家長姓名 22
                    if (ParentDict.ContainsKey(si.StudentID))
                    {
                        if (!string.IsNullOrWhiteSpace(ParentDict[si.StudentID].CustodianName))
                        {
                            parentName = ParentDict[si.StudentID].CustodianName;
                        }
                        else if (!string.IsNullOrWhiteSpace(ParentDict[si.StudentID].FatherName))
                        {
                            parentName = ParentDict[si.StudentID].FatherName;
                        }
                        else if (!string.IsNullOrWhiteSpace(ParentDict[si.StudentID].MotherName))
                        {
                            parentName = ParentDict[si.StudentID].MotherName;
                        }
                        else
                        {
                        }
                        wst.Cells[wstRIdx, 22].PutValue(parentName);
                    }


                    // 市內電話 23
                    // 行動電話 24
                    if (PhoneDict.ContainsKey(si.StudentID))
                    {
                        wst.Cells[wstRIdx, 23].PutValue(PhoneDict[si.StudentID].Contact.Replace("-", "").Replace(")", "").Replace("(", ""));
                        wst.Cells[wstRIdx, 24].PutValue(PhoneDict[si.StudentID].Cell.Replace("-", "").Replace(")", "").Replace("(", ""));
                    }


                    // 郵遞區號 25
                    if (AddressDict.ContainsKey(si.StudentID))
                    {
                        string zipCode = "";

                        if (AddressDict[si.StudentID].MailingZipCode != null)
                        {
                            zipCode = AddressDict[si.StudentID].MailingZipCode;
                        }

                        if (zipCode.Length >= 3)
                        {
                            zipCode = zipCode.Substring(0, 3);
                        }

                        wst.Cells[wstRIdx, 25].PutValue(zipCode);

                        // 通訊地址 26
                        wst.Cells[wstRIdx, 26].PutValue(AddressDict[si.StudentID].MailingCounty + AddressDict[si.StudentID].MailingTown + AddressDict[si.StudentID].MailingDistrict + AddressDict[si.StudentID].MailingArea + AddressDict[si.StudentID].MailingDetail);
                    }
                    // 非中華民國身分證號 27
                    if (si.isTaiwanID)
                    {
                        wst.Cells[wstRIdx, 27].PutValue("");
                    }
                    else
                    {
                        wst.Cells[wstRIdx, 27].PutValue("V");
                    }


                    // 市內電話分機 29

                    // 均衡學習 30
                    // 計算分數
                    if (SemesterScoreRecordDict.ContainsKey(si.StudentID))
                    {
                        si.CalcSemsScore5(SemesterScoreRecordDict[si.StudentID]);
                        // 成績滿5學期才顯示
                        if (si.hasSemester5Score)
                        {
                            wst.Cells[wstRIdx, 30].PutValue(si.Semester5Score);
                        }
                    }

                    // 服務表現 31
                    si.CalcCadreScore(CadreName1);
                    wst.Cells[wstRIdx, 31].PutValue(si.ServiceScore);

                    // 品德表現 32
                    if (DemeritRecordDict.ContainsKey(si.StudentID))
                    {
                        if (MeritRecordDict.ContainsKey(si.StudentID))
                        {
                            si.CalcDemeritMemeritScore(DemeritRecordDict[si.StudentID], MeritRecordDict[si.StudentID], DemeritReduceRecord);
                        }
                        else
                        {
                            si.CalcDemeritMemeritScore(DemeritRecordDict[si.StudentID], new List <JHMeritRecord>(), DemeritReduceRecord);
                        }
                        wst.Cells[wstRIdx, 32].PutValue(si.MeritDemeritScore);
                    }
                    else
                    {
                        // 沒有懲戒
                        wst.Cells[wstRIdx, 32].PutValue(10);
                    }


                    // 競賽表現 33
                    si.CalcCompetitionScore();
                    wst.Cells[wstRIdx, 33].PutValue(si.CompetitionScore);

                    // 體適能 34
                    // 計算並填入
                    si.CalcFitnessScore();
                    wst.Cells[wstRIdx, 34].PutValue(si.FitnessScore);

                    // 本土語言認證 35
                    if (hasLanguageCertificateIDList.Contains(si.StudentID))
                    {
                        wst.Cells[wstRIdx, 35].PutValue(2);
                    }
                    else
                    {
                        wst.Cells[wstRIdx, 35].PutValue(0);
                    }



                    // 36~39 系統無法提供先空
                    // 適性發展_高中 36
                    // 適性發展_高職 37
                    // 適性發展_綜合高中 38
                    // 適性發展_五專 39

                    wstRIdx++;
                }

                bgWorkerExport.ReportProgress(100);

                e.Result = wb;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
Exemple #2
0
        private void BgWorkerExport_DoWork(object sender, DoWorkEventArgs e)
        {
            bgWorkerExport.ReportProgress(1);
            try
            {
                // 取得預設樣板
                Workbook  wb  = new Workbook(new MemoryStream(Properties.Resources.Template));
                Worksheet wst = wb.Worksheets[0];


                // 取得學生基本資料
                List <StudentInfo> StudentInfoList = QueryData.GetStudentInfoList3();

                List <string> StudentIDList = new List <string>();
                foreach (StudentInfo si in StudentInfoList)
                {
                    StudentIDList.Add(si.StudentID);
                }

                // 取得地址資訊
                Dictionary <string, JHAddressRecord> AddressDict = new Dictionary <string, JHAddressRecord>();
                List <JHAddressRecord> tmpAddress = JHAddress.SelectByStudentIDs(StudentIDList);
                foreach (JHAddressRecord rec in tmpAddress)
                {
                    if (!AddressDict.ContainsKey(rec.RefStudentID))
                    {
                        AddressDict.Add(rec.RefStudentID, rec);
                    }
                }

                // 取得電話資料
                Dictionary <string, JHPhoneRecord> PhoneDict = new Dictionary <string, JHPhoneRecord>();
                List <JHPhoneRecord> tmpPhone = JHPhone.SelectByStudentIDs(StudentIDList);
                foreach (JHPhoneRecord rec in tmpPhone)
                {
                    if (!PhoneDict.ContainsKey(rec.RefStudentID))
                    {
                        PhoneDict.Add(rec.RefStudentID, rec);
                    }
                }

                bgWorkerExport.ReportProgress(20);

                // 取得監護人父母資訊
                Dictionary <string, JHParentRecord> ParentDict = new Dictionary <string, JHParentRecord>();
                List <JHParentRecord> tmpParent = JHParent.SelectByStudentIDs(StudentIDList);
                foreach (JHParentRecord rec in tmpParent)
                {
                    if (!ParentDict.ContainsKey(rec.RefStudentID))
                    {
                        ParentDict.Add(rec.RefStudentID, rec);
                    }
                }

                // 轉換各項類別對照值
                Dictionary <string, string> MappingTag1 = new Dictionary <string, string>();
                Dictionary <string, string> MappingTag2 = new Dictionary <string, string>();
                Dictionary <string, string> MappingTag3 = new Dictionary <string, string>();
                Dictionary <string, string> MappingTag4 = new Dictionary <string, string>();

                // 取得學生類別
                Dictionary <string, List <string> > StudentTagDict = QueryData.GetStudentTagName(StudentIDList);

                // 解析對照設定
                XElement elmRoot = XElement.Parse(_Configure.MappingContent);
                if (elmRoot != null)
                {
                    foreach (XElement elm in elmRoot.Elements("Group"))
                    {
                        string gpName = elm.Attribute("Name").Value;
                        if (gpName == "學生身分")
                        {
                            foreach (XElement elm1 in elm.Elements("Item"))
                            {
                                string tagName = elm1.Attribute("TagName").Value;
                                if (!MappingTag1.ContainsKey(tagName) && tagName.Length > 0)
                                {
                                    MappingTag1.Add(tagName, elm1.Attribute("Code").Value);
                                }
                            }
                        }

                        if (gpName == "身心障礙")
                        {
                            foreach (XElement elm1 in elm.Elements("Item"))
                            {
                                string tagName = elm1.Attribute("TagName").Value;
                                if (!MappingTag2.ContainsKey(tagName) && tagName.Length > 0)
                                {
                                    MappingTag2.Add(tagName, elm1.Attribute("Code").Value);
                                }
                            }
                        }

                        if (gpName == "學生報名身分設定")
                        {
                            foreach (XElement elm1 in elm.Elements("Item"))
                            {
                                string tagName = elm1.Attribute("TagName").Value;
                                if (!MappingTag3.ContainsKey(tagName) && tagName.Length > 0)
                                {
                                    MappingTag3.Add(tagName, elm1.Attribute("Code").Value);
                                }
                            }
                        }

                        if (gpName == "失業勞工子女")
                        {
                            foreach (XElement elm1 in elm.Elements("Item"))
                            {
                                string tagName = elm1.Attribute("TagName").Value;
                                if (!MappingTag4.ContainsKey(tagName) && tagName.Length > 0)
                                {
                                    MappingTag4.Add(tagName, elm1.Attribute("Code").Value);
                                }
                            }
                        }
                    }
                }



                bgWorkerExport.ReportProgress(40);

                // 取得成績相關資料
                Dictionary <string, List <JHSemesterScoreRecord> > SemesterScoreRecordDict = new Dictionary <string, List <JHSemesterScoreRecord> >();
                List <JHSemesterScoreRecord> tmpSemsScore = JHSemesterScore.SelectByStudentIDs(StudentIDList);
                foreach (JHSemesterScoreRecord rec in tmpSemsScore)
                {
                    if (!SemesterScoreRecordDict.ContainsKey(rec.RefStudentID))
                    {
                        SemesterScoreRecordDict.Add(rec.RefStudentID, new List <JHSemesterScoreRecord>());
                    }

                    SemesterScoreRecordDict[rec.RefStudentID].Add(rec);
                }

                // 取得功過紀錄
                // 功過對照表
                JHMeritDemeritReduceRecord DemeritReduceRecord = JHMeritDemeritReduce.Select();
                // 懲
                Dictionary <string, List <JHDemeritRecord> > DemeritRecordDict = new Dictionary <string, List <JHDemeritRecord> >();
                List <JHDemeritRecord> tmpDemeritRecord = JHDemerit.SelectByStudentIDs(StudentIDList);
                foreach (JHDemeritRecord rec in tmpDemeritRecord)
                {
                    if (rec.Cleared == "是")
                    {
                        continue;
                    }

                    if (rec.OccurDate > _Configure.EndDate)
                    {
                        continue;
                    }
                    else
                    {
                        if (!DemeritRecordDict.ContainsKey(rec.RefStudentID))
                        {
                            DemeritRecordDict.Add(rec.RefStudentID, new List <JHDemeritRecord>());
                        }

                        DemeritRecordDict[rec.RefStudentID].Add(rec);
                    }
                }
                // 獎
                Dictionary <string, List <JHMeritRecord> > MeritRecordDict = new Dictionary <string, List <JHMeritRecord> >();
                List <JHMeritRecord> tmpMeritRecord = JHMerit.SelectByStudentIDs(StudentIDList);
                foreach (JHMeritRecord rec in tmpMeritRecord)
                {
                    if (rec.OccurDate > _Configure.EndDate)
                    {
                        continue;
                    }
                    else
                    {
                        if (!MeritRecordDict.ContainsKey(rec.RefStudentID))
                        {
                            MeritRecordDict.Add(rec.RefStudentID, new List <JHMeritRecord>());
                        }

                        MeritRecordDict[rec.RefStudentID].Add(rec);
                    }
                }

                // 取得服務學習時數
                StudentInfoList = QueryData.FillServiceLearn(StudentIDList, StudentInfoList, _Configure.EndDate);

                // 填入中低收入戶
                StudentInfoList = QueryData.FillIncomeType(StudentIDList, StudentInfoList);


                // 取得學生體適能資料並填入,嘉義版不卡日期,日期傳入不會限制
                StudentInfoList = QueryData.FillStudentFitness(StudentIDList, StudentInfoList, _Configure.EndDate);

                // 取得競賽總積分並填入學生資料
                StudentInfoList = QueryData.FillStudentCompetitionPerformanceSum(StudentIDList, StudentInfoList);

                // 填入 Excel 資料
                int wstRIdx = 1;
                bgWorkerExport.ReportProgress(70);

                foreach (StudentInfo si in StudentInfoList)
                {
                    // 考區代碼 0,嘉義區 10
                    wst.Cells[wstRIdx, 0].PutValue(10);

                    // 集報單位代碼 1
                    wst.Cells[wstRIdx, 1].PutValue(K12.Data.School.Code);

                    // 序號 2
                    wst.Cells[wstRIdx, 2].PutValue(wstRIdx);

                    // 學號 3
                    wst.Cells[wstRIdx, 3].PutValue(si.StudentNumber);

                    // 班級 4
                    wst.Cells[wstRIdx, 4].PutValue(si.ClassName);

                    // 座號 5
                    wst.Cells[wstRIdx, 5].PutValue(si.SeatNo);

                    // 學生姓名 6  // 2021-12-27 有些學校會為了整齊把學生的名字+空白,這裡濾掉
                    wst.Cells[wstRIdx, 6].PutValue(si.StudentName.Replace(" ", "").Replace(" ", ""));

                    // 身分證統一編號 7
                    wst.Cells[wstRIdx, 7].PutValue(si.IDNumber);

                    // 非中華民國身分證號 8
                    if (si.isTaiwanID)
                    {
                        wst.Cells[wstRIdx, 8].PutValue("");
                    }
                    else
                    {
                        wst.Cells[wstRIdx, 8].PutValue("V");
                    }

                    // 性別 9
                    wst.Cells[wstRIdx, 9].PutValue(si.GenderCode);

                    // 出生年(民國年) 10
                    wst.Cells[wstRIdx, 10].PutValue(si.BirthYear);

                    // 出生月 11
                    wst.Cells[wstRIdx, 11].PutValue(si.BirthMonth);

                    // 出生日 12
                    wst.Cells[wstRIdx, 12].PutValue(si.BirthDay);

                    // 畢業學校代碼 13
                    wst.Cells[wstRIdx, 13].PutValue(K12.Data.School.Code);

                    // 畢業年(民國年) 14
                    int gyear;
                    if (int.TryParse(K12.Data.School.DefaultSchoolYear, out gyear))
                    {
                        wst.Cells[wstRIdx, 14].PutValue(gyear + 1);
                    }

                    // 畢肄業 15
                    wst.Cells[wstRIdx, 15].PutValue(1);


                    wst.Cells[wstRIdx, 16].PutValue(0);
                    wst.Cells[wstRIdx, 17].PutValue(0);
                    wst.Cells[wstRIdx, 18].PutValue(0);
                    wst.Cells[wstRIdx, 22].PutValue(0);

                    if (StudentTagDict.ContainsKey(si.StudentID))
                    {
                        foreach (string tagName in StudentTagDict[si.StudentID])
                        {
                            if (MappingTag1.ContainsKey(tagName))
                            {
                                // 學生身分 16
                                wst.Cells[wstRIdx, 16].PutValue(MappingTag1[tagName]);
                            }

                            if (MappingTag2.ContainsKey(tagName))
                            {
                                si.isSpecial = true;
                                // 身心障礙 18
                                wst.Cells[wstRIdx, 18].PutValue(MappingTag2[tagName]);
                            }

                            if (MappingTag3.ContainsKey(tagName))
                            {
                                // 學生報名身分 17
                                wst.Cells[wstRIdx, 17].PutValue(MappingTag3[tagName]);
                            }
                            if (MappingTag4.ContainsKey(tagName))
                            {
                                // 失業勞工子女 22
                                wst.Cells[wstRIdx, 22].PutValue(MappingTag4[tagName]);
                            }
                        }
                    }


                    // 就學區 19,不處理

                    // 低收入戶 20
                    if (si.incomeType1)
                    {
                        wst.Cells[wstRIdx, 20].PutValue(1);
                    }
                    else
                    {
                        wst.Cells[wstRIdx, 20].PutValue(0);
                    }

                    // 中低收入戶 21
                    if (si.incomeType2)
                    {
                        wst.Cells[wstRIdx, 21].PutValue(1);
                    }
                    else
                    {
                        wst.Cells[wstRIdx, 21].PutValue(0);
                    }



                    // 資料授權 23
                    wst.Cells[wstRIdx, 23].PutValue(0);

                    string parentName = "";
                    // 家長姓名 24
                    if (ParentDict.ContainsKey(si.StudentID))
                    {
                        if (!string.IsNullOrWhiteSpace(ParentDict[si.StudentID].CustodianName))
                        {
                            parentName = ParentDict[si.StudentID].CustodianName;
                        }
                        else if (!string.IsNullOrWhiteSpace(ParentDict[si.StudentID].FatherName))
                        {
                            parentName = ParentDict[si.StudentID].FatherName;
                        }
                        else if (!string.IsNullOrWhiteSpace(ParentDict[si.StudentID].MotherName))
                        {
                            parentName = ParentDict[si.StudentID].MotherName;
                        }
                        else
                        {
                        }
                        wst.Cells[wstRIdx, 24].PutValue(parentName);
                    }


                    // 市內電話 25
                    // 市內電話分機 26
                    // 行動電話 27
                    if (PhoneDict.ContainsKey(si.StudentID))
                    {
                        wst.Cells[wstRIdx, 25].PutValue(PhoneDict[si.StudentID].Contact.Replace("-", "").Replace(")", "").Replace("(", ""));
                        wst.Cells[wstRIdx, 27].PutValue(PhoneDict[si.StudentID].Cell.Replace("-", "").Replace(")", "").Replace("(", ""));
                    }


                    // 郵遞區號 28
                    if (AddressDict.ContainsKey(si.StudentID))
                    {
                        if (AddressDict[si.StudentID].MailingZipCode != null)
                        {
                            string zipCode = AddressDict[si.StudentID].MailingZipCode;

                            if (zipCode.Length >= 3)
                            {
                                zipCode = zipCode.Substring(0, 3);
                            }

                            wst.Cells[wstRIdx, 28].PutValue(zipCode);
                        }

                        // 通訊地址 29
                        wst.Cells[wstRIdx, 29].PutValue(AddressDict[si.StudentID].MailingCounty + AddressDict[si.StudentID].MailingTown + AddressDict[si.StudentID].MailingDistrict + AddressDict[si.StudentID].MailingArea + AddressDict[si.StudentID].MailingDetail);
                    }

                    // 計算分數
                    if (SemesterScoreRecordDict.ContainsKey(si.StudentID))
                    {
                        si.CalcSemsScore5(SemesterScoreRecordDict[si.StudentID]);
                    }

                    // 健康與體育 30
                    if (si.isDomainHelPass)
                    {
                        wst.Cells[wstRIdx, 30].PutValue(1);
                    }
                    else
                    {
                        wst.Cells[wstRIdx, 30].PutValue(0);
                    }

                    // 藝術 31
                    if (si.isDoaminArtPass)
                    {
                        wst.Cells[wstRIdx, 31].PutValue(1);
                    }
                    else
                    {
                        wst.Cells[wstRIdx, 31].PutValue(0);
                    }

                    // 綜合活動 32
                    if (si.isDomainActPass)
                    {
                        wst.Cells[wstRIdx, 32].PutValue(1);
                    }
                    else
                    {
                        wst.Cells[wstRIdx, 32].PutValue(0);
                    }

                    // 品德表現 33
                    List <JHDemeritRecord> recD;
                    List <JHMeritRecord>   recM;

                    if (DemeritRecordDict.ContainsKey(si.StudentID))
                    {
                        recD = DemeritRecordDict[si.StudentID];
                    }
                    else
                    {
                        recD = new List <JHDemeritRecord>();
                    }

                    if (MeritRecordDict.ContainsKey(si.StudentID))
                    {
                        recM = MeritRecordDict[si.StudentID];
                    }
                    else
                    {
                        recM = new List <JHMeritRecord>();
                    }

                    si.CalcDemeritMemeritScore(recD, recM, DemeritReduceRecord);
                    wst.Cells[wstRIdx, 33].PutValue(si.MeritDemeritScore);

                    // 服務學習 34
                    wst.Cells[wstRIdx, 34].PutValue(si.ServiceLearnScore);

                    // 體適能 35
                    si.CalcFitnessScore();
                    wst.Cells[wstRIdx, 35].PutValue(si.FitnessScore);

                    // 競賽表現 36,使用者自行處理
                    if (si.CompPerfSum.HasValue)
                    {
                        wst.Cells[wstRIdx, 36].PutValue(si.CompPerfSum.Value);
                    }
                    else  // 2021-12-27 嘉義協同國中 見安老師要求預設值 0
                    {
                        wst.Cells[wstRIdx, 36].PutValue("0");
                    }

                    // 2021-12-27 嘉義協同國中 見安老師要求預設值全部填1
                    // https://3.basecamp.com/4399967/buckets/15765350/todos/4475736499#__recording_4477516175
                    // 家長意見_高中 37
                    wst.Cells[wstRIdx, 37].PutValue("1");
                    // 家長意見_高職 38
                    wst.Cells[wstRIdx, 38].PutValue("1");
                    // 導師意見_高中 39
                    wst.Cells[wstRIdx, 39].PutValue("1");
                    // 導師意見_高職 40
                    wst.Cells[wstRIdx, 40].PutValue("1");
                    // 輔導教師意見_高中 41
                    wst.Cells[wstRIdx, 41].PutValue("1");
                    // 輔導教師意見_高職 42
                    wst.Cells[wstRIdx, 42].PutValue("1");


                    wstRIdx++;
                }

                bgWorkerExport.ReportProgress(100);

                e.Result = wb;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        private void Worker_DoWork(object sender, DoWorkEventArgs e)
        {
            double total = _config.Students.Count;
            double count = 0;

            _worker.ReportProgress(0);

            List <string> student_ids = new List <string>();

            foreach (JHStudentRecord item in _config.Students)
            {
                student_ids.Add(item.ID);
            }

            #region 快取資料
            //獎勵
            Dictionary <string, List <JHMeritRecord> > meritCache = new Dictionary <string, List <JHMeritRecord> >();
            foreach (JHMeritRecord record in JHMerit.SelectByStudentIDs(student_ids))
            {
                if (record.OccurDate < _config.StartDate)
                {
                    continue;
                }
                if (record.OccurDate > _config.EndDate)
                {
                    continue;
                }

                if (!meritCache.ContainsKey(record.RefStudentID))
                {
                    meritCache.Add(record.RefStudentID, new List <JHMeritRecord>());
                }
                meritCache[record.RefStudentID].Add(record);
            }

            //懲戒
            Dictionary <string, List <JHDemeritRecord> > demeritCache = new Dictionary <string, List <JHDemeritRecord> >();
            foreach (JHDemeritRecord record in JHDemerit.SelectByStudentIDs(student_ids))
            {
                if (record.OccurDate < _config.StartDate)
                {
                    continue;
                }
                if (record.OccurDate > _config.EndDate)
                {
                    continue;
                }

                if (!demeritCache.ContainsKey(record.RefStudentID))
                {
                    demeritCache.Add(record.RefStudentID, new List <JHDemeritRecord>());
                }
                demeritCache[record.RefStudentID].Add(record);
            }

            //缺曠
            Dictionary <string, List <JHAttendanceRecord> > attendanceCache = new Dictionary <string, List <JHAttendanceRecord> >();
            foreach (JHAttendanceRecord record in JHAttendance.SelectByStudentIDs(student_ids))
            {
                if (record.OccurDate < _config.StartDate)
                {
                    continue;
                }
                if (record.OccurDate > _config.EndDate)
                {
                    continue;
                }

                if (!attendanceCache.ContainsKey(record.RefStudentID))
                {
                    attendanceCache.Add(record.RefStudentID, new List <JHAttendanceRecord>());
                }
                attendanceCache[record.RefStudentID].Add(record);
            }

            List <string> course_ids = new List <string>();
            foreach (JHSCAttendRecord record in JHSCAttend.SelectByStudentIDs(student_ids))
            {
                if (!course_ids.Contains(record.RefCourseID))
                {
                    course_ids.Add(record.RefCourseID);
                }
            }

            //課程
            JHCourse.RemoveAll();
            int schoolYear = _config.SchoolYear;
            int semester   = _config.Semester;
            Dictionary <string, JHCourseRecord> courseCache = new Dictionary <string, JHCourseRecord>();
            foreach (JHCourseRecord record in JHCourse.SelectByIDs(course_ids))
            {
                if ("" + record.SchoolYear != "" + schoolYear)
                {
                    continue;
                }
                if ("" + record.Semester != "" + semester)
                {
                    continue;
                }

                // 過濾使用者所選課程才放入
                if (Global._selectCourseIDList.Contains(record.ID))
                {
                    if (!courseCache.ContainsKey(record.ID))
                    {
                        courseCache.Add(record.ID, record);
                    }
                }
            }

            //修課記錄
            Dictionary <string, List <string> > scCache = new Dictionary <string, List <string> >();
            //foreach (JHSCAttendRecord sc in JHSCAttend.Select(student_ids, course_ids, new string[] { }, "" + _config.SchoolYear, "" + _config.Semester))
            foreach (JHSCAttendRecord sc in JHSCAttend.SelectByStudentIDAndCourseID(student_ids, course_ids))
            {
                if (!courseCache.ContainsKey(sc.RefCourseID))
                {
                    continue;
                }

                if (!scCache.ContainsKey(sc.RefStudentID))
                {
                    scCache.Add(sc.RefStudentID, new List <string>());
                }

                // 過濾使用者不選
                if (Global._selectCourseIDList.Contains(sc.RefCourseID))
                {
                    scCache[sc.RefStudentID].Add(sc.RefCourseID);
                }
            }

            //評量成績
            Dictionary <string, List <HC.JHSCETakeRecord> > sceScoreCache = new Dictionary <string, List <HC.JHSCETakeRecord> >();
            foreach (JHSCETakeRecord record in JHSCETake.SelectByStudentAndCourse(student_ids, course_ids))
            {
                if (record.RefExamID != _config.Exam.ID)
                {
                    continue;
                }

                if (!sceScoreCache.ContainsKey(record.RefStudentID))
                {
                    sceScoreCache.Add(record.RefStudentID, new List <HC.JHSCETakeRecord>());
                }
                sceScoreCache[record.RefStudentID].Add(new HC.JHSCETakeRecord(record));
            }

            //學期歷程
            Dictionary <string, K12.Data.SemesterHistoryItem> historyCache = new Dictionary <string, K12.Data.SemesterHistoryItem>();
            foreach (JHSemesterHistoryRecord record in JHSemesterHistory.SelectByStudentIDs(student_ids))
            {
                foreach (K12.Data.SemesterHistoryItem item in record.SemesterHistoryItems)
                {
                    if ("" + item.SchoolYear != K12.Data.School.DefaultSchoolYear)
                    {
                        continue;
                    }
                    if ("" + item.Semester != K12.Data.School.DefaultSemester)
                    {
                        continue;
                    }

                    if (!historyCache.ContainsKey(record.RefStudentID))
                    {
                        historyCache.Add(record.RefStudentID, item);
                    }
                }
            }

            //取得所有教師,為了Cache下來
            JHTeacher.SelectAll();
            #endregion

            #region 建立節次對照及假別列表
            Dictionary <string, string> periodMapping = new Dictionary <string, string>();
            foreach (JHPeriodMappingInfo info in JHPeriodMapping.SelectAll())
            {
                if (!periodMapping.ContainsKey(info.Name))
                {
                    periodMapping.Add(info.Name, info.Type);
                }
            }

            List <string> absenceList = new List <string>();
            foreach (JHAbsenceMappingInfo info in JHAbsenceMapping.SelectAll())
            {
                absenceList.Add(info.Name);
            }
            #endregion

            #region 判斷要列印的領域科目
            Dictionary <string, bool>           domains  = new Dictionary <string, bool>();
            Dictionary <string, List <string> > subjects = new Dictionary <string, List <string> >();

            List <JHCourseRecord> courseList = new List <JHCourseRecord>(courseCache.Values);
            courseList.Sort(delegate(JHCourseRecord x, JHCourseRecord y)
            {
                return(JHSchool.Evaluation.Subject.CompareSubjectOrdinal(x.Subject, y.Subject));
                //List<string> list = new List<string>(new string[] { "國語文", "國文", "英文", "英語", "數學", "歷史", "地理", "公民", "理化", "生物" });
                //int ix = list.IndexOf(x.Subject);
                //int iy = list.IndexOf(y.Subject);

                //if (ix >= 0 && iy >= 0)
                //    return ix.CompareTo(iy);
                //else if (ix >= 0)
                //    return -1;
                //else if (iy >= 0)
                //    return 1;
                //else
                //    return x.Subject.CompareTo(y.Subject);
            });

            string domainSubjectSetup = _rc.GetString("領域科目設定", "Domain");
            _config.DomainSubjectSetup = domainSubjectSetup;

            if (domainSubjectSetup == "Domain")
            {
                foreach (var domain in JHSchool.Evaluation.Subject.Domains)
                {
                    domains.Add(domain, true);
                }
                //domains.Add("彈性課程", false);

                if (domains.ContainsKey("語文"))
                {
                    domains["語文"] = false;
                }
                if (!domains.ContainsKey(""))
                {
                    domains.Add("", false);
                }
            }
            else if (domainSubjectSetup == "Subject")
            {
                foreach (var domain in JHSchool.Evaluation.Subject.Domains)
                {
                    domains.Add(domain, false);
                }
                //domains.Add("彈性課程", false);
                if (!domains.ContainsKey(""))
                {
                    domains.Add("", false);
                }
            }
            else
            {
                throw new Exception("請重新儲存一次列印設定");
            }

            foreach (var domain in JHSchool.Evaluation.Subject.Domains)
            {
                subjects.Add(domain, new List <string>());
            }
            //subjects.Add("彈性課程", new List<string>());
            subjects.Add("", new List <string>());

            //foreach (JHCourseRecord course in courseList)
            //{
            //    if (!domains.ContainsKey(course.Domain)) continue;

            //    if (!subjects.ContainsKey(course.Domain))
            //        subjects.Add(course.Domain, new List<string>());

            //    //很怪
            //    if (domains[course.Domain] == true) continue;

            //    if (!subjects[course.Domain].Contains(course.Subject))
            //        subjects[course.Domain].Add(course.Subject);
            //}

            _config.SetPrintDomains(domains);
            _config.SetPrintSubjects(subjects);
            #endregion

            DocumentBuilder templateBuilder = new DocumentBuilder(_template);

            #region 判斷是否列印文字評語

            templateBuilder.MoveToMergeField("文字評語");
            if (_rc.GetBoolean("列印文字評語", true))
            {
                templateBuilder.Write("文字評語");
            }
            else
            {
                Cell   first = templateBuilder.CurrentParagraph.ParentNode as Cell;
                double width = first.CellFormat.Width;
                Table  table = first.ParentRow.ParentTable;
                foreach (Row row in table.Rows)
                {
                    if (row.ChildNodes.Count == 1)
                    {
                        break;
                    }
                    row.RemoveChild(row.LastCell);
                    int lastIndex = row.ChildNodes.Count - 1;
                    row.Cells[lastIndex--].CellFormat.Width += (width / 3f);
                    row.Cells[lastIndex--].CellFormat.Width += (width / 3f);
                    row.Cells[lastIndex].CellFormat.Width   += (width / 3f);
                }
            }
            #endregion

            #region 依節權數設定,在畫面上顯示
            string pcDisplay = string.Empty;
            bool   p         = _rc.GetBoolean("列印節數", false);
            bool   c         = _rc.GetBoolean("列印權數", false);
            if (p && c)
            {
                pcDisplay = "節/權數";
            }
            else if (p)
            {
                pcDisplay = "節數";
            }
            else if (c)
            {
                pcDisplay = "權數";
            }

            while (templateBuilder.MoveToMergeField("節權數"))
            {
                templateBuilder.Write(pcDisplay);
            }
            #endregion

            #region 如果使用者不印定期評量,從畫面上將欄位拿掉
            templateBuilder.MoveToMergeField("定期評量");

            if (_rc.GetBoolean("列印定期評量", false) == false)
            {
                Cell   assignmentCell = templateBuilder.CurrentParagraph.ParentNode as Cell;
                double width          = assignmentCell.CellFormat.Width;
                bool   hasText        = false;
                if (assignmentCell.NextSibling != null)
                {
                    hasText = true;
                }
                Table scoreTable = assignmentCell.ParentRow.ParentTable;
                foreach (Row eachRow in scoreTable.Rows)
                {
                    if (eachRow.Cells.Count == 1)
                    {
                        break;
                    }

                    int lastIndex = 0;
                    if (hasText)
                    {
                        eachRow.RemoveChild(eachRow.Cells[eachRow.Count - 3]);
                        lastIndex = eachRow.ChildNodes.Count - 3;
                    }
                    else
                    {
                        eachRow.RemoveChild(eachRow.LastCell);
                        lastIndex = eachRow.ChildNodes.Count - 1;
                    }
                    eachRow.Cells[lastIndex--].CellFormat.Width += (width / 2f);
                    eachRow.Cells[lastIndex].CellFormat.Width   += (width / 2f);
                }
            }
            else
            {
                templateBuilder.Write("定期評量");
            }
            #endregion


            #region 如果使用者不印平時評量,從畫面上將欄位拿掉
            templateBuilder.MoveToMergeField("平時評量");

            if (_rc.GetBoolean("列印平時評量", false) == false)
            {
                Cell   assignmentCell = templateBuilder.CurrentParagraph.ParentNode as Cell;
                double width          = assignmentCell.CellFormat.Width;
                bool   hasText        = false;
                if (assignmentCell.NextSibling != null)
                {
                    hasText = true;
                }
                Table scoreTable = assignmentCell.ParentRow.ParentTable;
                foreach (Row eachRow in scoreTable.Rows)
                {
                    if (eachRow.Cells.Count == 1)
                    {
                        break;
                    }

                    int lastIndex = 0;
                    if (hasText)
                    {
                        eachRow.RemoveChild(eachRow.Cells[eachRow.Count - 2]);
                        lastIndex = eachRow.ChildNodes.Count - 2;
                    }
                    else
                    {
                        eachRow.RemoveChild(eachRow.LastCell);
                        lastIndex = eachRow.ChildNodes.Count - 1;
                    }
                    eachRow.Cells[lastIndex--].CellFormat.Width += (width / 2f);
                    eachRow.Cells[lastIndex].CellFormat.Width   += (width / 2f);
                }
            }
            else
            {
                templateBuilder.Write("平時評量");
            }
            #endregion

            #region 如果使用者不印定期學習評量總成績,從畫面上將欄位拿掉
            templateBuilder.MoveToMergeField("定期學習評量總成績");

            if (_rc.GetBoolean("列印定期學習評量總成績", false) == false)
            {
                Cell   assignmentCell = templateBuilder.CurrentParagraph.ParentNode as Cell;
                double width          = assignmentCell.CellFormat.Width;
                bool   hasText        = false;
                if (assignmentCell.NextSibling != null)
                {
                    hasText = true;
                }
                Table scoreTable = assignmentCell.ParentRow.ParentTable;
                foreach (Row eachRow in scoreTable.Rows)
                {
                    if (eachRow.Cells.Count == 1)
                    {
                        break;
                    }

                    int lastIndex = 0;
                    if (hasText)
                    {
                        eachRow.RemoveChild(eachRow.Cells[eachRow.Count - 2]);
                        lastIndex = eachRow.ChildNodes.Count - 2;
                    }
                    else
                    {
                        eachRow.RemoveChild(eachRow.LastCell);
                        lastIndex = eachRow.ChildNodes.Count - 1;
                    }
                    eachRow.Cells[lastIndex--].CellFormat.Width += (width / 2f);
                    eachRow.Cells[lastIndex].CellFormat.Width   += (width / 2f);
                }
            }
            else
            {
                templateBuilder.Write("定期學習評量總成績");
            }
            #endregion


            #region 取得學生成績計算規則
            ScoreCalculator defaultScoreCalculator = new ScoreCalculator(null);

            //key: ScoreCalcRuleID
            Dictionary <string, ScoreCalculator> calcCache = new Dictionary <string, ScoreCalculator>();
            //key: StudentID, val: ScoreCalcRuleID
            Dictionary <string, string> calcIDCache = new Dictionary <string, string>();
            List <string> scoreCalcRuleIDList       = new List <string>();
            foreach (JHStudentRecord student in _config.Students)
            {
                //calcCache.Add(student.ID, new ScoreCalculator(student.ScoreCalcRule));
                string calcID = string.Empty;
                if (!string.IsNullOrEmpty(student.OverrideScoreCalcRuleID))
                {
                    calcID = student.OverrideScoreCalcRuleID;
                }
                else if (student.Class != null && !string.IsNullOrEmpty(student.Class.RefScoreCalcRuleID))
                {
                    calcID = student.Class.RefScoreCalcRuleID;
                }

                if (!string.IsNullOrEmpty(calcID))
                {
                    calcIDCache.Add(student.ID, calcID);
                }
            }
            foreach (JHScoreCalcRuleRecord record in JHScoreCalcRule.SelectByIDs(calcIDCache.Values))
            {
                if (!calcCache.ContainsKey(record.ID))
                {
                    calcCache.Add(record.ID, new ScoreCalculator(record));
                }
            }
            //MsgBox.Show("" + (Environment.TickCount - t));
            #endregion

            #region 檢查學生成績是否超出可列印行數

            foreach (JHStudentRecord student in _config.Students)
            {
                if (scCache.ContainsKey(student.ID))
                {
                    int checkCount = 0;
                    if (_config.DomainSubjectSetup == "Subject")
                    {
                        checkCount = scCache[student.ID].Count;
                    }
                    else
                    {
                        List <string> checkDomains = new List <string>();
                        foreach (string courseID in scCache[student.ID])
                        {
                            JHCourseRecord course = courseCache[courseID];
                            if (string.IsNullOrEmpty(course.Domain))
                            {
                                checkCount++;
                            }
                            else if (!checkDomains.Contains(course.Domain))
                            {
                                checkDomains.Add(course.Domain);
                            }
                        }
                        checkCount += checkDomains.Count;
                    }

                    if (checkCount > _rowCount)
                    {
                        _overStudentList.Add(student.ID);
                    }
                }
            }

            //有學生資料超出範圍
            if (_overStudentList.Count > 0)
            {
                //K12.Presentation.NLDPanels.Student.AddToTemp(overStudentList);
                System.Windows.Forms.DialogResult result = MsgBox.Show("有 " + _overStudentList.Count + " 位學生評量成績資料超出範本可列印範圍,已將學生加入待處理。\n是否繼續列印?", System.Windows.Forms.MessageBoxButtons.YesNo);
                if (result == System.Windows.Forms.DialogResult.No)
                {
                    e.Result = "Cancel";
                }
            }
            #endregion

            // 取得學生課程ID對照
            Dictionary <string, List <string> > studCourseID = new Dictionary <string, List <string> >();
            List <string> sid = (from stud in _config.Students select stud.ID).ToList();
            foreach (JHSCAttendRecord attend in JHSCAttend.SelectByStudentIDs(sid))
            {
                if (attend.Course.SchoolYear.HasValue && attend.Course.Semester.HasValue)
                {
                    if (attend.Course.SchoolYear == _config.SchoolYear && attend.Course.Semester == _config.Semester)
                    {
                        if (studCourseID.ContainsKey(attend.RefStudentID))
                        {
                            studCourseID[attend.RefStudentID].Add(attend.RefCourseID);
                        }
                        else
                        {
                            List <string> coid = new List <string>();
                            coid.Add(attend.RefCourseID);
                            studCourseID.Add(attend.RefStudentID, coid);
                        }
                    }
                }
            }

            // 取得學期歷程
            Config._StudSemesterHistoryItemDict.Clear();

            List <JHSemesterHistoryRecord> semHisRec = JHSemesterHistory.SelectByStudents(_config.Students);
            // 當畫面學期歷程內的學年度學期與畫面上設定相同,加入
            foreach (JHSemesterHistoryRecord rec in semHisRec)
            {
                foreach (K12.Data.SemesterHistoryItem shi in rec.SemesterHistoryItems)
                {
                    if (shi.SchoolYear == _config.SchoolYear && shi.Semester == _config.Semester)
                    {
                        if (!Config._StudSemesterHistoryItemDict.ContainsKey(shi.RefStudentID))
                        {
                            Config._StudSemesterHistoryItemDict.Add(shi.RefStudentID, shi);
                        }
                    }
                }
            }

            // 取得評量比例
            Utility.ScorePercentageHSDict.Clear();
            Utility.ScorePercentageHSDict = Utility.GetScorePercentageHS();


            #region 產生
            foreach (JHStudentRecord student in _config.Students)
            {
                count++;
                if (_overStudentList.Contains(student.ID))
                {
                    continue;
                }
                Document        each    = (Document)_template.Clone(true);
                DocumentBuilder builder = new DocumentBuilder(each);

                #region 學生基本資料
                StudentBasicInfo basicInfo = new StudentBasicInfo(builder);
                basicInfo.SetStudent(student);
                #endregion

                #region 班導師
                builder.MoveToMergeField("班導師");
                if (historyCache.ContainsKey(student.ID))
                {
                    builder.Write(historyCache[student.ID].Teacher);
                }
                else
                {
                    builder.Write(string.Empty);
                }
                #endregion

                #region 成績
                List <HC.JHSCETakeRecord> sceScoreList = null;
                if (sceScoreCache.ContainsKey(student.ID))
                {
                    sceScoreList = sceScoreCache[student.ID];
                }
                else
                {
                    sceScoreList = new List <HC.JHSCETakeRecord>();
                }
                ScoreCalculator studentCalculator = defaultScoreCalculator;
                if (calcIDCache.ContainsKey(student.ID) && calcCache.ContainsKey(calcIDCache[student.ID]))
                {
                    studentCalculator = calcCache[calcIDCache[student.ID]];
                }

                // 過濾 courseCache studid
                Dictionary <string, JHCourseRecord> courseCache1 = new Dictionary <string, JHCourseRecord>();

                foreach (KeyValuePair <string, JHCourseRecord> val in courseCache)
                {
                    // 從學生修課來對應到課程
                    if (studCourseID.ContainsKey(student.ID))
                    {
                        if (studCourseID[student.ID].Contains(val.Value.ID))
                        {
                            courseCache1.Add(val.Key, val.Value);
                        }
                    }
                }

                StudentExamScore examScore = new StudentExamScore(builder, _config, courseCache1);
                examScore.PrintPeriod     = _rc.GetBoolean("列印節數", false);
                examScore.PrintCredit     = _rc.GetBoolean("列印權數", false);
                examScore.PrintText       = _rc.GetBoolean("列印文字評語", true);
                examScore.PrintScore      = _rc.GetBoolean("列印定期評量", true);
                examScore.PrintAssScore   = _rc.GetBoolean("列印平時評量", true);
                examScore.PrintTotalScore = _rc.GetBoolean("列印定期學習評量總成績", true);

                examScore.SetScoreCalculator(studentCalculator);
                if (scCache.ContainsKey(student.ID))
                {
                    examScore.SetSubjects(scCache[student.ID]);
                }
                examScore.SetData(sceScoreList);

                #endregion

                if (_config.DomainSubjectSetup == "Subject")
                {
                    // 科目定期評量加權平均
                    if (builder.MoveToMergeField("加權平均") || builder.MoveToMergeField("定期評量加權平均"))
                    {
                        if (examScore.SubjAvgScore > 0)
                        {
                            builder.Write(examScore.SubjAvgScore.ToString());
                        }
                        else
                        {
                            builder.Write("");
                        }
                    }

                    // 科目平時評量加權平均
                    if (builder.MoveToMergeField("平時評量加權平均"))
                    {
                        if (examScore.SubjAvgAssignmentScore > 0)
                        {
                            builder.Write(examScore.SubjAvgAssignmentScore.ToString());
                        }
                        else
                        {
                            builder.Write("");
                        }
                    }

                    // 科目學習總分加權平均
                    if (builder.MoveToMergeField("定期學習評量總成績加權平均"))
                    {
                        if (examScore.SubjAvgFinalScore > 0)
                        {
                            builder.Write(examScore.SubjAvgFinalScore.ToString());
                        }
                        else
                        {
                            builder.Write("");
                        }
                    }
                }
                else
                {
                    // 領域定期評量加權平均
                    if (builder.MoveToMergeField("加權平均") || builder.MoveToMergeField("定期評量加權平均"))
                    {
                        if (examScore.DomainAvgScore > 0)
                        {
                            builder.Write(examScore.DomainAvgScore.ToString());
                        }
                        else
                        {
                            builder.Write("");
                        }
                    }

                    // 領域平時評量加權平均
                    if (builder.MoveToMergeField("平時評量加權平均"))
                    {
                        if (examScore.DomainAvgAssignmentScore > 0)
                        {
                            builder.Write(examScore.DomainAvgAssignmentScore.ToString());
                        }
                        else
                        {
                            builder.Write("");
                        }
                    }

                    // 領域學習總分加權平均
                    if (builder.MoveToMergeField("定期學習評量總成績加權平均"))
                    {
                        if (examScore.DomainAvgFinalScore > 0)
                        {
                            builder.Write(examScore.DomainAvgFinalScore.ToString());
                        }
                        else
                        {
                            builder.Write("");
                        }
                    }
                }

                #region 日常表現
                List <JHMeritRecord>      meritList      = null;
                List <JHDemeritRecord>    demeritList    = null;
                List <JHAttendanceRecord> attendanceList = null;

                meritList      = (meritCache.ContainsKey(student.ID)) ? meritCache[student.ID] : new List <JHMeritRecord>();
                demeritList    = (demeritCache.ContainsKey(student.ID)) ? demeritCache[student.ID] : new List <JHDemeritRecord>();
                attendanceList = (attendanceCache.ContainsKey(student.ID)) ? attendanceCache[student.ID] : new List <JHAttendanceRecord>();

                StudentMoralScore moral = new StudentMoralScore(builder, _config, periodMapping, absenceList);
                moral.SetData(meritList, demeritList, attendanceList);
                #endregion

                foreach (Section sec in each.Sections)
                {
                    _doc.Sections.Add(_doc.ImportNode(sec, true));
                }

                //回報進度
                _worker.ReportProgress((int)(count * 100.0 / total));
            }

            List <string> globalFieldName  = new List <string>();
            List <object> globalFieldValue = new List <object>();

            globalFieldName.Add("學校名稱");
            globalFieldValue.Add(K12.Data.School.ChineseName);

            globalFieldName.Add("學年度");
            globalFieldValue.Add(_config.SchoolYear);

            globalFieldName.Add("學期");
            globalFieldValue.Add(_config.Semester);

            globalFieldName.Add("評量名稱");
            globalFieldValue.Add(_config.Exam.Name);

            globalFieldName.Add("統計期間");
            globalFieldValue.Add(_config.StartDate.ToShortDateString() + " ~ " + _config.EndDate.ToShortDateString());

            globalFieldName.Add("列印日期");
            globalFieldValue.Add(DateConvert.CDate(DateTime.Now.ToString("yyyy/MM/dd")) + " " + DateTime.Now.ToString("HH:mm:ss"));

            string chancellor, eduDirector, stuDirector;
            chancellor = eduDirector = stuDirector = string.Empty;

            XmlElement schoolInfo         = K12.Data.School.Configuration["學校資訊"].PreviousData;
            XmlElement chancellorElement  = (XmlElement)schoolInfo.SelectSingleNode("ChancellorChineseName");
            XmlElement eduDirectorElement = (XmlElement)schoolInfo.SelectSingleNode("EduDirectorName");

            if (chancellorElement != null)
            {
                chancellor = chancellorElement.InnerText;
            }
            if (eduDirectorElement != null)
            {
                eduDirector = eduDirectorElement.InnerText;
            }

            globalFieldName.Add("教務主任");
            globalFieldValue.Add(eduDirector);

            globalFieldName.Add("校長");
            globalFieldValue.Add(chancellor);

            globalFieldName.Add("成績校正日期");
            globalFieldValue.Add(_rc.GetString("成績校正日期", string.Empty));

            if (_config.Students.Count > _overStudentList.Count)
            {
                _doc.MailMerge.Execute(globalFieldName.ToArray(), globalFieldValue.ToArray());
            }

            #endregion
        }
        public DataRationalityMessage Execute()
        {
            RATRecords.Clear();

            DataRationalityMessage Message = new DataRationalityMessage();

            int UpdateRecordCount = 0;

            //取得學生資料及建立資料物件
            foreach (JHStudentRecord student in JHStudent.SelectAll())
            {
                if (!Dic.ContainsKey(student.ID))
                {
                    Dic.Add(student.ID, new SuperObj_new(student));
                }
            }

            foreach (JHUpdateRecordRecord each in JHUpdateRecord.SelectByStudentIDs(Dic.Keys))
            {
                if (each.UpdateCode == "3")              //轉入異動代碼為"3"
                {
                    if (Dic.ContainsKey(each.StudentID)) //包含於清單內
                    {
                        Dic.Remove(each.StudentID);      //將其移除
                        UpdateRecordCount++;
                    }
                }
            }

            //取得所有懲戒明細,並加入學生資料物件內
            foreach (JHDemeritRecord demerit in JHDemerit.SelectAll())
            {
                if (Dic.ContainsKey(demerit.RefStudentID))
                {
                    Dic[demerit.RefStudentID].DemeritList.Add(demerit);
                }
            }

            //取得(971,972,981,982)自動統計,排除目前學年度/學期
            List <SchoolYearSemester> SysList = new List <SchoolYearSemester>();

            SysList.Add(new SchoolYearSemester(97, 1));
            SysList.Add(new SchoolYearSemester(97, 2));
            SysList.Add(new SchoolYearSemester(98, 1));
            SysList.Add(new SchoolYearSemester(98, 2));
            SysList.Add(new SchoolYearSemester(99, 1));
            SysList.Add(new SchoolYearSemester(99, 2));
            List <AutoSummaryRecord> AutoSummaryList = AutoSummary.Select(Dic.Keys, SysList, SummaryType.Discipline, true);

            foreach (AutoSummaryRecord autoSummary in AutoSummaryList)
            {
                if (!Dic[autoSummary.RefStudentID].AutoSummaryDic.Contains(autoSummary))
                {
                    Dic[autoSummary.RefStudentID].AutoSummaryDic.Add(autoSummary);
                }
            }


            foreach (string each in Dic.Keys)
            {
                //if (Dic[each].IsCleadDmmerit())
                //{
                if (Dic[each].DetailAndSummary(97, 1))
                {
                    SetValue(Dic[each], 97, 1);
                }
                if (Dic[each].DetailAndSummary(97, 2))
                {
                    SetValue(Dic[each], 97, 2);
                }
                if (Dic[each].DetailAndSummary(98, 1))
                {
                    SetValue(Dic[each], 98, 1);
                }
                if (Dic[each].DetailAndSummary(98, 2))
                {
                    SetValue(Dic[each], 98, 2);
                }
                if (Dic[each].DetailAndSummary(99, 1))
                {
                    SetValue(Dic[each], 99, 1);
                }
                if (Dic[each].DetailAndSummary(99, 2))
                {
                    SetValue(Dic[each], 99, 2);
                }
                //}
            }

            //錯誤說明
            StringBuilder strBuilder = new StringBuilder();

            strBuilder.AppendLine("檢查(非明細統計)筆數:" + AutoSummaryList.Count());
            strBuilder.AppendLine("檢查(非明細統計)不為0筆數:" + RATRecords.Count);
            strBuilder.AppendLine("具有(轉入異動)記錄之學生共" + UpdateRecordCount + "名,未列入檢查範圍!");
            strBuilder.AppendLine("(非明細定義於:僅轉入生可以有值)");

            var SortedRATRecords = from RATRecord in RATRecords orderby RATRecord.班級, K12.Data.Int.ParseAllowNull(RATRecord.座號), RATRecord.學年度, RATRecord.學期 select RATRecord;

            Message.Data    = SortedRATRecords.ToList();
            Message.Message = strBuilder.ToString();

            if (RATRecords.Count == 0)
            {
                MsgBox.Show("未檢查到錯誤資料!!");
            }

            return(Message);
        }
Exemple #5
0
        private void Worker_DoWork(object sender, DoWorkEventArgs e)
        {
            double total = Students.Count;
            double count = 0;

            _worker.ReportProgress(0);

            List <string> studentIDs = Students.Select(x => x.ID).ToList();

            #region 快取資料

            //獎勵
            // 1.依學生編號、開始日期、結束日期,取得學生獎勵紀錄
            // 2.依學生編號進行分群
            Dictionary <string, List <JHMeritRecord> > meritCache = new Dictionary <string, List <JHMeritRecord> >();
            foreach (JHMeritRecord record in JHMerit.Select(studentIDs, _config.StartDate, _config.EndDate, null, null, null, null))
            {
                if (!meritCache.ContainsKey(record.RefStudentID))
                {
                    meritCache.Add(record.RefStudentID, new List <JHMeritRecord>());
                }
                meritCache[record.RefStudentID].Add(record);
            }

            //懲戒
            // 1.依學生編號、開始日期、結束日期,取得學生懲戒紀錄
            // 2.依學生編號進行分群
            Dictionary <string, List <JHDemeritRecord> > demeritCache = new Dictionary <string, List <JHDemeritRecord> >();
            foreach (JHDemeritRecord record in JHDemerit.Select(studentIDs, _config.StartDate, _config.EndDate, null, null, null, null))
            {
                if (!demeritCache.ContainsKey(record.RefStudentID))
                {
                    demeritCache.Add(record.RefStudentID, new List <JHDemeritRecord>());
                }
                demeritCache[record.RefStudentID].Add(record);
            }

            //缺曠
            // 1.依學生編號、開始日期、結束日期,取得學生缺曠紀錄
            // 2.依學生編號進行分群
            Dictionary <string, List <JHAttendanceRecord> > attendanceCache = new Dictionary <string, List <JHAttendanceRecord> >();
            foreach (JHAttendanceRecord record in JHAttendance.Select(studentIDs, _config.StartDate, _config.EndDate, null, null, null))
            {
                if (!attendanceCache.ContainsKey(record.RefStudentID))
                {
                    attendanceCache.Add(record.RefStudentID, new List <JHAttendanceRecord>());
                }
                attendanceCache[record.RefStudentID].Add(record);
            }

            // 建立平時評量與修課成績Idx Key studentID
            Dictionary <string, List <JHSCAttendRecord> > _studAttendRecDict = new Dictionary <string, List <JHSCAttendRecord> >();


            //修課紀錄
            // 1.依學生編號、學年度、學期,取得修課紀錄
            // 2.
            List <string> courseIDs = new List <string>();
            List <string> attendIDs = new List <string>();
            Dictionary <string, List <string> > scCache = new Dictionary <string, List <string> >();
            foreach (var attend in JHSCAttend.Select(studentIDs, null, null, "" + _config.SchoolYear, "" + _config.Semester))
            {
                attendIDs.Add(attend.ID);
                if (!scCache.ContainsKey(attend.RefStudentID))
                {
                    scCache.Add(attend.RefStudentID, new List <string>());
                }
                scCache[attend.RefStudentID].Add(attend.RefCourseID);
                if (!courseIDs.Contains(attend.RefCourseID))
                {
                    courseIDs.Add(attend.RefCourseID);
                }

                // 建立評量與修課成績
                if (_studAttendRecDict.ContainsKey(attend.RefStudentID))
                {
                    _studAttendRecDict[attend.RefStudentID].Add(attend);
                }
                else
                {
                    List <JHSCAttendRecord> atten = new List <JHSCAttendRecord>();
                    atten.Add(attend);
                    _studAttendRecDict.Add(attend.RefStudentID, atten);
                }
            }

            //課程
            // 1.依課程編號取得課程紀錄
            // 2.略過不列入成績計算的課程
            JHCourse.RemoveByIDs(courseIDs);
            Dictionary <string, JHCourseRecord> courseCache = JHCourse.SelectByIDs(courseIDs).Where(x => x.CalculationFlag != "2").ToDictionary(x => x.ID);

            //試別資訊: 取得所有試別
            Dictionary <string, JHExamRecord> examCache = JHExam.SelectAll().ToDictionary(x => x.ID);

            // 取得社團ExamID
            List <string> NExamIDList = new List <string> ();
            foreach (JHExamRecord rec in JHExam.SelectAll())
            {
                if (rec.Name.IndexOf("社團") > -1)
                {
                    NExamIDList.Add(rec.ID);
                }
            }

            //評量成績
            // 1.依修課記錄及所有試別取得評量成績
            // 2.依第1點的評量成績取得試別編號 (實際學生評量成績中的試別編號)
            // 3.依學生編號進行分群
            Dictionary <string, List <KH.JHSCETakeRecord> > sceScoreCache = new Dictionary <string, List <KH.JHSCETakeRecord> >();
            List <string> validExamIDs = new List <string>();

            // 檢查有修課才讀取成績
            if (attendIDs.Count > 0 && examCache.Count > 0)
            {
                foreach (JHSCETakeRecord record in JHSCETake.Select(null, null, examCache.Keys, null, attendIDs))
                {
                    if (!NExamIDList.Contains(record.RefExamID))
                    {
                        if (!validExamIDs.Contains(record.RefExamID))
                        {
                            validExamIDs.Add(record.RefExamID);
                        }
                    }

                    if (!sceScoreCache.ContainsKey(record.RefStudentID))
                    {
                        sceScoreCache.Add(record.RefStudentID, new List <KH.JHSCETakeRecord>());
                    }
                    sceScoreCache[record.RefStudentID].Add(new KH.JHSCETakeRecord(record));
                }
            }

            //將『所有試別編號』與『實際學生評量成績中的試別編號』做交集,以取得使用管理的試別次序
            //假設『所有試別編號』為1,4,3,5
            //假設『實際學生評量成績中的試別編號』為3,4,1
            //交集後的結果為1,4,3
            validExamIDs = examCache.Keys.Intersect(validExamIDs).ToList();

            validExamIDs.Add("平時評量");
            //validExamIDs.Add("課程總成績");

            // 取得學生成績計算規則
            // 如果學生沒有計算規則一律用預設,預設進位方式取到小數點第2位
            ScoreCalculator defaultScoreCalculator = new ScoreCalculator(null);
            //key: ScoreCalcRuleID
            Dictionary <string, ScoreCalculator> calcCache = new Dictionary <string, ScoreCalculator>();
            //key: StudentID, val: ScoreCalcRuleID
            Dictionary <string, string> calcIDCache = new Dictionary <string, string>();

            List <string> scoreCalcRuleIDList = new List <string>();

            // 取得學生計算規則的ID,建立對照表
            // 如果學生身上有指定成績計算規則,就以學生身上成績計算規則為主
            // 如果學生身上沒有指定成績計算規則,就以學生所屬班級成績計算規則為主
            foreach (JHStudentRecord student in _config.Students)
            {
                string calcID = string.Empty;
                if (!string.IsNullOrEmpty(student.OverrideScoreCalcRuleID))
                {
                    calcID = student.OverrideScoreCalcRuleID;
                }
                else if (student.Class != null && !string.IsNullOrEmpty(student.Class.RefScoreCalcRuleID))
                {
                    calcID = student.Class.RefScoreCalcRuleID;
                }

                if (!string.IsNullOrEmpty(calcID))
                {
                    calcIDCache.Add(student.ID, calcID);
                }
            }
            // 取得計算規則建立成績進位器
            foreach (JHScoreCalcRuleRecord record in JHScoreCalcRule.SelectByIDs(calcIDCache.Values))
            {
                if (!calcCache.ContainsKey(record.ID))
                {
                    calcCache.Add(record.ID, new ScoreCalculator(record));
                }
            }

            #endregion


            #region 判斷領域是否需要展開
            //判斷領域是否展開對照表
            //Key:領域名稱
            //Value:false=展開,true=不展開
            //展開: 詳列該領域下所有科目成績
            //不展開: 只列該領域成績
            Dictionary <string, bool> domains = new Dictionary <string, bool>();

            DomainSubjectSetup domainSubjectSetup = _config.DomainSubjectSetup;
            //使用者設定"只列印領域"
            if (domainSubjectSetup == DomainSubjectSetup.Domain)
            {
                //預設從領域資料管理來的領域名稱皆不展開
                foreach (var domain in JHSchool.Evaluation.Subject.Domains)
                {
                    domains.Add(domain, DomainSubjectExpand.展開);
                }
                //彈性課程一定展開
                if (!domains.ContainsKey(""))
                {
                    domains.Add("", DomainSubjectExpand.展開);
                }
            }
            //使用者設定"只列印科目"
            else if (domainSubjectSetup == DomainSubjectSetup.Subject)
            {
                //預設從領域資料管理來的領域名稱皆展開
                foreach (var domain in JHSchool.Evaluation.Subject.Domains)
                {
                    domains.Add(domain, DomainSubjectExpand.展開);
                }
                //彈性課程一定展開
                if (!domains.ContainsKey(""))
                {
                    domains.Add("", DomainSubjectExpand.展開);
                }
            }
            else
            {
                throw new Exception("請重新儲存一次列印設定");
            }

            _config.PrintDomains = domains;
            #endregion

            #region 建立節次對照
            Dictionary <string, string> periodMapping = JHPeriodMapping.SelectAll().ToDictionary(x => x.Name, y => y.Type);
            #endregion

            #region 假別列表
            List <string> absenceList = JHAbsenceMapping.SelectAll().Select(x => x.Name).ToList();
            #endregion

            #region 依評量試別重新劃分範本
            //如有不懂自求多福
            int             rowCount        = 0;
            DocumentBuilder templateBuilder = new DocumentBuilder(_template);
            templateBuilder.MoveToMergeField("各次評量");
            Font   font       = templateBuilder.Font;
            Cell   examsCell  = templateBuilder.CurrentParagraph.ParentNode as Cell;
            Table  table      = examsCell.ParentRow.ParentTable;
            double width      = examsCell.CellFormat.Width;
            double examWidth  = width / (double)validExamIDs.Count;
            double scoreWidth = width / (double)validExamIDs.Count / 2.0;

            //計算有幾個 Score Row
            foreach (Row row in table.Rows)
            {
                if (row.Cells.Count > 3)
                {
                    rowCount++;
                }
            }

            #region Header Cell
            //建立評量欄位對照表
            Dictionary <string, int> columnMapping = new Dictionary <string, int>();
            int columnShift = 3;
            int columnIndex = 0;

            table.Rows[0].LastCell.Remove();
            table.Rows[1].LastCell.Remove();

            foreach (string examID in validExamIDs)
            {
                columnMapping.Add(examID, columnIndex + columnShift);

                Cell topHeaderCell = new Cell(_template);
                if (examID == "平時評量" || examID == "課程總成績")
                {
                    WordHelper.Write(topHeaderCell, font, examID);
                }
                else
                {
                    WordHelper.Write(topHeaderCell, font, examCache[examID].Name);
                }
                table.Rows[0].Cells.Add(topHeaderCell);

                Cell subHeaderCell1 = new Cell(_template);
                WordHelper.Write(subHeaderCell1, font, "分數", "評量");
                table.Rows[1].Cells.Add(subHeaderCell1);
                columnIndex++;

                Cell subHeaderCell2 = new Cell(_template);
                WordHelper.Write(subHeaderCell2, font, "努力", "程度");
                table.Rows[1].Cells.Add(subHeaderCell2);
                columnIndex++;

                topHeaderCell.CellFormat.Width  = examWidth;
                subHeaderCell1.CellFormat.Width = subHeaderCell2.CellFormat.Width = scoreWidth;

                topHeaderCell.CellFormat.VerticalAlignment  = CellVerticalAlignment.Center;
                subHeaderCell1.CellFormat.VerticalAlignment = CellVerticalAlignment.Center;
                subHeaderCell2.CellFormat.VerticalAlignment = CellVerticalAlignment.Center;
            }

            WordHelper.MergeVerticalCell(table.Rows[0].Cells[1], 2);
            #endregion

            #region Content Cell
            int shift = 2; //Header has 2 rows
            for (int i = 0; i < rowCount; i++)
            {
                table.Rows[i + shift].LastCell.Remove();

                for (int j = 0; j < validExamIDs.Count * 2; j++)
                {
                    Cell contentCell = new Cell(_template);
                    contentCell.CellFormat.Width             = scoreWidth;
                    contentCell.CellFormat.VerticalAlignment = CellVerticalAlignment.Center;

                    table.Rows[i + shift].Cells.Add(contentCell);
                }
            }
            #endregion

            #endregion

            #region 依節權數設定,在畫面上顯示
            string pcDisplay = string.Empty;
            if (_config.PrintPeriod && _config.PrintCredit)
            {
                pcDisplay = "節/權數";
            }
            else if (_config.PrintPeriod)
            {
                pcDisplay = "節數";
            }
            else if (_config.PrintCredit)
            {
                pcDisplay = "權數";
            }

            templateBuilder.MoveToMergeField("節權數");
            templateBuilder.Write(pcDisplay);
            #endregion

            // 取得學期歷程
            Config._StudSemesterHistoryItemDict.Clear();

            List <JHSemesterHistoryRecord> semHisRec = JHSemesterHistory.SelectByStudents(Students);
            // 當畫面學期歷程內的學年度學期與畫面上設定相同,加入
            foreach (JHSemesterHistoryRecord rec in semHisRec)
            {
                foreach (K12.Data.SemesterHistoryItem shi in rec.SemesterHistoryItems)
                {
                    if (shi.SchoolYear == _config.SchoolYear && shi.Semester == _config.Semester)
                    {
                        if (!Config._StudSemesterHistoryItemDict.ContainsKey(shi.RefStudentID))
                        {
                            Config._StudSemesterHistoryItemDict.Add(shi.RefStudentID, shi);
                        }
                    }
                }
            }

            // 取得學生服務學習時數
            Config._SRDict.Clear();
            List <string> sidList = (from data in Students select data.ID).ToList();
            Config._SRDict = Utility.GetServiceLearningDetail(sidList, _config.SchoolYear, _config.Semester);


            #region 產生
            foreach (JHStudentRecord student in Students)
            {
                count++;

                Document        each    = (Document)_template.Clone(true);
                DocumentBuilder builder = new DocumentBuilder(each);

                #region 學生基本資料
                StudentBasicInfo basicInfo = new StudentBasicInfo(builder);
                basicInfo.SetStudent(student);
                #endregion


                #region 各評量成績
                List <KH.JHSCETakeRecord> sceScoreList = null;
                if (sceScoreCache.ContainsKey(student.ID))
                {
                    sceScoreList = sceScoreCache[student.ID];
                }
                else
                {
                    sceScoreList = new List <KH.JHSCETakeRecord>();
                }

                ScoreCalculator studentCalculator = defaultScoreCalculator;
                if (calcIDCache.ContainsKey(student.ID) && calcCache.ContainsKey(calcIDCache[student.ID]))
                {
                    studentCalculator = calcCache[calcIDCache[student.ID]];
                }

                // 課程成績
                Dictionary <string, JHSCAttendRecord> attendRecDict = new Dictionary <string, JHSCAttendRecord>();
                // 領域成績(平時)
                Dictionary <string, decimal?> domainScDict = new Dictionary <string, decimal?>();
                //// 領域成績(總)
                //Dictionary<string, decimal> domainScDictTT = new Dictionary<string, decimal>();

                if (_studAttendRecDict.ContainsKey(student.ID))
                {
                    foreach (JHSCAttendRecord rec in _studAttendRecDict[student.ID])
                    {
                        if (!attendRecDict.ContainsKey(rec.Course.Subject))
                        {
                            attendRecDict.Add(rec.Course.Subject, rec);
                        }
                    }


                    List <string> tName = (from xx in _studAttendRecDict[student.ID] select xx.Course.Domain).Distinct().ToList();

                    foreach (string Name in tName)
                    {
                        decimal?sc = 0, co = 0;
                        foreach (JHSCAttendRecord rec in _studAttendRecDict[student.ID])
                        {
                            if (rec.Course.Domain == Name)
                            {
                                if (rec.OrdinarilyScore.HasValue && rec.Course.Credit.HasValue)
                                {
                                    sc += (rec.OrdinarilyScore.Value * rec.Course.Credit.Value);
                                    // 有成績才算入
                                    co += rec.Course.Credit.Value;
                                }
                            }
                        }

                        if (co.HasValue && sc.HasValue)
                        {
                            if (co.Value > 0)
                            {
                                if (!domainScDict.ContainsKey(Name))
                                {
                                    domainScDict.Add(Name, (sc.Value / co.Value));
                                }
                            }
                        }
                    }
                }

                //StudentExamScore examScore = new StudentExamScore(builder, _config, courseCache, attendRecDict,domainScDict,domainScDictTT);
                StudentExamScore examScore = new StudentExamScore(builder, _config, courseCache, attendRecDict, domainScDict);
                if (scCache.ContainsKey(student.ID))
                {
                    examScore.SetSubjects(scCache[student.ID]);
                }
                examScore.SetColumnMap(columnMapping);
                examScore.SetEffortMapper(_effortMapper);
                examScore.SetCalculator(studentCalculator);
                examScore.SetData(sceScoreList);
                #endregion

                #region 缺曠獎懲
                List <JHMeritRecord>      meritList      = null;
                List <JHDemeritRecord>    demeritList    = null;
                List <JHAttendanceRecord> attendanceList = null;

                meritList      = (meritCache.ContainsKey(student.ID)) ? meritCache[student.ID] : new List <JHMeritRecord>();
                demeritList    = (demeritCache.ContainsKey(student.ID)) ? demeritCache[student.ID] : new List <JHDemeritRecord>();
                attendanceList = (attendanceCache.ContainsKey(student.ID)) ? attendanceCache[student.ID] : new List <JHAttendanceRecord>();

                StudentMoralScore moral = new StudentMoralScore(builder, _config, periodMapping, absenceList);
                moral.SetData(meritList, demeritList, attendanceList);
                #endregion

                foreach (Section sec in each.Sections)
                {
                    _doc.Sections.Add(_doc.ImportNode(sec, true));
                }

                //回報進度
                _worker.ReportProgress((int)(count * 100.0 / total));
            }

            #region 全域 MergeField
            List <string> globalFieldName  = new List <string>();
            List <object> globalFieldValue = new List <object>();

            globalFieldName.Add("學校名稱");
            globalFieldValue.Add(K12.Data.School.ChineseName);

            globalFieldName.Add("學年度");
            globalFieldValue.Add(_config.SchoolYear.ToString());
            //globalFieldValue.Add(K12.Data.School.DefaultSchoolYear);

            globalFieldName.Add("學期");
            globalFieldValue.Add(_config.Semester.ToString());
            //globalFieldValue.Add(K12.Data.School.DefaultSemester);

            globalFieldName.Add("統計期間");
            globalFieldValue.Add(_config.StartDate.ToShortDateString() + " ~ " + _config.EndDate.ToShortDateString());

            globalFieldName.Add("列印日期");
            globalFieldValue.Add(DateConvert.CDate(DateTime.Now.ToString("yyyy/MM/dd")) + " " + DateTime.Now.ToString("HH:mm:ss"));

            string chancellor, eduDirector, stuDirector;
            chancellor = eduDirector = stuDirector = string.Empty;

            XmlElement schoolInfo         = K12.Data.School.Configuration["學校資訊"].PreviousData;
            XmlElement chancellorElement  = (XmlElement)schoolInfo.SelectSingleNode("ChancellorChineseName");
            XmlElement eduDirectorElement = (XmlElement)schoolInfo.SelectSingleNode("EduDirectorName");
            XmlElement stuDirectorElement = (XmlElement)schoolInfo.SelectSingleNode("StuDirectorName");

            if (chancellorElement != null)
            {
                chancellor = chancellorElement.InnerText;
            }
            if (eduDirectorElement != null)
            {
                eduDirector = eduDirectorElement.InnerText;
            }
            if (stuDirectorElement != null)
            {
                stuDirector = stuDirectorElement.InnerText;
            }

            globalFieldName.Add("校長");
            globalFieldValue.Add(chancellor);

            globalFieldName.Add("教務主任");
            globalFieldValue.Add(eduDirector);

            globalFieldName.Add("學務主任");
            globalFieldValue.Add(stuDirector);

            _doc.MailMerge.Execute(globalFieldName.ToArray(), globalFieldValue.ToArray());
            #endregion

            #endregion
        }
Exemple #6
0
        private void Worker_DoWork(object sender, DoWorkEventArgs e)
        {
            double total = Students.Count;
            double count = 0;

            _worker.ReportProgress(0);

            List <string> studentIDs = Students.Select(x => x.ID).ToList();

            //List<string> student_ids = new List<string>();
            //foreach (JHStudentRecord item in Students)
            //    student_ids.Add(item.ID);

            #region 快取資料

            //獎勵
            // 1.依學生編號、開始日期、結束日期,取得學生獎勵紀錄
            // 2.依學生編號進行分群
            Dictionary <string, List <JHMeritRecord> > meritCache = new Dictionary <string, List <JHMeritRecord> >();
            foreach (JHMeritRecord record in JHMerit.Select(studentIDs, _config.StartDate, _config.EndDate, null, null, null, null))
            {
                if (!meritCache.ContainsKey(record.RefStudentID))
                {
                    meritCache.Add(record.RefStudentID, new List <JHMeritRecord>());
                }
                meritCache[record.RefStudentID].Add(record);
            }
            //Dictionary<string, List<JHMeritRecord>> meritCache = new Dictionary<string, List<JHMeritRecord>>();
            //foreach (JHMeritRecord record in JHMerit.SelectByStudentIDs(student_ids))
            //{
            //    if (record.OccurDate < _config.StartDate) continue;
            //    if (record.OccurDate > _config.EndDate) continue;

            //    if (!meritCache.ContainsKey(record.RefStudentID))
            //        meritCache.Add(record.RefStudentID, new List<JHMeritRecord>());
            //    meritCache[record.RefStudentID].Add(record);
            //}

            //懲戒
            // 1.依學生編號、開始日期、結束日期,取得學生懲戒紀錄
            // 2.依學生編號進行分群
            Dictionary <string, List <JHDemeritRecord> > demeritCache = new Dictionary <string, List <JHDemeritRecord> >();
            foreach (JHDemeritRecord record in JHDemerit.Select(studentIDs, _config.StartDate, _config.EndDate, null, null, null, null))
            {
                if (!demeritCache.ContainsKey(record.RefStudentID))
                {
                    demeritCache.Add(record.RefStudentID, new List <JHDemeritRecord>());
                }
                demeritCache[record.RefStudentID].Add(record);
            }

            //Dictionary<string, List<JHDemeritRecord>> demeritCache = new Dictionary<string, List<JHDemeritRecord>>();
            //foreach (JHDemeritRecord record in JHDemerit.SelectByStudentIDs(student_ids))
            //{
            //    if (record.OccurDate < _config.StartDate) continue;
            //    if (record.OccurDate > _config.EndDate) continue;

            //    if (!demeritCache.ContainsKey(record.RefStudentID))
            //        demeritCache.Add(record.RefStudentID, new List<JHDemeritRecord>());
            //    demeritCache[record.RefStudentID].Add(record);
            //}


            ////缺曠
            //// 1.依學生編號、開始日期、結束日期,取得學生缺曠紀錄
            //// 2.依學生編號進行分群
            //Dictionary<string, List<JHAttendanceRecord>> attendanceCache = new Dictionary<string, List<JHAttendanceRecord>>();
            //foreach (JHAttendanceRecord record in JHAttendance.Select(studentIDs, _config.StartDate, _config.EndDate, null, null, null))
            //{
            //    if (!attendanceCache.ContainsKey(record.RefStudentID))
            //        attendanceCache.Add(record.RefStudentID, new List<JHAttendanceRecord>());
            //    attendanceCache[record.RefStudentID].Add(record);
            //}
            //Dictionary<string, List<JHAttendanceRecord>> attendanceCache = new Dictionary<string, List<JHAttendanceRecord>>();
            //foreach (JHAttendanceRecord record in JHAttendance.SelectByStudentIDs(student_ids))
            //{
            //    if (record.OccurDate < _config.StartDate) continue;
            //    if (record.OccurDate > _config.EndDate) continue;

            //    if (!attendanceCache.ContainsKey(record.RefStudentID))
            //        attendanceCache.Add(record.RefStudentID, new List<JHAttendanceRecord>());
            //    attendanceCache[record.RefStudentID].Add(record);
            //}

            //List<string> studentIDs = new List<string>();
            //foreach (var stu in _config.Students)
            //    studentIDs.Add(stu.ID);

            //缺曠
            // 1.依學生編號、開始日期、結束日期,取得學生缺曠紀錄
            // 2.依學生編號進行分群
            Dictionary <string, List <JHAttendanceRecord> > attendanceCache = new Dictionary <string, List <JHAttendanceRecord> >();
            foreach (JHAttendanceRecord record in JHAttendance.Select(studentIDs, _config.StartDate, _config.EndDate, null, null, null))
            {
                if (!attendanceCache.ContainsKey(record.RefStudentID))
                {
                    attendanceCache.Add(record.RefStudentID, new List <JHAttendanceRecord>());
                }
                attendanceCache[record.RefStudentID].Add(record);
            }



            //修課紀錄
            // 1.依學生編號、學年度、學期,取得修課紀錄
            // 2.
            List <string> courseIDs = new List <string>();
            List <string> attendIDs = new List <string>();
            Dictionary <string, List <string> > scCache = new Dictionary <string, List <string> >();
            foreach (var attend in JHSCAttend.Select(studentIDs, null, null, "" + _config.SchoolYear, "" + _config.Semester))
            {
                attendIDs.Add(attend.ID);
                if (!scCache.ContainsKey(attend.RefStudentID))
                {
                    scCache.Add(attend.RefStudentID, new List <string>());
                }
                scCache[attend.RefStudentID].Add(attend.RefCourseID);
                if (!courseIDs.Contains(attend.RefCourseID))
                {
                    courseIDs.Add(attend.RefCourseID);
                }
            }

            //課程
            // 1.依課程編號取得課程紀錄
            // 2.略過不列入成績計算的課程
            JHCourse.RemoveByIDs(courseIDs);
            Dictionary <string, JHCourseRecord> courseCache = JHCourse.SelectByIDs(courseIDs).Where(x => x.CalculationFlag != "2").ToDictionary(x => x.ID);

            //試別資訊: 取得所有試別
            Dictionary <string, JHExamRecord> examCache = JHExam.SelectAll().ToDictionary(x => x.ID);

            // 取得社團ExamID
            List <string> NExamIDList = new List <string>();
            foreach (JHExamRecord rec in JHExam.SelectAll())
            {
                if (rec.Name.IndexOf("社團") > -1)
                {
                    NExamIDList.Add(rec.ID);
                }
            }

            //評量成績
            // 1.依修課記錄及所有試別取得評量成績
            // 2.依第1點的評量成績取得試別編號 (實際學生評量成績中的試別編號)
            // 3.依學生編號進行分群
            Dictionary <string, List <HC.JHSCETakeRecord> > sceScoreCache = new Dictionary <string, List <HC.JHSCETakeRecord> >();
            List <string> validExamIDs = new List <string>();

            //  檢查當有修課紀錄才取成績資料
            if (attendIDs.Count > 0 && examCache.Count > 0)
            {
                foreach (JHSCETakeRecord record in JHSCETake.Select(null, null, examCache.Keys, null, attendIDs))
                {
                    if (!NExamIDList.Contains(record.RefExamID))
                    {
                        if (!validExamIDs.Contains(record.RefExamID))
                        {
                            validExamIDs.Add(record.RefExamID);
                        }
                    }

                    if (!sceScoreCache.ContainsKey(record.RefStudentID))
                    {
                        sceScoreCache.Add(record.RefStudentID, new List <HC.JHSCETakeRecord>());
                    }
                    sceScoreCache[record.RefStudentID].Add(new HC.JHSCETakeRecord(record));
                }
            }

            //將『所有試別編號』與『實際學生評量成績中的試別編號』做交集,以取得使用管理的試別次序
            //假設『所有試別編號』為1,4,3,5
            //假設『實際學生評量成績中的試別編號』為3,4,1
            //交集後的結果為1,4,3
            validExamIDs = examCache.Keys.Intersect(validExamIDs).ToList();



            // 取得學生成績計算規則
            // 如果學生沒有計算規則一律用預設,預設進位方式取到小數點第2位
            ScoreCalculator defaultScoreCalculator = new ScoreCalculator(null);
            //key: ScoreCalcRuleID
            Dictionary <string, ScoreCalculator> calcCache = new Dictionary <string, ScoreCalculator>();
            //key: StudentID, val: ScoreCalcRuleID
            Dictionary <string, string> calcIDCache = new Dictionary <string, string>();

            List <string> scoreCalcRuleIDList = new List <string>();

            // 取得學生計算規則的ID,建立對照表
            // 如果學生身上有指定成績計算規則,就以學生身上成績計算規則為主
            // 如果學生身上沒有指定成績計算規則,就以學生所屬班級成績計算規則為主
            foreach (JHStudentRecord student in _config.Students)
            {
                string calcID = string.Empty;
                if (!string.IsNullOrEmpty(student.OverrideScoreCalcRuleID))
                {
                    calcID = student.OverrideScoreCalcRuleID;
                }
                else if (student.Class != null && !string.IsNullOrEmpty(student.Class.RefScoreCalcRuleID))
                {
                    calcID = student.Class.RefScoreCalcRuleID;
                }

                if (!string.IsNullOrEmpty(calcID))
                {
                    calcIDCache.Add(student.ID, calcID);
                }
            }
            // 取得計算規則建立成績進位器
            foreach (JHScoreCalcRuleRecord record in JHScoreCalcRule.SelectByIDs(calcIDCache.Values))
            {
                if (!calcCache.ContainsKey(record.ID))
                {
                    calcCache.Add(record.ID, new ScoreCalculator(record));
                }
            }


            ////修課紀錄
            //// 1.依學生編號、學年度、學期,取得修課紀錄
            //// 2.
            //List<string> courseIDs = new List<string>();
            //foreach (var attend in JHSCAttend.SelectByStudentIDs(studentIDs))
            //{
            //    if (!courseIDs.Contains(attend.RefCourseID))
            //        courseIDs.Add(attend.RefCourseID);
            //}

            //int schoolYear = _config.SchoolYear;
            //int semester = _config.Semester;
            //List<JHCourseRecord> courses = JHCourse.SelectByIDs(courseIDs);

            ////課程
            //Dictionary<string, JHCourseRecord> courseCache = new Dictionary<string, JHCourseRecord>();
            //foreach (JHCourseRecord record in JHCourse.SelectByIDs(courseIDs))
            //{
            //    if ("" + record.SchoolYear != "" + schoolYear) continue;
            //    if ("" + record.Semester != "" + semester) continue;
            //    if (record.CalculationFlag == "2") continue;
            //    //if (string.IsNullOrEmpty(record.Domain)) continue; //沒有填領域

            //    if (!courseCache.ContainsKey(record.ID))
            //        courseCache.Add(record.ID, record);
            //}

            ////試別資訊
            //Dictionary<string, JHExamRecord> examCache = new Dictionary<string, JHExamRecord>();
            //foreach (JHExamRecord exam in JHExam.SelectAll())
            //{
            //    if (!examCache.ContainsKey(exam.ID))
            //        examCache.Add(exam.ID, exam);
            //}
            //List<string> validExamIDs = new List<string>();

            ////評量成績
            //Dictionary<string, List<HC.JHSCETakeRecord>> sceScoreCache = new Dictionary<string, List<HC.JHSCETakeRecord>>();
            //foreach (JHSCETakeRecord record in JHSCETake.SelectByStudentIDs(student_ids))
            //{
            //    if (examCache.ContainsKey(record.RefExamID))
            //    {
            //        if (!validExamIDs.Contains(record.RefExamID))
            //            validExamIDs.Add(record.RefExamID);
            //    }
            //    else
            //        continue;

            //    if (!sceScoreCache.ContainsKey(record.RefStudentID))
            //        sceScoreCache.Add(record.RefStudentID, new List<HC.JHSCETakeRecord>());
            //    sceScoreCache[record.RefStudentID].Add(new HC.JHSCETakeRecord(record));
            //}
            //// TODO: 這邊的排序有可能再改
            //validExamIDs.Sort(delegate(string x, string y)
            //{
            //    int ix, iy;
            //    if (!int.TryParse(x, out ix))
            //        ix = int.MaxValue;
            //    if (!int.TryParse(y, out iy))
            //        iy = int.MaxValue;
            //    return ix.CompareTo(iy);
            //});

            //學期歷程
            //Dictionary<string, K12.Data.SemesterHistoryItem> historyCache = new Dictionary<string, K12.Data.SemesterHistoryItem>();
            //foreach (JHSemesterHistoryRecord record in JHSemesterHistory.SelectByStudentIDs(student_ids))
            //{
            //    foreach (K12.Data.SemesterHistoryItem item in record.SemesterHistoryItems)
            //    {
            //        if ("" + item.SchoolYear != K12.Data.School.DefaultSchoolYear) continue;
            //        if ("" + item.Semester != K12.Data.School.DefaultSemester) continue;

            //        if (!historyCache.ContainsKey(record.RefStudentID))
            //            historyCache.Add(record.RefStudentID, item);
            //    }
            //}
            #endregion

            #region 判斷領域是否需要展開
            //判斷領域是否展開對照表
            //Key:領域名稱
            //Value:false=展開,true=不展開
            //展開: 詳列該領域下所有科目成績
            //不展開: 只列該領域成績
            Dictionary <string, bool>           domains  = new Dictionary <string, bool>();
            Dictionary <string, List <string> > subjects = new Dictionary <string, List <string> >();

            List <JHCourseRecord> courseList = new List <JHCourseRecord>(courseCache.Values);
            courseList.Sort(delegate(JHCourseRecord x, JHCourseRecord y)
            {
                return(JHSchool.Evaluation.Subject.CompareSubjectOrdinal(x.Subject, y.Subject));
                //List<string> list = new List<string>(new string[] { "國語文", "國文", "英文", "英語", "數學", "歷史", "地理", "公民", "理化", "生物" });
                //int ix = list.IndexOf(x.Subject);
                //int iy = list.IndexOf(y.Subject);

                //if (ix >= 0 && iy >= 0)
                //    return ix.CompareTo(iy);
                //else if (ix >= 0)
                //    return -1;
                //else if (iy >= 0)
                //    return 1;
                //else
                //    return x.Subject.CompareTo(y.Subject);
            });

            DomainSubjectSetup domainSubjectSetup = _config.DomainSubjectSetup;
            //使用者設定"只列印領域"
            if (domainSubjectSetup == DomainSubjectSetup.Domain)
            {
                //預設從領域資料管理來的領域名稱皆不展開
                foreach (var domain in JHSchool.Evaluation.Subject.Domains)
                {
                    domains.Add(domain, DomainSubjectExpand.展開);
                }
                if (domains.ContainsKey("語文"))
                {
                    domains["語文"] = DomainSubjectExpand.展開;
                }

                //彈性課程一定展開
                if (!domains.ContainsKey(""))
                {
                    domains.Add("", DomainSubjectExpand.展開);
                }
                //if (!domains.ContainsKey("彈性課程")) domains.Add("彈性課程", false);
            }
            //使用者設定"只列印科目"
            else if (domainSubjectSetup == DomainSubjectSetup.Subject)
            {
                //預設從領域資料管理來的領域名稱皆展開
                foreach (var domain in JHSchool.Evaluation.Subject.Domains)
                {
                    domains.Add(domain, DomainSubjectExpand.展開);
                }
                //彈性課程一定展開
                if (!domains.ContainsKey(""))
                {
                    domains.Add("", DomainSubjectExpand.展開);
                }
                //if (!domains.ContainsKey("彈性課程")) domains.Add("彈性課程", false);
            }
            else
            {
                throw new Exception("請重新儲存一次列印設定");
            }

            //foreach (var domain in JHSchool.Evaluation.Subject.Domains)
            //    subjects.Add(domain, new List<string>());

            //if (!subjects.ContainsKey("")) subjects.Add("", new List<string>());
            //if (!subjects.ContainsKey("彈性課程")) subjects.Add("彈性課程", new List<string>());

            //foreach (var course in courseList)
            //{
            //    if (!subjects.ContainsKey(course.Domain))
            //        subjects.Add(course.Domain, new List<string>());
            //    if (!subjects[course.Domain].Contains(course.Subject))
            //        subjects[course.Domain].Add(course.Subject);
            //}

            //_config.SetPrintDomains(domains);
            //_config.SetPrintSubjects(subjects);
            _config.PrintDomains = domains;
            #endregion

            #region 建立節次對照
            Dictionary <string, string> periodMapping = JHPeriodMapping.SelectAll().ToDictionary(x => x.Name, y => y.Type);
            //Dictionary<string, string> periodMapping = new Dictionary<string, string>();
            //foreach (JHPeriodMappingInfo info in JHPeriodMapping.SelectAll())
            //{
            //    if (!periodMapping.ContainsKey(info.Name))
            //        periodMapping.Add(info.Name, info.Type);
            //}
            #endregion

            #region 假別列表
            List <string> absenceList = JHAbsenceMapping.SelectAll().Select(x => x.Name).ToList();
            //List<string> absenceList = new List<string>();
            //foreach (JHAbsenceMappingInfo info in JHAbsenceMapping.SelectAll())
            //    absenceList.Add(info.Name);
            #endregion

            #region 依評量試別重新劃分範本
            int             rowCount        = 0;
            DocumentBuilder templateBuilder = new DocumentBuilder(_template);
            templateBuilder.MoveToMergeField("各次評量");
            Font   font       = templateBuilder.Font;
            Cell   examsCell  = templateBuilder.CurrentParagraph.ParentNode as Cell;
            Table  table      = examsCell.ParentRow.ParentTable;
            double width      = examsCell.CellFormat.Width;
            double examWidth  = width / (double)validExamIDs.Count;
            double scoreWidth = width / (double)validExamIDs.Count / 3.0;

            //計算有幾個 Score Row
            foreach (Row row in table.Rows)
            {
                if (row.Cells.Count > 3)
                {
                    rowCount++;
                }
            }

            #region Header Cell
            //建立評量欄位對照表
            Dictionary <string, int> columnMapping = new Dictionary <string, int>();
            int columnShift = 3;
            int columnIndex = 0;

            table.Rows[0].LastCell.Remove();
            table.Rows[1].LastCell.Remove();
            foreach (string examID in validExamIDs)
            {
                columnMapping.Add(examID, columnIndex + columnShift);

                Cell topHeaderCell = new Cell(_template);
                WordHelper.Write(topHeaderCell, font, examCache[examID].Name);
                table.Rows[0].Cells.Add(topHeaderCell);

                Cell subHeaderCell1 = new Cell(_template);
                WordHelper.Write(subHeaderCell1, font, "定期", "評量");
                table.Rows[1].Cells.Add(subHeaderCell1);
                columnIndex++;

                Cell subHeaderCell2 = new Cell(_template);
                WordHelper.Write(subHeaderCell2, font, "平時", "評量");
                table.Rows[1].Cells.Add(subHeaderCell2);
                columnIndex++;

                Cell subHeaderCell3 = new Cell(_template);
                WordHelper.Write(subHeaderCell3, font, "總成績");
                table.Rows[1].Cells.Add(subHeaderCell3);
                columnIndex++;

                topHeaderCell.CellFormat.Width  = examWidth;
                subHeaderCell1.CellFormat.Width = scoreWidth;
                subHeaderCell2.CellFormat.Width = scoreWidth;
                subHeaderCell3.CellFormat.Width = scoreWidth;

                topHeaderCell.CellFormat.VerticalAlignment  = CellVerticalAlignment.Center;
                subHeaderCell1.CellFormat.VerticalAlignment = CellVerticalAlignment.Center;
                subHeaderCell2.CellFormat.VerticalAlignment = CellVerticalAlignment.Center;
                subHeaderCell3.CellFormat.VerticalAlignment = CellVerticalAlignment.Center;
            }
            WordHelper.MergeVerticalCell(table.Rows[0].Cells[1], 2);
            #endregion

            #region Content Cell
            int shift = 2; //Header has 2 rows
            for (int i = 0; i < rowCount; i++)
            {
                table.Rows[i + shift].LastCell.Remove();

                for (int j = 0; j < validExamIDs.Count * 3; j++)
                {
                    Cell contentCell = new Cell(_template);
                    contentCell.CellFormat.Width             = scoreWidth;
                    contentCell.CellFormat.VerticalAlignment = CellVerticalAlignment.Center;

                    table.Rows[i + shift].Cells.Add(contentCell);
                }
            }
            #endregion

            #endregion

            #region 依節權數設定,在畫面上顯示
            string pcDisplay = string.Empty;
            if (_config.PrintPeriod && _config.PrintCredit)
            {
                pcDisplay = "節/權數";
            }
            else if (_config.PrintPeriod)
            {
                pcDisplay = "節數";
            }
            else if (_config.PrintCredit)
            {
                pcDisplay = "權數";
            }

            templateBuilder.MoveToMergeField("節權數");
            templateBuilder.Write(pcDisplay);
            #endregion

            //#region 取得學生成績計算規則

            //ScoreCalculator defaultScoreCalculator = new ScoreCalculator(null);

            ////key: ScoreCalcRuleID
            //Dictionary<string, ScoreCalculator> calcCache = new Dictionary<string, ScoreCalculator>();
            ////key: StudentID, val: ScoreCalcRuleID
            //Dictionary<string, string> calcIDCache = new Dictionary<string, string>();

            //List<string> scoreCalcRuleIDList = new List<string>();

            //foreach (JHStudentRecord student in _config.Students)
            //{
            //    string calcID = string.Empty;
            //    if (!string.IsNullOrEmpty(student.OverrideScoreCalcRuleID))
            //        calcID = student.OverrideScoreCalcRuleID;
            //    else if (student.Class != null && !string.IsNullOrEmpty(student.Class.RefScoreCalcRuleID))
            //        calcID = student.Class.RefScoreCalcRuleID;

            //    if (!string.IsNullOrEmpty(calcID))
            //        calcIDCache.Add(student.ID, calcID);
            //}
            //foreach (JHScoreCalcRuleRecord record in JHScoreCalcRule.SelectByIDs(calcIDCache.Values))
            //{
            //    if (!calcCache.ContainsKey(record.ID))
            //        calcCache.Add(record.ID, new ScoreCalculator(record));
            //}
            //#endregion

            // 取得學期歷程
            Config._StudSemesterHistoryItemDict.Clear();

            List <JHSemesterHistoryRecord> semHisRec = JHSemesterHistory.SelectByStudents(Students);
            // 當畫面學期歷程內的學年度學期與畫面上設定相同,加入
            foreach (JHSemesterHistoryRecord rec in semHisRec)
            {
                foreach (K12.Data.SemesterHistoryItem shi in rec.SemesterHistoryItems)
                {
                    if (shi.SchoolYear == _config.SchoolYear && shi.Semester == _config.Semester)
                    {
                        if (!Config._StudSemesterHistoryItemDict.ContainsKey(shi.RefStudentID))
                        {
                            Config._StudSemesterHistoryItemDict.Add(shi.RefStudentID, shi);
                        }
                    }
                }
            }

            // 取得學生服務學習時數
            Config._SRDict.Clear();
            List <string> sidList = (from data in Students select data.ID).ToList();
            Config._SRDict = Utility.GetServiceLearningDetail(sidList, _config.SchoolYear, _config.Semester);

            #region 產生
            foreach (JHStudentRecord student in Students)
            {
                count++;

                Document        each    = (Document)_template.Clone(true);
                DocumentBuilder builder = new DocumentBuilder(each);

                #region 學生基本資料
                StudentBasicInfo basicInfo = new StudentBasicInfo(builder);
                basicInfo.SetStudent(student);
                #endregion

                //#region 班導師
                //builder.MoveToMergeField("班導師");
                //if (historyCache.ContainsKey(student.ID))
                //    builder.Write(historyCache[student.ID].Teacher);
                //else
                //    builder.Write(string.Empty);
                //#endregion

                #region 各評量成績
                List <HC.JHSCETakeRecord> sceScoreList = null;
                if (sceScoreCache.ContainsKey(student.ID))
                {
                    sceScoreList = sceScoreCache[student.ID];
                }
                else
                {
                    sceScoreList = new List <HC.JHSCETakeRecord>();
                }

                ScoreCalculator studentCalculator = defaultScoreCalculator;
                if (calcIDCache.ContainsKey(student.ID) && calcCache.ContainsKey(calcIDCache[student.ID]))
                {
                    studentCalculator = calcCache[calcIDCache[student.ID]];
                }

                try {
                    StudentExamScore examScore = new StudentExamScore(builder, _config, courseCache);
                    if (scCache.ContainsKey(student.ID))
                    {
                        examScore.SetSubjects(scCache[student.ID]);
                    }
                    examScore.SetColumnMap(columnMapping);
                    examScore.SetCalculator(studentCalculator);
                    examScore.SetData(sceScoreList);
                } catch (Exception erro)
                {
                    e.Cancel = true;
                }

                #endregion

                #region 缺曠獎懲
                List <JHMeritRecord>      meritList      = null;
                List <JHDemeritRecord>    demeritList    = null;
                List <JHAttendanceRecord> attendanceList = null;

                meritList      = (meritCache.ContainsKey(student.ID)) ? meritCache[student.ID] : new List <JHMeritRecord>();
                demeritList    = (demeritCache.ContainsKey(student.ID)) ? demeritCache[student.ID] : new List <JHDemeritRecord>();
                attendanceList = (attendanceCache.ContainsKey(student.ID)) ? attendanceCache[student.ID] : new List <JHAttendanceRecord>();

                StudentMoralScore moral = new StudentMoralScore(builder, _config, periodMapping, absenceList);
                moral.SetData(meritList, demeritList, attendanceList);
                #endregion

                foreach (Section sec in each.Sections)
                {
                    _doc.Sections.Add(_doc.ImportNode(sec, true));
                }

                //回報進度
                _worker.ReportProgress((int)(count * 100.0 / total));
            }

            #region 全域 MergeField
            List <string> globalFieldName  = new List <string>();
            List <object> globalFieldValue = new List <object>();

            globalFieldName.Add("學校名稱");
            globalFieldValue.Add(K12.Data.School.ChineseName);

            globalFieldName.Add("學年度");
            //globalFieldValue.Add(K12.Data.School.DefaultSchoolYear);
            globalFieldValue.Add(_config.SchoolYear.ToString());

            globalFieldName.Add("學期");
            //globalFieldValue.Add(K12.Data.School.DefaultSemester);
            globalFieldValue.Add(_config.Semester.ToString());

            globalFieldName.Add("統計期間");
            globalFieldValue.Add(_config.StartDate.ToShortDateString() + " ~ " + _config.EndDate.ToShortDateString());

            globalFieldName.Add("列印日期");
            globalFieldValue.Add(DateConvert.CDate(DateTime.Now.ToString("yyyy/MM/dd")) + " " + DateTime.Now.ToString("HH:mm:ss"));

            string chancellor, eduDirector, stuDirector;
            chancellor = eduDirector = stuDirector = string.Empty;

            XmlElement schoolInfo         = K12.Data.School.Configuration["學校資訊"].PreviousData;
            XmlElement chancellorElement  = (XmlElement)schoolInfo.SelectSingleNode("ChancellorChineseName");
            XmlElement eduDirectorElement = (XmlElement)schoolInfo.SelectSingleNode("EduDirectorName");
            XmlElement stuDirectorElement = (XmlElement)schoolInfo.SelectSingleNode("StuDirectorName");

            if (chancellorElement != null)
            {
                chancellor = chancellorElement.InnerText;
            }
            if (eduDirectorElement != null)
            {
                eduDirector = eduDirectorElement.InnerText;
            }
            if (stuDirectorElement != null)
            {
                stuDirector = stuDirectorElement.InnerText;
            }

            globalFieldName.Add("校長");
            globalFieldValue.Add(chancellor);

            globalFieldName.Add("教務主任");
            globalFieldValue.Add(eduDirector);

            globalFieldName.Add("學務主任");
            globalFieldValue.Add(stuDirector);

            _doc.MailMerge.Execute(globalFieldName.ToArray(), globalFieldValue.ToArray());
            #endregion

            #endregion
        }