Esempio n. 1
0
        private void Worker_DoWork(object sender, DoWorkEventArgs e)
        {
            StudentAttendInfo info = new StudentAttendInfo();

            Worker.ReportProgress(0);
            //快取指定學期的課程清單,查詢用。
            Dictionary <string, JHCourseRecord> courseDict = new Dictionary <string, JHCourseRecord>();

            foreach (JHCourseRecord course in JHCourse.SelectBySchoolYearAndSemester(SchoolYear, Semester))
            {
                courseDict.Add(course.ID, course);
            }

            Worker.ReportProgress(30);
            foreach (JHSCAttendRecord sc in JHSCAttend.SelectByStudentIDs(Students.AsKeyList()))
            {
                //修習的課程必須是指定學期的課程
                if (courseDict.ContainsKey(sc.RefCourseID))
                {
                    info.Add(sc.RefStudentID, courseDict[sc.RefCourseID]);
                }
            }

            Worker.ReportProgress(80);
            info.RemoveRegular();
            Worker.ReportProgress(100);
            e.Result = info;
        }
        private Dictionary <string, JHCourseRecord> ReadCourse()
        {
            Reporter.Feedback("讀取課程資料...", 0);

            Dictionary <string, JHCourseRecord> courses = new Dictionary <string, JHCourseRecord>();

            JHCourse.RemoveAll();
            List <JHCourseRecord> lstCourses = JHCourse.SelectBySchoolYearAndSemester(SchoolYear, Semester);

            foreach (JHCourseRecord each in lstCourses)
            {
                //過慮掉不計算的科目。
                if (!IsValidSubject(each))
                {
                    continue;
                }

                if (!courses.ContainsKey(each.ID))
                {
                    courses.Add(each.ID, each);
                }
            }

            return(courses);
        }
Esempio n. 3
0
        public static Dictionary <string, JHCourseRecord> GetCourseDict(int SchoolYear, int Semester)
        {
            Dictionary <string, JHCourseRecord> dictCourses = new Dictionary <string, JHCourseRecord>();

            foreach (JHCourseRecord course in JHCourse.SelectBySchoolYearAndSemester(SchoolYear, Semester))
            {
                dictCourses.Add(course.ID, course);
            }
            return(dictCourses);
        }
Esempio n. 4
0
        /// <summary>
        /// (Network Access)將目前學期的資料填入到 Courses、SCAttends 變數中。
        /// </summary>
        private void FillCurrentSemesterData()
        {
            Courses   = new Dictionary <string, JHCourseRecord>();
            SCAttends = new Dictionary <string, JHSCAttendRecord>();

            if (Students.Count <= 0)
            {
                return;                      //沒有學生當然就沒有任何資料了。
            }
            //Network Access
            int t1 = Environment.TickCount;
            List <JHCourseRecord> listCourses = JHCourse.SelectBySchoolYearAndSemester(Sems.SelectedSchoolYear, Sems.SelectedSemester);

            Console.WriteLine(string.Format("JHCourse.SelectBySchoolYearAndSemester Time:{0}", Environment.TickCount - t1));

            if (listCourses.Count <= 0)
            {
                return;                         //沒有任何課程也不會有成績資料了。
            }
            #region 建立 Course Dictionary
            foreach (JHCourseRecord each in listCourses)
            {
                Courses.Add(each.ID, each);
            }
            #endregion

            //Network Access
            t1 = Environment.TickCount;
            List <JHSCAttendRecord> listSCAttends = JHSCAttend.SelectByStudentIDAndCourseID(Students.ToKeys(), Courses.Values.ToKeys());

            Console.WriteLine(string.Format("JHSCAttend.SelectByStudentIDAndCourseID Time:{0}", Environment.TickCount - t1));

            t1 = Environment.TickCount;
            #region 建立 SCAttend Dictionary
            int selSchoolYear = Sems.SelectedSchoolYear;
            int selSemester   = Sems.SelectedSemester;
            foreach (JHSCAttendRecord each in listSCAttends)
            {
                JHCourseRecord course = Courses[each.RefCourseID];
                if (course.SchoolYear != selSchoolYear || course.Semester != selSemester)
                {
                    continue;
                }

                SCAttends.Add(each.ID, each);
            }
            #endregion
            Console.WriteLine(string.Format("建立 SCAttend Dictionary Time:{0}", Environment.TickCount - t1));
        }
