public static void Calculate(List <StudentRecord> students) { const string LearnDomain = "學習領域"; const string CourseLearn = "課程學習"; ScoreCalcRule.Instance.SyncAllBackground(); //SemesterScore.Instance.SyncAllBackground(); Dictionary <string, List <JHSemesterScoreRecord> > studentSemesterScoreRecordCache = new Dictionary <string, List <JHSchool.Data.JHSemesterScoreRecord> >(); foreach (JHSemesterScoreRecord record in JHSemesterScore.SelectByStudentIDs(students.AsKeyList())) { if (!studentSemesterScoreRecordCache.ContainsKey(record.RefStudentID)) { studentSemesterScoreRecordCache.Add(record.RefStudentID, new List <JHSchool.Data.JHSemesterScoreRecord>()); } studentSemesterScoreRecordCache[record.RefStudentID].Add(record); } List <GradScoreRecordEditor> editors = new List <GradScoreRecordEditor>(); BackgroundWorker worker = new BackgroundWorker(); worker.WorkerReportsProgress = true; MultiThreadBackgroundWorker <GradScoreRecordEditor> multiWorker = new MultiThreadBackgroundWorker <GradScoreRecordEditor>(); multiWorker.WorkerReportsProgress = true; multiWorker.AutoReportsProgress = true; multiWorker.PackageSize = 50; multiWorker.Loading = MultiThreadLoading.Light; worker.DoWork += delegate { Dictionary <string, ScoreCalculator> calc = new Dictionary <string, ScoreCalculator>(); double studentTotal = students.Count; double studentCount = 0; foreach (StudentRecord student in students) { studentCount++; #region 取得成績計算規則 string calcID = string.Empty; ScoreCalcRuleRecord calcRecord = student.GetScoreCalcRuleRecord(); if (calcRecord != null) { calcID = calcRecord.ID; if (!calc.ContainsKey(calcID)) { JHScoreCalcRuleRecord record = null; List <JHScoreCalcRuleRecord> list = JHScoreCalcRule.SelectByIDs(new string[] { calcRecord.ID }); if (list.Count > 0) { record = list[0]; } calc.Add(calcID, new ScoreCalculator(record)); } } else { if (!calc.ContainsKey(string.Empty)) { calc.Add(string.Empty, new ScoreCalculator(null)); } } #endregion #region 取得各學期成績 List <JHSemesterScoreRecord> semesterScoreRecordList; if (studentSemesterScoreRecordCache.ContainsKey(student.ID)) { semesterScoreRecordList = studentSemesterScoreRecordCache[student.ID]; } else { semesterScoreRecordList = new List <JHSemesterScoreRecord>(); } Dictionary <string, List <decimal> > domainScores = new Dictionary <string, List <decimal> >(); foreach (JHSemesterScoreRecord record in semesterScoreRecordList) { foreach (K12.Data.DomainScore domain in record.Domains.Values) { if (!domainScores.ContainsKey(domain.Domain)) { domainScores.Add(domain.Domain, new List <decimal>()); } if (domain.Score.HasValue) { domainScores[domain.Domain].Add(domain.Score.Value); } } if (!domainScores.ContainsKey(LearnDomain)) { domainScores.Add(LearnDomain, new List <decimal>()); } if (record.LearnDomainScore.HasValue) { domainScores[LearnDomain].Add(record.LearnDomainScore.Value); } if (!domainScores.ContainsKey(CourseLearn)) { domainScores.Add(CourseLearn, new List <decimal>()); } if (record.CourseLearnScore.HasValue) { domainScores[CourseLearn].Add(record.CourseLearnScore.Value); } } #endregion #region 產生畢業成績資料 GradScoreRecordEditor editor; GradScoreRecord gradScoreRecord = GradScore.Instance.Items[student.ID]; if (gradScoreRecord != null) { editor = gradScoreRecord.GetEditor(); } else { editor = new GradScoreRecordEditor(student); } editor.LearnDomainScore = null; editor.CourseLearnScore = null; editor.Domains.Clear(); foreach (string domain in domainScores.Keys) { decimal total = 0; decimal count = domainScores[domain].Count; if (count <= 0) { continue; } foreach (decimal score in domainScores[domain]) { total += score; } total = total / count; total = calc[calcID].ParseGraduateScore(total); if (domain == LearnDomain) { editor.LearnDomainScore = total; } else if (domain == CourseLearn) { editor.CourseLearnScore = total; } else { if (!editor.Domains.ContainsKey(domain)) { editor.Domains.Add(domain, new GradDomainScore(domain)); } editor.Domains[domain].Score = total; } } editors.Add(editor); #endregion worker.ReportProgress((int)(studentCount * 100 / studentTotal)); } }; worker.ProgressChanged += delegate(object sender, ProgressChangedEventArgs e) { FISCA.Presentation.MotherForm.SetStatusBarMessage("計算畢業成績中", e.ProgressPercentage); }; worker.RunWorkerCompleted += delegate(object sender, RunWorkerCompletedEventArgs e) { if (e.Error != null) { MsgBox.Show("計算畢業成績時發生錯誤。" + e.Error.Message); editors.Clear(); } else { multiWorker.RunWorkerAsync(editors); } }; multiWorker.DoWork += delegate(object sender, PackageDoWorkEventArgs <GradScoreRecordEditor> e) { IEnumerable <GradScoreRecordEditor> list = e.Items; list.SaveAllEditors(); }; multiWorker.ProgressChanged += delegate(object sender, ProgressChangedEventArgs e) { FISCA.Presentation.MotherForm.SetStatusBarMessage("上傳畢業成績中", e.ProgressPercentage); }; multiWorker.RunWorkerCompleted += delegate(object sender, RunWorkerCompletedEventArgs e) { if (e.Error != null) { MsgBox.Show("上傳畢業成績時發生錯誤。" + e.Error.Message); } else { FISCA.Presentation.MotherForm.SetStatusBarMessage("上傳畢業成績完成"); } }; worker.RunWorkerAsync(); }
protected override void OnSaveButtonClick(EventArgs e) { dgv.EndEdit(); if (!IsValid()) { MsgBox.Show("請先修正錯誤。"); return; } GradScoreRecordEditor editor; if (_record != null) { editor = _record.GetEditor(); } else { editor = new GradScoreRecordEditor(Student.Instance.Items[PrimaryKey]); } foreach (DataGridViewRow row in dgv.Rows) { string domain = "" + row.Cells[chDomain.Index].Value; string value = "" + row.Cells[chScore.Index].Value; if ("" + row.Tag == "LearnDomain") { if (!string.IsNullOrEmpty(value)) { editor.LearnDomainScore = decimal.Parse(value); } else { editor.LearnDomainScore = null; } } else if ("" + row.Tag == "CourseLearn") { if (!string.IsNullOrEmpty(value)) { editor.CourseLearnScore = decimal.Parse(value); } else { editor.CourseLearnScore = null; } } else { if (!editor.Domains.ContainsKey(domain)) { editor.Domains.Add(domain, new GradDomainScore(domain)); } if (!string.IsNullOrEmpty(value)) { editor.Domains[domain].Score = decimal.Parse(value); } else { editor.Domains[domain].Score = null; } } } //foreach (TextBox txt in _txtBoxes) //{ // string domain = "" + txt.Tag; // if (!editor.Domains.ContainsKey(domain)) // editor.Domains.Add(domain, new GradDomainScore(domain)); // if (!string.IsNullOrEmpty(txt.Text)) // editor.Domains[domain].Score = decimal.Parse(txt.Text); //} //if (!string.IsNullOrEmpty(txtLearnDomain.Text)) // editor.LearnDomainScore = decimal.Parse(txtLearnDomain.Text); //if (!string.IsNullOrEmpty(txtCourseLearn.Text)) // editor.CourseLearnScore = decimal.Parse(txtCourseLearn.Text); editor.Save(); SaveLog(editor); _listener.Reset(); SaveButtonVisible = CancelButtonVisible = false; base.OnSaveButtonClick(e); }
public override void InitializeImport(SmartSchool.API.PlugIn.Import.ImportWizard wizard) { Dictionary <string, int> _ID_SchoolYear_Semester_GradeYear = new Dictionary <string, int>(); Dictionary <string, List <string> > _ID_SchoolYear_Semester_Subject = new Dictionary <string, List <string> >(); Dictionary <string, JHStudentRecord> _StudentCollection = new Dictionary <string, JHStudentRecord>(); Dictionary <JHStudentRecord, Dictionary <int, decimal> > _StudentPassScore = new Dictionary <JHStudentRecord, Dictionary <int, decimal> >(); wizard.PackageLimit = 3000; wizard.ImportableFields.AddRange("領域", "分數評量"); wizard.RequiredFields.AddRange("領域", "分數評量"); wizard.ValidateStart += delegate(object sender, SmartSchool.API.PlugIn.Import.ValidateStartEventArgs e) { #region ValidateStart _ID_SchoolYear_Semester_GradeYear.Clear(); _ID_SchoolYear_Semester_Subject.Clear(); _StudentCollection.Clear(); List <JHStudentRecord> list = JHStudent.SelectByIDs(e.List); MultiThreadWorker <JHStudentRecord> loader = new MultiThreadWorker <JHStudentRecord>(); loader.MaxThreads = 3; loader.PackageSize = 250; loader.PackageWorker += delegate(object sender1, PackageWorkEventArgs <JHStudentRecord> e1) { GradScore.Instance.SyncDataBackground(e.List); }; loader.Run(list); foreach (JHStudentRecord stu in list) { if (!_StudentCollection.ContainsKey(stu.ID)) { _StudentCollection.Add(stu.ID, stu); } } #endregion }; wizard.ValidateRow += delegate(object sender, SmartSchool.API.PlugIn.Import.ValidateRowEventArgs e) { #region ValidateRow int t; decimal d; JHStudentRecord student; if (_StudentCollection.ContainsKey(e.Data.ID)) { student = _StudentCollection[e.Data.ID]; } else { e.ErrorMessage = "壓根就沒有這個學生" + e.Data.ID; return; } bool inputFormatPass = true; #region 驗各欄位填寫格式 foreach (string field in e.SelectFields) { string value = e.Data[field]; switch (field) { default: break; case "領域": //if (value == "") //{ // inputFormatPass &= false; // e.ErrorFields.Add(field, "必須填寫"); //} //else if (!Domains.Contains(value)) //{ // inputFormatPass &= false; // e.ErrorFields.Add(field, "必須為七大領域、學習領域、課程學習"); //} break; case "分數評量": if (value != "" && !decimal.TryParse(value, out d)) { inputFormatPass &= false; e.ErrorFields.Add(field, "必須填入空白或數值"); } break; } } #endregion //輸入格式正確才會針對情節做檢驗 if (inputFormatPass) { string errorMessage = ""; string key = e.Data.ID; string skey = e.Data["領域"]; if (!_ID_SchoolYear_Semester_Subject.ContainsKey(key)) { _ID_SchoolYear_Semester_Subject.Add(key, new List <string>()); } if (_ID_SchoolYear_Semester_Subject[key].Contains(skey)) { errorMessage += (errorMessage == "" ? "" : "\n") + "同一學生不允許多筆相同畢業領域的資料"; } else { _ID_SchoolYear_Semester_Subject[key].Add(skey); } e.ErrorMessage = errorMessage; } #endregion }; wizard.ImportPackage += delegate(object sender, SmartSchool.API.PlugIn.Import.ImportPackageEventArgs e) { #region ImportPackage Dictionary <string, List <RowData> > id_Rows = new Dictionary <string, List <RowData> >(); #region 分包裝 foreach (RowData data in e.Items) { if (!id_Rows.ContainsKey(data.ID)) { id_Rows.Add(data.ID, new List <RowData>()); } id_Rows[data.ID].Add(data); } #endregion Dictionary <string, GradScoreRecordEditor> gradDict = new Dictionary <string, GradScoreRecordEditor>(); //交叉比對各學生資料 #region 交叉比對各學生資料 foreach (string id in id_Rows.Keys) { JHStudentRecord studentRec = _StudentCollection[id]; GradScoreRecord record = GradScore.Instance.Items[studentRec.ID]; GradScoreRecordEditor editor = null; if (record != null) { editor = record.GetEditor(); } else { editor = new GradScoreRecordEditor(Student.Instance.Items[studentRec.ID]); } if (!gradDict.ContainsKey(studentRec.ID)) { gradDict.Add(studentRec.ID, editor); } //要匯入的學期科目成績 Dictionary <string, RowData> importScoreDictionary = new Dictionary <string, RowData>(); #region 整理要匯入的資料 foreach (RowData row in id_Rows[id]) { int t; string domain = row["領域"]; if (!importScoreDictionary.ContainsKey(domain)) { importScoreDictionary.Add(domain, row); } } #endregion //開始處理ImportScore foreach (string domain in importScoreDictionary.Keys) { RowData data = importScoreDictionary[domain]; if (domain == "學習領域") { decimal d; if (decimal.TryParse(data["分數評量"], out d)) { editor.LearnDomainScore = d; } else { editor.LearnDomainScore = null; } } else if (domain == "課程學習") { decimal d; if (decimal.TryParse(data["分數評量"], out d)) { editor.CourseLearnScore = d; } else { editor.CourseLearnScore = null; } } else { if (!editor.Domains.ContainsKey(domain)) { editor.Domains.Add(domain, new GradDomainScore(domain)); } decimal d; if (decimal.TryParse(data["分數評量"], out d)) { editor.Domains[domain].Score = d; } else { editor.Domains[domain].Score = null; } } } } #endregion if (gradDict.Values.Count > 0) { #region 分批次兩路上傳 List <List <GradScoreRecordEditor> > updatePackages = new List <List <GradScoreRecordEditor> >(); List <List <GradScoreRecordEditor> > updatePackages2 = new List <List <GradScoreRecordEditor> >(); { List <GradScoreRecordEditor> package = null; int count = 0; foreach (GradScoreRecordEditor var in gradDict.Values) { if (count == 0) { package = new List <GradScoreRecordEditor>(30); count = 30; if ((updatePackages.Count & 1) == 0) { updatePackages.Add(package); } else { updatePackages2.Add(package); } } package.Add(var); count--; } } Thread threadUpdateSemesterSubjectScore = new Thread(new ParameterizedThreadStart(updateSemesterSubjectScore)); threadUpdateSemesterSubjectScore.IsBackground = true; threadUpdateSemesterSubjectScore.Start(updatePackages); Thread threadUpdateSemesterSubjectScore2 = new Thread(new ParameterizedThreadStart(updateSemesterSubjectScore)); threadUpdateSemesterSubjectScore2.IsBackground = true; threadUpdateSemesterSubjectScore2.Start(updatePackages2); threadUpdateSemesterSubjectScore.Join(); threadUpdateSemesterSubjectScore2.Join(); #endregion } FISCA.LogAgent.ApplicationLog.Log("成績系統.匯入匯出", "匯入畢業成績", "總共匯入" + gradDict.Values.Count + "筆畢業成績。"); #endregion }; wizard.ImportComplete += delegate { //EventHub.Instance.InvokScoreChanged(new List<string>(_StudentCollection.Keys).ToArray()); }; }