private void btnAdd_Click(object sender, EventArgs e)
        {
            try
            {
                DataTable dataTable = queryHelper.Select(string.Format("select class_name, student.name as student_name, student.id as id, student_number from student left join class on class.id=student.ref_class_id where student.status in (1, 4) and student_number ilike ('{0}')", this.txtStudentNumber.Text.Trim()));

                if (dataTable == null || dataTable.Rows.Count == 0)
                {
                    MessageBox.Show("查無此人。");
                    return;
                }
                else
                {
                    List<UDT.CSAttend> CSAttends = Access.Select<UDT.CSAttend>(string.Format("ref_student_id={0} and ref_course_id={1}", dataTable.Rows[0]["id"] + "", CourseID));

                    if (CSAttends.Count > 0)
                    {
                        MessageBox.Show(string.Format("已加入學生「班級:{0},學號:{1},姓名:{2}」。", dataTable.Rows[0]["class_name"] + "", dataTable.Rows[0]["student_number"] + "", dataTable.Rows[0]["student_name"] + ""));
                        return;
                    }
                    UDT.CSAttend CSAttend = new UDT.CSAttend();
                    UDT.CSAttendLog CSAttendLog = new UDT.CSAttendLog();

                    CSAttend.CourseID = int.Parse(CourseID);
                    CSAttend.StudentID = int.Parse(dataTable.Rows[0]["id"] + "");
                    CSAttend.SchoolYear = this.SchoolYear;
                    CSAttend.Semester = this.Semester;
                    CSAttend.Item = this.item;
                    CSAttend.Manually = true;
                    CSAttend.IsManual = true;

                    CSAttendLog.CourseID = int.Parse(CourseID);
                    CSAttendLog.StudentID = int.Parse(dataTable.Rows[0]["id"] + "");
                    CSAttendLog.SchoolYear = this.SchoolYear;
                    CSAttendLog.Semester = this.Semester;
                    CSAttendLog.Action = "insert_manually";
                    CSAttendLog.ActionBy = "staff";
                    CSAttendLog.Item = this.item;

                    CSAttend.Save();
                    CSAttendLog.Save();
                    Event.DeliverCSAttendEventArgs ee = new Event.DeliverCSAttendEventArgs(new List<UDT.CSAttend> { CSAttend });
                    Event.DeliverActiveRecord.RaiseSendingEvent(this, ee);
                    MessageBox.Show(string.Format("已加入學生「班級:{0},學號:{1},姓名:{2}」", dataTable.Rows[0]["class_name"] + "", dataTable.Rows[0]["student_number"] + "", dataTable.Rows[0]["student_name"] + ""));
                }
            }
            catch(Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
        private void btnRecover_Click(object sender, EventArgs e)
        {
            if (this.lstCourse.SelectedIndex == -1)
                return;

            this.DisableButtons();

            string CourseID = this.groupPanel1.Tag + "";
            decimal school_year = this.nudSchoolYear.Value;
            string semester = (this.cboSemester.SelectedItem as DataItems.SemesterItem).Value;

            List<UDT.CSAttend> CSAttends = new List<UDT.CSAttend>();
            List<UDT.CSAttendLog> CSAttendLogs = new List<UDT.CSAttendLog>();
            if (this.dgvData.SelectedRows.Count == 0)
                return;

            this.dgvData.SelectedRows.Cast<DataGridViewRow>().ToList().ForEach((x) =>
            {
                if (x.DefaultCellStyle.BackColor == System.Drawing.Color.Pink)
                {
                    UDT.CSAttend CSAttend = new UDT.CSAttend();
                    UDT.CSAttendLog CSAttendLog = new UDT.CSAttendLog();

                    CSAttend.StudentID = int.Parse(x.Cells["lblStudentID"].Value + "");
                    CSAttend.CourseID = int.Parse(CourseID);
                    CSAttend.SchoolYear = int.Parse(school_year.ToString());
                    CSAttend.Semester = int.Parse(semester);
                    CSAttend.Item = this.item;

                    CSAttends.Add(CSAttend);

                    CSAttendLog.StudentID = int.Parse(x.Cells["lblStudentID"].Value + "");
                    CSAttendLog.CourseID = int.Parse(CourseID);
                    CSAttendLog.SchoolYear = int.Parse(school_year.ToString());
                    CSAttendLog.Semester = int.Parse(semester);
                    CSAttendLog.Item = this.item;
                    CSAttendLog.Action = "insert";
                    CSAttendLog.ActionBy = "staff";

                    CSAttendLogs.Add(CSAttendLog);

                    x.DefaultCellStyle.BackColor = System.Drawing.SystemColors.Window;
                }
            });
            CSAttends.SaveAll();
            CSAttendLogs.SaveAll();

            this.InitCSAttend(CourseID);
            if (this.chkShowLog.Checked)
                this.AppendCSAttendLog(CourseID);

            this.EnableButtons();
        }
        private void btnManualFilter_Click(object sender, EventArgs e)
        {
            this.DisableButtons();

            List<UDT.CSAttend> CSAttend_Deleteds = new List<UDT.CSAttend>();
            List<UDT.CSAttendLog> CSAttendLogs = new List<UDT.CSAttendLog>();
            string CourseID = this.groupPanel1.Tag + "";
            List<UDT.CSAttend> CSAttends = Access.Select<UDT.CSAttend>(string.Format("ref_course_id={0}", CourseID));
            Dictionary<int, UDT.CSAttend> dicCSAttends = new Dictionary<int, UDT.CSAttend>();
            if (CSAttends.Count > 0)
            {
                CSAttends.ForEach((x) =>
                {
                    if (!dicCSAttends.ContainsKey(x.StudentID))
                        dicCSAttends.Add(x.StudentID, x);
                });
            }

            decimal school_year = this.nudSchoolYear.Value;
            string semester = (this.cboSemester.SelectedItem as DataItems.SemesterItem).Value;
            string error_message = string.Empty;
            List<DataGridViewRow> cantdeletes = new List<DataGridViewRow>();
            foreach(DataGridViewRow row in this.dgvData.SelectedRows)
            {
                int StudentID = int.Parse(row.Cells["lblStudentID"].Value + "");

                bool locked_evaluation = false;
                bool locked_condition = false;
                bool manual = false;
                bool period1 = false;
                if (bool.TryParse(row.Cells["colManual"].Value + "", out manual) && manual)
                    cantdeletes.Add(row);
                if (bool.TryParse(row.Cells["colPeriod1"].Value + "", out period1) && period1)
                    cantdeletes.Add(row);
                if (bool.TryParse(row.Cells["chkEvaluation"].Value + "", out locked_evaluation) && locked_evaluation)
                    cantdeletes.Add(row);
                if (bool.TryParse(row.Cells["chkLock"].Value + "", out locked_condition) && locked_condition)
                    cantdeletes.Add(row);

                cantdeletes = cantdeletes.Distinct().ToList();

                if (dicCSAttends.ContainsKey(StudentID))
                {
                    UDT.CSAttend CSAttend = dicCSAttends[StudentID];
                    UDT.CSAttendLog CSAttendLog = new UDT.CSAttendLog();
                    CSAttend.Deleted = true;

                    CSAttendLog.StudentID = StudentID;
                    CSAttendLog.CourseID = int.Parse(CourseID);
                    CSAttendLog.SchoolYear = int.Parse(school_year.ToString());
                    CSAttendLog.Semester = int.Parse(semester);
                    CSAttendLog.Item = this.item;
                    CSAttendLog.Action = "delete";
                    CSAttendLog.ActionBy = "staff";

                    CSAttendLogs.Add(CSAttendLog);
                    CSAttend_Deleteds.Add(CSAttend);
                }
            }
            if (cantdeletes.Count > 0)
            {
                error_message = "下列學生已勾選「優先」,確定手動篩汰學生?\n\n";
                foreach (DataGridViewRow row in cantdeletes)
                {
                    error_message += string.Format("學號「{0}」,姓名「{1}」。\n", row.Cells[3].Value + "", row.Cells[4].Value + "");
                }
                if (MessageBox.Show(error_message, "提示", MessageBoxButtons.OKCancel) == System.Windows.Forms.DialogResult.Cancel)
                {
                    this.EnableButtons();
                    return;
                }
            }
            else
            {
                if (MessageBox.Show("確定手動篩汰學生?", "提示", MessageBoxButtons.OKCancel) == System.Windows.Forms.DialogResult.Cancel)
                {
                    this.EnableButtons();
                    return;
                }
            }
            CSAttend_Deleteds.SaveAll();
            CSAttendLogs.SaveAll();

            this.InitCSAttend(CourseID);
            if (this.chkShowLog.Checked)
                this.AppendCSAttendLog(CourseID);

            this.EnableButtons();
        }
        private void btnFilter_Click(object sender, EventArgs e)
        {
            uint capacity = 0;

            if (uint.TryParse(txtCapacity.Text.Trim(), out capacity))
            {
                if (capacity == 0)
                {
                    MessageBox.Show("人數上限為 0,無法自動篩汰學生。");
                    return;
                }
                else
                {
                    uint locked_no = 0;
                    uint total_no = 0;
                    foreach (DataGridViewRow row in this.dgvData.Rows)
                    {
                        if (row.DefaultCellStyle.BackColor != System.Drawing.Color.Pink)
                        {
                            total_no += 1;

                            bool manual = false;
                            bool period1 = false;
                            if ((bool.TryParse(row.Cells["colManual"].Value + "", out manual) && manual) || (bool.TryParse(row.Cells["colPeriod1"].Value + "", out period1) && period1))
                                locked_no += 1;
                        }
                    }
                    if (capacity >= total_no)
                    {
                        MessageBox.Show("選課人數未超過人數上限,不需篩汰學生。");
                        return;
                    }
                    else
                    {
                        if (locked_no > capacity)
                        {
                            MessageBox.Show("「手動優先人數」+「第一階段選上人數」大於人數上限,無法自動篩汰學生。");
                            return;
                        }
                        else
                        {
                            this.DisableButtons();

                            uint delete_no = total_no - capacity;

                            List<DataGridViewRow> locked_rows_evaluation = new List<DataGridViewRow>();
                            List<DataGridViewRow> locked_rows_condition = new List<DataGridViewRow>();
                            List<DataGridViewRow> locked_rows_condition_evaluation = new List<DataGridViewRow>();
                            List<DataGridViewRow> deleted_rows = new List<DataGridViewRow>();
                            List<DataGridViewRow> locked_rows = new List<DataGridViewRow>();
                            List<DataGridViewRow> no_locked_rows = new List<DataGridViewRow>();
                            foreach (DataGridViewRow row in this.dgvData.Rows)
                            {
                                if (row.DefaultCellStyle.BackColor == System.Drawing.Color.Pink)
                                {
                                    deleted_rows.Add(row);
                                    continue;
                                }
                                bool locked_evaluation = false;
                                bool locked_condition = false;
                                bool manual = false;
                                bool period1 = false;

                                bool.TryParse(row.Cells["colManual"].Value + "", out manual);
                                bool.TryParse(row.Cells["colPeriod1"].Value + "", out period1);
                                bool.TryParse(row.Cells["chkEvaluation"].Value + "", out locked_evaluation);
                                bool.TryParse(row.Cells["chkLock"].Value + "", out locked_condition);

                                if (manual || period1)
                                    continue;

                                if (!locked_evaluation && !locked_condition)
                                    no_locked_rows.Add(row);

                                if (!locked_condition && locked_evaluation)
                                    locked_rows_evaluation.Add(row);

                                if (locked_condition && !locked_evaluation)
                                    locked_rows_condition.Add(row);

                                if (locked_condition && locked_evaluation)
                                    locked_rows_condition_evaluation.Add(row);
                            }
                            //  重排「no_locked_rows」索引號
                            List<int> OrderedArray_no_locked = RandomOrder(Enumerable.Range(0, no_locked_rows.Count).ToList());
                            //  重排「locked_rows_evaluation」索引號
                            List<int> OrderedArray_evaluation = RandomOrder(Enumerable.Range(0, locked_rows_evaluation.Count).ToList());
                            //  重排「locked_rows_condition」索引號
                            List<int> OrderedArray_condition = RandomOrder(Enumerable.Range(0, locked_rows_condition.Count).ToList());
                            //  重排「locked_rows_condition_evaluation」索引號
                            List<int> OrderedArray_condition_evaluation = RandomOrder(Enumerable.Range(0, locked_rows_condition_evaluation.Count).ToList());
                            //  待移除資料
                            List<DataGridViewRow> will_delete_rows = new List<DataGridViewRow>();
                            //  先移除沒有任何勾選
                            for (int i = 0; i < OrderedArray_no_locked.Count; i++)
                            {
                                will_delete_rows.Add(no_locked_rows.ElementAt(OrderedArray_no_locked.ElementAt(i)));
                            }
                            //  再移除選課優先
                            for (int i = 0; i < OrderedArray_evaluation.Count; i++)
                            {
                                will_delete_rows.Add(locked_rows_evaluation.ElementAt(OrderedArray_evaluation.ElementAt(i)));
                            }
                            //  再移除條件優先
                            for (int i = 0; i < OrderedArray_condition.Count; i++)
                            {
                                will_delete_rows.Add(locked_rows_condition.ElementAt(OrderedArray_condition.ElementAt(i)));
                            }
                            //  最後移除選課優先+條件優先
                            for (int i = 0; i < OrderedArray_condition_evaluation.Count; i++)
                            {
                                will_delete_rows.Add(locked_rows_condition_evaluation.ElementAt(OrderedArray_condition_evaluation.ElementAt(i)));
                            }
                            // 寫入自動篩汰資料
                            string CourseID = this.groupPanel1.Tag + "";
                            decimal school_year = this.nudSchoolYear.Value;
                            string semester = (this.cboSemester.SelectedItem as DataItems.SemesterItem).Value;

                            List<UDT.CSAttend> CSAttends = Access.Select<UDT.CSAttend>(string.Format("ref_course_id={0}", CourseID));
                            Dictionary<int, UDT.CSAttend> dicCSAttends = new Dictionary<int, UDT.CSAttend>();
                            if (CSAttends.Count > 0)
                            {
                                CSAttends.ForEach((x) =>
                                {
                                    if (!dicCSAttends.ContainsKey(x.StudentID))
                                        dicCSAttends.Add(x.StudentID, x);
                                });
                            }
                            List<UDT.CSAttend> CSAttend_Deleteds = new List<UDT.CSAttend>();
                            List<UDT.CSAttendLog> CSAttendLogs = new List<UDT.CSAttendLog>();
                            //  開始移除「will_delete_rows」的元素
                            for (int i = 0; i<delete_no; i++)
                            {
                                DataGridViewRow row = will_delete_rows.ElementAt(i);

                                int StudentID = int.Parse(row.Cells["lblStudentID"].Value + "");
                                if (dicCSAttends.ContainsKey(StudentID))
                                {
                                    UDT.CSAttend CSAttend = dicCSAttends[StudentID];
                                    UDT.CSAttendLog CSAttendLog = new UDT.CSAttendLog();
                                    CSAttend.Deleted = true;

                                    CSAttendLog.StudentID = StudentID;
                                    CSAttendLog.CourseID = int.Parse(CourseID);
                                    CSAttendLog.SchoolYear = int.Parse(school_year.ToString());
                                    CSAttendLog.Semester = int.Parse(semester);
                                    CSAttendLog.Item = this.item;
                                    CSAttendLog.Action = "delete";
                                    CSAttendLog.ActionBy = "staff";

                                    CSAttendLogs.Add(CSAttendLog);
                                    CSAttend_Deleteds.Add(CSAttend);
                                }
                            }
                            CSAttend_Deleteds.SaveAll();
                            CSAttendLogs.SaveAll();

                            this.InitCSAttend(CourseID);
                            if (this.chkShowLog.Checked)
                                this.AppendCSAttendLog(CourseID);

                            this.EnableButtons();
                        }
                    }
                }
            }
            else
            {
                MessageBox.Show("人數上限必須為正整數。");
                return;
            }
        }