Esempio n. 5
0
        /// <summary>
        /// (Network Access)將目前學期的資料填入到 Courses、SCAttends 變數中。
        /// </summary>
        private void FillCurrentSemesterData()
        {
            Courses   = new Dictionary <string, JHCourseRecord>();
            SCAttends = new Dictionary <string, JHSCAttendRecord>();

            if (Students.Count <= 0)
            {
                return;                      //沒有學生當然就沒有任何資料了。
            }
            //Network Access
            List <JHCourseRecord> listCourses = JHCourse.SelectBySchoolYearAndSemester(Sems.SelectedSchoolYear, Sems.SelectedSemester);

            if (listCourses.Count <= 0)
            {
                return;                         //沒有任何課程也不會有成績資料了。
            }
            #region 建立 Course Dictionary
            foreach (JHCourseRecord each in listCourses)
            {
                Courses.Add(each.ID, each);
            }
            #endregion

            //Network Access
            List <JHSCAttendRecord> listSCAttends = JHSCAttend.SelectByStudentIDAndCourseID(Students.ToKeys(), Courses.Values.ToKeys());

            #region 建立 SCAttend Dictionary
            foreach (JHSCAttendRecord each in listSCAttends)
            {
                JHCourseRecord course = Courses[each.RefCourseID];
                if (course.SchoolYear != Sems.SelectedSchoolYear || course.Semester != Sems.SelectedSemester)
                {
                    continue;
                }

                SCAttends.Add(each.ID, each);
            }
            #endregion
        }
