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 }
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 }