Esempio n. 6
0
        public ImportStartupForm()
        {
            InitializeComponent();
            InitializeSemesters();

            _effortMapper = new EffortMapper();

            // 載入預設儲存值
            LoadConfigData();

            _worker = new BackgroundWorker();
            _worker.WorkerReportsProgress = true;
            _worker.ProgressChanged      += delegate(object sender, ProgressChangedEventArgs e)
            {
                lblMessage.Text = "" + e.UserState;
            };
            _worker.DoWork += delegate(object sender, DoWorkEventArgs e)
            {
                #region Worker DoWork
                _worker.ReportProgress(0, "檢查讀卡文字格式…");

                #region 檢查文字檔
                ValidateTextFiles  vtf      = new ValidateTextFiles(intStudentNumberLenght.Value);
                ValidateTextResult vtResult = vtf.CheckFormat(_files);
                if (vtResult.Error)
                {
                    e.Result = vtResult;
                    return;
                }
                #endregion

                //文字檔轉 RawData
                RawDataCollection rdCollection = new RawDataCollection();
                rdCollection.ConvertFromFiles(_files);

                //RawData 轉 DataRecord
                DataRecordCollection drCollection = new DataRecordCollection();
                drCollection.ConvertFromRawData(rdCollection);

                _rawDataValidator    = new DataValidator <RawData>();
                _dataRecordValidator = new DataValidator <DataRecord>();

                #region 取得驗證需要的資料
                JHCourse.RemoveAll();
                _worker.ReportProgress(0, "取得學生資料…");
                List <JHStudentRecord> studentList = GetInSchoolStudents();

                List <string> s_ids = new List <string>();
                Dictionary <string, List <string> > studentNumberToStudentIDs = new Dictionary <string, List <string> >();
                foreach (JHStudentRecord student in studentList)
                {
                    string sn = SCValidatorCreator.GetStudentNumberFormat(student.StudentNumber);
                    if (!studentNumberToStudentIDs.ContainsKey(sn))
                    {
                        studentNumberToStudentIDs.Add(sn, new List <string>());
                    }
                    studentNumberToStudentIDs[sn].Add(student.ID);
                }
                foreach (var dr in drCollection)
                {
                    if (studentNumberToStudentIDs.ContainsKey(dr.StudentNumber))
                    {
                        s_ids.AddRange(studentNumberToStudentIDs[dr.StudentNumber]);
                    }
                }

                studentList.Clear();

                _worker.ReportProgress(0, "取得課程資料…");
                List <JHCourseRecord>    courseList = JHCourse.SelectBySchoolYearAndSemester(SchoolYear, Semester);
                List <JHAEIncludeRecord> aeList     = JHAEInclude.SelectAll();

                //List<JHSCAttendRecord> scaList = JHSCAttend.SelectAll();
                var c_ids = from course in courseList select course.ID;
                _worker.ReportProgress(0, "取得修課資料…");
                //List<JHSCAttendRecord> scaList2 = JHSCAttend.SelectByStudentIDAndCourseID(s_ids, c_ids.ToList<string>());
                List <JHSCAttendRecord> scaList = new List <JHSCAttendRecord>();
                FunctionSpliter <string, JHSCAttendRecord> spliter = new FunctionSpliter <string, JHSCAttendRecord>(300, 3);
                spliter.Function = delegate(List <string> part)
                {
                    return(JHSCAttend.Select(part, c_ids.ToList <string>(), null, SchoolYear.ToString(), Semester.ToString()));
                };
                scaList = spliter.Execute(s_ids);

                _worker.ReportProgress(0, "取得試別資料…");
                List <JHExamRecord> examList = JHExam.SelectAll();
                #endregion

                #region 註冊驗證
                _worker.ReportProgress(0, "載入驗證規則…");
                _rawDataValidator.Register(new SubjectCodeValidator());
                _rawDataValidator.Register(new ClassCodeValidator());
                _rawDataValidator.Register(new ExamCodeValidator());

                SCValidatorCreator scCreator = new SCValidatorCreator(JHStudent.SelectByIDs(s_ids), courseList, scaList);
                _dataRecordValidator.Register(scCreator.CreateStudentValidator());
                _dataRecordValidator.Register(new ExamValidator(examList));
                _dataRecordValidator.Register(scCreator.CreateSCAttendValidator());
                _dataRecordValidator.Register(new CourseExamValidator(scCreator.StudentCourseInfo, aeList, examList));
                #endregion

                #region 進行驗證
                _worker.ReportProgress(0, "進行驗證中…");
                List <string> msgList = new List <string>();

                foreach (RawData rawData in rdCollection)
                {
                    List <string> msgs = _rawDataValidator.Validate(rawData);
                    msgList.AddRange(msgs);
                }
                if (msgList.Count > 0)
                {
                    e.Result = msgList;
                    return;
                }

                foreach (DataRecord dataRecord in drCollection)
                {
                    List <string> msgs = _dataRecordValidator.Validate(dataRecord);
                    msgList.AddRange(msgs);
                }
                if (msgList.Count > 0)
                {
                    e.Result = msgList;
                    return;
                }
                #endregion

                #region 取得學生的評量成績
                _deleteScoreList.Clear();
                _addScoreList.Clear();

                //var student_ids = from student in scCreator.StudentNumberDictionary.Values select student.ID;
                //List<string> course_ids = scCreator.AttendCourseIDs;

                var scaIDs = from sca in scaList select sca.ID;

                Dictionary <string, JHSCETakeRecord>      sceList    = new Dictionary <string, JHSCETakeRecord>();
                FunctionSpliter <string, JHSCETakeRecord> spliterSCE = new FunctionSpliter <string, JHSCETakeRecord>(300, 3);
                spliterSCE.Function = delegate(List <string> part)
                {
                    return(JHSCETake.Select(null, null, null, null, part));
                };
                foreach (JHSCETakeRecord sce in spliterSCE.Execute(scaIDs.ToList()))
                {
                    string key = GetCombineKey(sce.RefStudentID, sce.RefCourseID, sce.RefExamID);
                    if (!sceList.ContainsKey(key))
                    {
                        sceList.Add(key, sce);
                    }
                }

                Dictionary <string, JHExamRecord>     examTable = new Dictionary <string, JHExamRecord>();
                Dictionary <string, JHSCAttendRecord> scaTable  = new Dictionary <string, JHSCAttendRecord>();

                foreach (JHExamRecord exam in examList)
                {
                    if (!examTable.ContainsKey(exam.Name))
                    {
                        examTable.Add(exam.Name, exam);
                    }
                }

                foreach (JHSCAttendRecord sca in scaList)
                {
                    string key = GetCombineKey(sca.RefStudentID, sca.RefCourseID);
                    if (!scaTable.ContainsKey(key))
                    {
                        scaTable.Add(key, sca);
                    }
                }

                foreach (DataRecord dr in drCollection)
                {
                    JHStudentRecord       student = student = scCreator.StudentNumberDictionary[dr.StudentNumber];
                    JHExamRecord          exam    = examTable[dr.Exam];
                    List <JHCourseRecord> courses = new List <JHCourseRecord>();
                    foreach (JHCourseRecord course in scCreator.StudentCourseInfo.GetCourses(dr.StudentNumber))
                    {
                        if (dr.Subjects.Contains(course.Subject))
                        {
                            courses.Add(course);
                        }
                    }

                    foreach (JHCourseRecord course in courses)
                    {
                        string key = GetCombineKey(student.ID, course.ID, exam.ID);

                        if (sceList.ContainsKey(key))
                        {
                            _deleteScoreList.Add(sceList[key]);
                        }

                        JHSCETakeRecord    jh     = new JHSCETakeRecord();
                        KH.JHSCETakeRecord sceNew = new KH.JHSCETakeRecord(jh);
                        sceNew.RefCourseID   = course.ID;
                        sceNew.RefExamID     = exam.ID;
                        sceNew.RefSCAttendID = scaTable[GetCombineKey(student.ID, course.ID)].ID;
                        sceNew.RefStudentID  = student.ID;
                        sceNew.Score         = dr.Score;
                        sceNew.Effort        = _effortMapper.GetCodeByScore(dr.Score);
                        _addScoreList.Add(sceNew.AsJHSCETakeRecord());
                    }
                }
                #endregion

                e.Result = null;
                #endregion
            };
            _worker.RunWorkerCompleted += delegate(object sender, RunWorkerCompletedEventArgs e)
            {
                #region Worker Completed
                if (e.Error == null && e.Result == null)
                {
                    if (!_upload.IsBusy)
                    {
                        //如果學生身上已有成績,則提醒使用者
                        if (_deleteScoreList.Count > 0)
                        {
                            _warn.RunWorkerAsync();
                        }
                        else
                        {
                            lblMessage.Text = "成績上傳中…";
                            FISCA.Presentation.MotherForm.SetStatusBarMessage("成績上傳中…", 0);
                            counter = 0;
                            _upload.RunWorkerAsync();
                        }
                    }
                }
                else
                {
                    ControlEnable = true;

                    if (e.Error != null)
                    {
                        MsgBox.Show("匯入失敗。" + e.Error.Message);
                        SmartSchool.ErrorReporting.ReportingService.ReportException(e.Error);
                    }
                    else if (e.Result != null && e.Result is ValidateTextResult)
                    {
                        ValidateTextResult    result = e.Result as ValidateTextResult;
                        ValidationErrorViewer viewer = new ValidationErrorViewer();
                        viewer.SetTextFileError(result.LineIndexes, result.ErrorFormatLineIndexes, result.DuplicateLineIndexes);
                        viewer.ShowDialog();
                    }
                    else if (e.Result != null && e.Result is List <string> )
                    {
                        ValidationErrorViewer viewer = new ValidationErrorViewer();
                        viewer.SetErrorLines(e.Result as List <string>);
                        viewer.ShowDialog();
                    }
                }
                #endregion
            };

            _upload = new BackgroundWorker();
            _upload.WorkerReportsProgress = true;
            _upload.ProgressChanged      += new ProgressChangedEventHandler(_upload_ProgressChanged);
            //_upload.ProgressChanged += delegate(object sender, ProgressChangedEventArgs e)
            //{
            //    counter += double.Parse("" + e.ProgressPercentage);
            //    FISCA.Presentation.MotherForm.SetStatusBarMessage("成績上傳中…", (int)(counter * 100f / (double)_addScoreList.Count));
            //};
            _upload.DoWork += new DoWorkEventHandler(_upload_DoWork);

            //_upload.DoWork += delegate
            //{


            //#region Upload DoWork
            //Framework.MultiThreadWorker<JHSCETakeRecord> multi = new Framework.MultiThreadWorker<JHSCETakeRecord>();
            //multi.MaxThreads = 3;
            //multi.PackageSize = 500;
            //multi.PackageWorker += delegate(object sender, Framework.PackageWorkEventArgs<JHSCETakeRecord> e)
            //{
            //    JHSCETake.Delete(e.List);
            //};
            //multi.Run(_deleteScoreList);

            //Framework.MultiThreadWorker<JHSCETakeRecord> multi2 = new Framework.MultiThreadWorker<JHSCETakeRecord>();
            //multi2.MaxThreads = 3;
            //multi2.PackageSize = 500;
            //multi2.PackageWorker += delegate(object sender, Framework.PackageWorkEventArgs<JHSCETakeRecord> e)
            //{
            //    JHSCETake.Insert(e.List);
            //    lock (_upload)
            //    {
            //        _upload.ReportProgress(e.List.Count);
            //    }
            //};
            //multi2.Run(_addScoreList);
            //#endregion
            //};


            _upload.RunWorkerCompleted += new RunWorkerCompletedEventHandler(_upload_RunWorkerCompleted);

            _warn = new BackgroundWorker();
            _warn.WorkerReportsProgress = true;
            _warn.DoWork += delegate(object sender, DoWorkEventArgs e)
            {
                _warn.ReportProgress(0, "產生警告訊息...");

                Dictionary <string, string> examDict = new Dictionary <string, string>();
                foreach (JHExamRecord exam in JHExam.SelectAll())
                {
                    if (!examDict.ContainsKey(exam.ID))
                    {
                        examDict.Add(exam.ID, exam.Name);
                    }
                }

                WarningForm form  = new WarningForm();
                int         count = 0;
                foreach (JHSCETakeRecord sce in _deleteScoreList)
                {
                    // 當成績資料是空值跳過
                    if (sce.Score.HasValue == false && sce.Effort.HasValue == false && string.IsNullOrEmpty(sce.Text))
                    {
                        continue;
                    }

                    count++;

                    JHStudentRecord student = JHStudent.SelectByID(sce.RefStudentID);
                    JHCourseRecord  course  = JHCourse.SelectByID(sce.RefCourseID);
                    string          exam    = (examDict.ContainsKey(sce.RefExamID) ? examDict[sce.RefExamID] : "<未知的試別>");

                    string s = "";
                    if (student.Class != null)
                    {
                        s += student.Class.Name;
                    }
                    if (!string.IsNullOrEmpty("" + student.SeatNo))
                    {
                        s += " " + student.SeatNo + "號";
                    }
                    if (!string.IsNullOrEmpty(student.StudentNumber))
                    {
                        s += " (" + student.StudentNumber + ")";
                    }
                    s += " " + student.Name;

                    form.Add(student.ID, s, string.Format("學生在「{0}」課程「{1}」中已有成績。", course.Name, exam));
                    _warn.ReportProgress((int)(count * 100 / _deleteScoreList.Count), "產生警告訊息...");
                }

                e.Result = form;
            };
            _warn.RunWorkerCompleted += delegate(object sender, RunWorkerCompletedEventArgs e)
            {
                WarningForm form = e.Result as WarningForm;

                if (form.ShowDialog() == DialogResult.OK)
                {
                    lblMessage.Text = "成績上傳中…";
                    FISCA.Presentation.MotherForm.SetStatusBarMessage("成績上傳中…", 0);
                    counter = 0;
                    _upload.RunWorkerAsync();
                }
                else
                {
                    this.DialogResult = DialogResult.Cancel;
                }
            };
            _warn.ProgressChanged += delegate(object sender, ProgressChangedEventArgs e)
            {
                FISCA.Presentation.MotherForm.SetStatusBarMessage("" + e.UserState, e.ProgressPercentage);
            };

            _files           = new List <FileInfo>();
            _addScoreList    = new List <JHSCETakeRecord>();
            _deleteScoreList = new List <JHSCETakeRecord>();
        }
Esempio n. 7
0
        public MainForm()
        {
            //GetSubjectList();
            InitializeComponent();
            InitializeSemester();
            this.Text        = Global.ReportName;
            this.MinimumSize = this.Size;
            this.MaximumSize = this.Size;

            _config = new Config(Global.ReportName);

            _data       = new List <ClassExamScoreData>();
            _courseDict = new Dictionary <string, JHCourseRecord>();
            _exams      = new List <JHExamRecord>();
            //_ecMapping = new Dictionary<string, List<string>>();
            _courseList = new List <string>();

            cbExam.DisplayMember = "Name";
            cbSource.Items.Add("定期");
            cbSource.Items.Add("定期加平時");
            cbSource.SelectedIndex = 0;

            cbExam.Items.Add("");
            _exams = JHExam.SelectAll();
            foreach (var exam in _exams)
            {
                cbExam.Items.Add(exam);
            }
            cbExam.SelectedIndex = 0;

            _worker         = new BackgroundWorker();
            _worker.DoWork += delegate(object sender, DoWorkEventArgs e)
            {
                JHExamRecord exam = e.Argument as JHExamRecord;
                #region 取得試別
                //_ecMapping.Clear();
                //_exams = JHExam.SelectAll();
                //List<string> examIDs = new List<string>();
                //foreach (JHExamRecord exam in _exams)
                //{
                //    examIDs.Add(exam.ID);
                //_ecMapping.Add(exam.ID, new List<string>());
                //}
                #endregion

                #region 取得課程
                _courseDict.Clear();
                List <JHCourseRecord> courseList = JHCourse.SelectBySchoolYearAndSemester(_runningSchoolYear, _runningSemester);
                List <string>         courseIDs  = new List <string>();
                foreach (JHCourseRecord course in courseList)
                {
                    courseIDs.Add(course.ID);
                    _courseDict.Add(course.ID, course);
                }
                #endregion

                #region 取得評量成績
                //StudentID -> ClassExamScoreData
                Dictionary <string, ClassExamScoreData> scMapping = new Dictionary <string, ClassExamScoreData>();
                List <string> ids = new List <string>();
                _classes = JHClass.SelectByIDs(K12.Presentation.NLDPanels.Class.SelectedSource);

                // 排序
                if (_classes.Count > 1)
                {
                    _classes = DAL.DALTransfer.ClassRecordSortByDisplayOrder(_classes);
                }

                // TODO: 這邊要排序
                //List<K12.Data.ClassRecord> c = new List<K12.Data.ClassRecord>(_classes);
                //c.Sort();
                //_classes = new List<JHClassRecord>(c);
                //((List<K12.Data.ClassRecord>)_classes).Sort();

                _data.Clear();
                foreach (JHClassRecord cla in _classes)
                {
                    ClassExamScoreData classData = new ClassExamScoreData(cla);
                    foreach (JHStudentRecord stu in classData.Students)
                    {
                        scMapping.Add(stu.ID, classData);
                    }
                    _data.Add(classData);
                }

                //foreach (string examID in examIDs)
                //{

                _courseList.Clear();
                if (courseIDs.Count > 0)
                {
                    // TODO: JHSCETake 需要提供 SelectBy 課程IDs and 試別IDs 嗎?
                    foreach (JHSCETakeRecord sce in JHSCETake.SelectByCourseAndExam(courseIDs, exam.ID))
                    {
                        // TODO: 下面前兩個判斷應該可以拿掉
                        //if (!examIDs.Contains(sce.RefExamID)) continue; //試別無效
                        //if (!courseIDs.Contains(sce.RefCourseID)) continue; //課程無效
                        if (!scMapping.ContainsKey(sce.RefStudentID))
                        {
                            continue;                                           //學生編號無效
                        }
                        if (string.IsNullOrEmpty(_courseDict[sce.RefCourseID].RefAssessmentSetupID))
                        {
                            continue;                                                                          //課程無評量設定
                        }
                        if (!_courseList.Contains(sce.RefCourseID))
                        {
                            _courseList.Add(sce.RefCourseID);
                        }
                        //if (!_ecMapping[sce.RefExamID].Contains(sce.RefCourseID))
                        //    _ecMapping[sce.RefExamID].Add(sce.RefCourseID);

                        ClassExamScoreData classData = scMapping[sce.RefStudentID];
                        classData.AddScore(sce);
                    }
                }
                //}
                #endregion
            };
            _worker.RunWorkerCompleted += delegate
            {
                string running = _runningSchoolYear + "_" + _runningSemester;
                string current = (int)cboSchoolYear.SelectedItem + "_" + (int)cboSemester.SelectedItem;
                if (running != current)
                {
                    if (!_worker.IsBusy)
                    {
                        _runningSchoolYear = (int)cboSchoolYear.SelectedItem;
                        _runningSemester   = (int)cboSemester.SelectedItem;

                        RunWorker();
                    }
                }
                else
                {
                    FillData();
                    ControlEnabled = true;
                }
            };

            RunWorker();
        }
Esempio n. 8
0
        private void Worker_DoWork(object sender, DoWorkEventArgs e)
        {
            #region DoWork
            object[] objs         = (object[])e.Argument;
            int      schoolyear   = Framework.Int.Parse(objs[0] as string);
            int      semester     = Framework.Int.Parse(objs[1] as string);
            string   domain       = objs[2] as string;
            string   subject      = objs[3] as string;
            string   periodcredit = objs[4] as string;
            string   required     = objs[5] as string;

            PeriodCredit pc = new PeriodCredit();
            pc.Parse(periodcredit);

            double total   = _classes.Count;
            double counter = 0;
            if (total == 0)
            {
                total = 1;
            }
            else
            {
                total *= 2;
            }
            _worker.ReportProgress(1, "正在檢查班級課程…");

            _classes.Sort(SortClassesByClassName);

            #region 檢查重複開課
            List <string> errors = new List <string>();

            List <string> classIDs = new List <string>();
            foreach (JHClassRecord cla in _classes)
            {
                classIDs.Add(cla.ID);
            }

            Dictionary <string, List <JHCourseRecord> > classExistCourses = new Dictionary <string, List <JHCourseRecord> >();
            List <JHCourseRecord> orphanCourse = new List <JHCourseRecord>();

            foreach (JHCourseRecord course in JHCourse.SelectBySchoolYearAndSemester(schoolyear, semester))
            {
                if (!classIDs.Contains(course.RefClassID))
                {
                    orphanCourse.Add(course);
                    continue;
                }

                if (!classExistCourses.ContainsKey(course.RefClassID))
                {
                    classExistCourses.Add(course.RefClassID, new List <JHCourseRecord>());
                }
                classExistCourses[course.RefClassID].Add(course);
            }

            foreach (JHClassRecord cla in _classes)
            {
                if (!classExistCourses.ContainsKey(cla.ID))
                {
                    continue;
                }

                foreach (JHCourseRecord course in classExistCourses[cla.ID])
                {
                    if (course.Subject == subject)
                    {
                        errors.Add(cla.Name + ":已有相同科目(" + subject + ")的課程。");
                    }
                }

                foreach (JHCourseRecord course in orphanCourse)
                {
                    if (course.Name == cla.Name + " " + subject)
                    {
                        errors.Add(cla.Name + ":已有相同課程名稱(" + course.Name + ")的課程。");
                    }
                }
            }

            if (errors.Count > 0)
            {
                e.Result = errors;
                return;
            }
            #endregion

            #region 開課
            Dictionary <string, string> classNewCourse = new Dictionary <string, string>();

            DSXmlHelper req = new DSXmlHelper("UpdateRequest");

            foreach (JHClassRecord cla in _classes)
            {
                JHCourseRecord newCourse = new JHCourseRecord();
                newCourse.CalculationFlag = "1";
                newCourse.Period          = pc.Period;
                newCourse.Credit          = pc.Credit;
                newCourse.Domain          = domain;
                newCourse.Subject         = subject;
                newCourse.Name            = cla.Name + " " + subject;
                newCourse.SchoolYear      = schoolyear;
                newCourse.Semester        = semester;
                newCourse.RefClassID      = cla.ID;

                //建立Course時也將CourseExtendRecord建立
                string             course_id = JHCourse.Insert(newCourse);
                CourseExtendRecord courseEx  = new CourseExtendRecord();
                courseEx.Ref_course_id = int.Parse(course_id);
                courseEx.GradeYear     = cla.GradeYear == null ? -1 : int.Parse(cla.GradeYear + "");
                courseEx.Save();

                classNewCourse.Add(cla.ID, course_id);
                req.AddElement("Course");
                req.AddElement("Course", "Field");
                req.AddElement("Course/Field", "IsRequired", required.Replace("修", ""));
                req.AddElement("Course", "Condition");
                req.AddElement("Course/Condition", "ID", classNewCourse[cla.ID]);

                counter++;
                _worker.ReportProgress((int)(counter * 100d / total), "正在進行開課…");
            }

            //更新必選修
            if (classNewCourse.Count > 0)
            {
                JHSchool.Feature.Legacy.EditCourse.UpdateCourse(new DSRequest(req));
            }

            #endregion

            #region 加入學生修課

            foreach (JHClassRecord cla in _classes)
            {
                List <JHSCAttendRecord> scattends = new List <JHSchool.Data.JHSCAttendRecord>();
                foreach (JHStudentRecord stu in cla.Students)
                {
                    JHSCAttendRecord scattend = new JHSchool.Data.JHSCAttendRecord();
                    scattend.RefCourseID  = classNewCourse[cla.ID];
                    scattend.RefStudentID = stu.ID;

                    scattends.Add(scattend);
                }

                if (scattends.Count > 0)
                {
                    JHSCAttend.Insert(scattends);
                }

                counter++;
                _worker.ReportProgress((int)(counter * 100d / total), "正在加入學生修課…");
            }
            #endregion

            // 加這主要是重新整理
            Course.Instance.SyncDataBackground(classNewCourse.Values);

            e.Result = string.Empty;

            #endregion
        }