using FarPoint.Excel; using FarPoint.Excel.EntityClassLibrary.DrawingVML; using FarPoint.Win.Spread; using FarPoint.Win.Spread.CellType.BarCode; using FCOMMON; using NetOffice.Extensions.Invoker; using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace FBS0000 { public partial class rHolidaySummary : fBase { public rHolidaySummary() { InitializeComponent(); Properties.Settings.Default["gwcs"] = FCOMMON.info.CS; this.WindowState = FormWindowState.Maximized; } private void rJobReport_Load(object sender, EventArgs e) { EnsureVisibleAndUsableSize(); this.tbMon.Text = DateTime.Now.ToShortDateString(); refrehData(); // this.reportViewer1.RefreshReport(); } void refrehData() { var dt = DateTime.Parse(this.tbMon.Text); ta.Fill(this.dsReport.holydata, FCOMMON.info.Login.gcode, dt.Year.ToString("0000") + "-01-01", dt.ToShortDateString()); //데이터를 재 집계한다. this.dsReport.holydatasum.Clear(); //1월1일년차데이터는 이월로 변경한다.. //var 이월데이터 = dsReport.holydata.Where(t => t.cate.StartsWith("이월") == false && t.cate.Contains("이월")).ToList(); //foreach (var dr in 이월데이터) //{ // var basecate = dr.cate.Split('-')[0].Trim(); // dr.cate = basecate; // dr.iwol = true; //} var grp_user = dsReport.holydata.GroupBy(t => t.uid).ToList(); var sum_drday = 0.0; var sum_crday = 0.0; var sum_addday = 0.0; var sum_janday = 0.0; var sum_iwol = 0.0; foreach (var grp in grp_user) { //cate group var first_user = grp.First(); var grp_cate = grp.GroupBy(t => t.cate).ToList(); foreach (var cate in grp_cate) { var newdr = this.dsReport.holydatasum.NewholydatasumRow(); var catename = cate.Key; newdr.uid = grp.Key; newdr.uname = first_user.name; newdr.process = first_user.Process; newdr.cate = cate.Key; if (catename.StartsWith("대체")) { newdr.dr = cate.Where(t => t.IsiwolNull() == true || t.iwol == false).Sum(t => t.DrTime); newdr.cr = cate.Where(t => t.IsiwolNull() == true || t.iwol == false).Sum(t => t.CrTime); newdr.iwol = cate.Where(t => t.IsiwolNull() == false && t.iwol == true).Sum(t => t.DrTime); } else if (catename.StartsWith("외출")) { } else { //이월과 그렇지 않은 데이터로 분리한다. newdr.drday = cate.Where(t => t.IsiwolNull() == true || t.iwol == false).Sum(t => t.DrDay); newdr.crday = cate.Where(t => t.IsiwolNull() == true || t.iwol == false).Sum(t => t.CrDay); newdr.iwolday = cate.Where(t => t.IsiwolNull() == false && t.iwol == true).Sum(t => t.DrDay); } if (catename.StartsWith("대체")) newdr.orderno = 99; else if (catename.StartsWith("년차")) newdr.orderno = 1; else if (catename.StartsWith("이월")) newdr.orderno = 0; else newdr.orderno = 2; if (newdr.dr == 0 && newdr.drday == 0 && newdr.cr == 0 && newdr.crday == 0) newdr.Delete(); else this.dsReport.holydatasum.AddholydatasumRow(newdr); } } this.dsReport.holydatasum.AcceptChanges(); ////this.reportViewer1.LocalReport.ReportPath = "JobReport_\\rK5Dailyform.rdlc"; //this.reportViewer1.SetDisplayMode(Microsoft.Reporting.WinForms.DisplayMode.Normal); //this.reportViewer1.ZoomMode = Microsoft.Reporting.WinForms.ZoomMode.Percent; //this.reportViewer1.RefreshReport(); var numcell1 = new FarPoint.Win.Spread.CellType.NumberCellType(); numcell1.DecimalPlaces = 1; numcell1.FixedPoint = false; numcell1.LeadingZero = FarPoint.Win.Spread.CellType.LeadingZero.No; numcell1.Separator = ","; numcell1.ShowSeparator = false; var percell1 = new FarPoint.Win.Spread.CellType.PercentCellType(); numcell1.DecimalPlaces = 1; numcell1.FixedPoint = false; numcell1.LeadingZero = FarPoint.Win.Spread.CellType.LeadingZero.No; numcell1.Separator = ","; numcell1.ShowSeparator = false; //데이터표시 var grpproc = dsReport.holydatasum.OrderBy(t => t.process).GroupBy(t => t.process); var row = 0; this.fpSpread1_Sheet1.ColumnHeaderRowCount = 2; var cols = new string[] { "공정", "사원명", "사번" }; var subcols = new string[] { "이월", "발생", "사용", "잔여", "초과", "소진율(%)", "이월\n소진율\n(%)" }; var headercol = 0; var catelist = new Dictionary(); foreach (var colname in cols) { this.fpSpread1_Sheet1.ColumnHeader.Cells[0, headercol].Value = colname; this.fpSpread1_Sheet1.AddColumnHeaderSpanCell(0, headercol, 2, 1); headercol += 1; } this.fpSpread1_Sheet1.ColumnCount = 200; //모든카테고리를 확인하여 컬럼을 먼저 생성한다. var gCate = dsReport.holydatasum.OrderBy(t => t.orderno).GroupBy(t => t.cate); foreach (var drCate in gCate) { catelist.Add(drCate.Key, headercol); this.fpSpread1_Sheet1.ColumnHeader.Cells[0, headercol].Value = drCate.Key; var grpstart = headercol; foreach (var colname in subcols) { this.fpSpread1_Sheet1.ColumnHeader.Cells[1, headercol++].Value = colname; } var grpend = headercol; fpSpread1.ActiveSheet.AddColumnHeaderSpanCell(0, grpstart, 1, grpend - grpstart); //같은그룹명 병합 } //최종합계추가 this.fpSpread1_Sheet1.ColumnHeader.Cells[0, headercol].Value = "합계(대체/외출 제외)"; var grpstart2 = headercol; foreach (var colname in subcols) { fpSpread1.ActiveSheet.ColumnCount = headercol + 1; this.fpSpread1_Sheet1.ColumnHeader.Cells[1, headercol++].Value = colname; } var grpend2 = headercol; fpSpread1.ActiveSheet.AddColumnHeaderSpanCell(0, grpstart2, 1, grpend2 - grpstart2); //같은그룹명 병합 fpSpread1.ActiveSheet.ColumnCount = headercol; this.fpSpread1_Sheet1.RowCount = 1; foreach (var drp in grpproc) { var grpdata = drp.OrderBy(t => t.uname).GroupBy(t => t.uid); var grpstart = row; foreach (var dr in grpdata) { var col = 0; var druser = dr.First(); if (row % 2 == 0) { fpSpread1_Sheet1.Rows[row].BackColor = Color.FromArgb(80, Color.LightSkyBlue); } else fpSpread1_Sheet1.Rows[row].BackColor = Color.White; fpSpread1_Sheet1.Cells[row, col++].Value = drp.First().process; fpSpread1_Sheet1.Cells[row, col++].Value = druser.uname; fpSpread1_Sheet1.Cells[row, col++].Value = druser.uid; //카테고리별로 데이터를 취합하여 대상 셀에 값을기록한다. var userCate = dr.GroupBy(t => t.cate); var sum_발생 = 0.0; var sum_사용 = 0.0; var sum_잔여 = 0.0; var sum_초과 = 0.0; var sum_이월 = 0.0; var lastcol = 0; foreach (var drCate in userCate) { var cateName = drCate.Key; var cateColumn = catelist[cateName]; //이컬럼의 시작 인덱스를 찾는다. //var offset = cateColumn; var 이월 = cateName.StartsWith("대체") ? drCate.Sum(t => t.iwol) : drCate.Sum(t => t.iwolday); var 발생 = cateName.StartsWith("대체") ? drCate.Sum(t => t.dr) : drCate.Sum(t => t.drday); var 사용 = cateName.StartsWith("대체") ? drCate.Sum(T => T.cr) : drCate.Sum(t => t.crday); var 잔여 = 발생 - 사용 + 이월; var 사용률 = 0.0; var 사용률2 = 0.0; var 초과 = 0.0; if (cateName.StartsWith("이월") && 잔여 < 0) { 잔여 = 0; } else { if (발생 + 이월 != 0) 사용률 = (사용 / (발생 + 이월)) * 100f; //년차에서만 초과를 계산한다. if (cateName.StartsWith("년차")) { //잔여가 -라면 초과분으로 한다 초과 = 잔여 < 0 ? -잔여 : 0; } if (발생 != 0) 사용률2 = ((사용 - 이월) / 발생) * 100f; } if (이월 != 0.0) fpSpread1_Sheet1.Cells[row, cateColumn++].Value = 이월; else cateColumn++; if (발생 != 0.0) fpSpread1_Sheet1.Cells[row, cateColumn++].Value = 발생; else cateColumn++; if (사용 != 0.0) fpSpread1_Sheet1.Cells[row, cateColumn++].Value = 사용; else cateColumn++; if (잔여 != 0.0) fpSpread1_Sheet1.Cells[row, cateColumn++].Value = 잔여; else cateColumn++; if (초과 != 0.0) fpSpread1_Sheet1.Cells[row, cateColumn++].Value = 초과; else cateColumn++; if (사용률 != 0.0) fpSpread1_Sheet1.Cells[row, cateColumn++].Value = Math.Round(사용률, 1); else cateColumn++; if (사용률2 != 0.0) fpSpread1_Sheet1.Cells[row, cateColumn++].Value = Math.Round(사용률2, 1); else cateColumn++; if (cateName.StartsWith("대체") == false && cateName.StartsWith("외출") == false) { sum_이월 += 이월; sum_발생 += 발생; sum_사용 += 사용; sum_잔여 += 잔여; sum_초과 += 초과; } if (cateColumn > lastcol) lastcol = cateColumn; } var sum_사용률 = Math.Round((sum_사용 / (sum_발생 + sum_이월)) * 100f, 1); var sum_사용률2 = Math.Round((sum_사용 - sum_이월) / (sum_발생) * 100f, 1); var offset = 0; if (sum_이월 != 0.0) fpSpread1_Sheet1.Cells[row, headercol - subcols.Length + offset++].Value = sum_이월; else fpSpread1_Sheet1.Cells[row, headercol - subcols.Length + offset++].Value = null; if (sum_발생 != 0.0) fpSpread1_Sheet1.Cells[row, headercol - subcols.Length + offset++].Value = sum_발생; else fpSpread1_Sheet1.Cells[row, headercol - subcols.Length + offset++].Value = null; if (sum_사용 != 0.0) fpSpread1_Sheet1.Cells[row, headercol - subcols.Length + offset++].Value = sum_사용; else fpSpread1_Sheet1.Cells[row, headercol - subcols.Length + offset++].Value = null; if (sum_잔여 != 0.0) fpSpread1_Sheet1.Cells[row, headercol - subcols.Length + offset++].Value = sum_잔여; else fpSpread1_Sheet1.Cells[row, headercol - subcols.Length + offset++].Value = null; if (sum_초과 != 0.0) fpSpread1_Sheet1.Cells[row, headercol - subcols.Length + offset++].Value = sum_초과; else fpSpread1_Sheet1.Cells[row, headercol - subcols.Length + offset++].Value = null; if (sum_사용률 != 0.0) fpSpread1_Sheet1.Cells[row, headercol - subcols.Length + offset++].Value = sum_사용률; else fpSpread1_Sheet1.Cells[row, headercol - subcols.Length + offset++].Value = null; if (sum_사용률2 != 0.0) fpSpread1_Sheet1.Cells[row, headercol - subcols.Length + offset++].Value = sum_사용률2; else fpSpread1_Sheet1.Cells[row, headercol - subcols.Length + offset++].Value = null; row += 1; if (this.fpSpread1_Sheet1.RowCount < 1 + row) this.fpSpread1_Sheet1.RowCount = 1 + row; } var grpend = row; fpSpread1.ActiveSheet.AddSpanCell(grpstart, 0, grpend - grpstart, 1); //같은그룹명 병합 } //마지막줄에는 총계를 표시한다. fpSpread1_Sheet1.Cells[row, 0].Value = "합계"; fpSpread1_Sheet1.AddSpanCell(row, 0, row, 3); fpSpread1_Sheet1.SetFormula(row, 3, $"SUM(R1C4:R{row}C4)"); //0번컬럼은 색상을 초기화 for (int i = 0; i < fpSpread1_Sheet1.RowCount; i++) fpSpread1_Sheet1.Cells[i, 0].BackColor = Color.White; for (int i = 4; i <= grpend2; i++) { var colname = fpSpread1_Sheet1.Columns[i - 1].Label; var cellf = fpSpread1_Sheet1.Cells.Get(row, i - 1).CellType; if (colname.Contains("%") == false) //일반 컬럼은 합계를 ㅏㅎㄴ다 { fpSpread1_Sheet1.SetFormula(row, i - 1, $"SUM(R1C{i}:R{row}C{i})"); } else { var startindex = colname.StartsWith("소진율") ? 2 : 3; //이월 var o이월 = fpSpread1_Sheet1.Cells[row, i - (startindex + 4)].Value; //발생 var o발생 = fpSpread1_Sheet1.Cells[row, i - (startindex + 3)].Value; //사용 var o사용 = fpSpread1_Sheet1.Cells[row, i - (startindex + 2)].Value; //잔여 var o잔여 = fpSpread1_Sheet1.Cells[row, i - (startindex + 1)].Value; //초과 var o초과 = fpSpread1_Sheet1.Cells[row, i - (startindex + 0)].Value; float 이월, 발생, 사용, 잔여, 초과; 이월 = o이월 != null ? float.Parse(o이월.ToString()) : 0; 발생 = o발생 != null ? float.Parse(o발생.ToString()) : 0; 사용 = o사용 != null ? float.Parse(o사용.ToString()) : 0; 잔여 = o잔여 != null ? float.Parse(o잔여.ToString()) : 0; 초과 = o초과 != null ? float.Parse(o초과.ToString()) : 0; var 소진율 = 0f; if ((발생 + 이월) != 0) 소진율 = (사용 / (발생 + 이월)) * 100f; var 소진율2 = 0f; if (발생 != 0) 소진율2 = ((사용 - 이월) / 발생) * 100f; if (colname.StartsWith("소진율")) { fpSpread1_Sheet1.SetValue(row, i - 1, 소진율);//.SetFormula(row, i - 1, $"AVERAGE(R1C{i}:R{row}C{i})"); fpSpread1_Sheet1.Cells[row, i - 1].CellType = numcell1; } else { fpSpread1_Sheet1.SetValue(row, i - 1, 소진율2);// fpSpread1_Sheet1.SetFormula(row, i - 1, $"AVERAGE(R1C{i}:R{row}C{i})"); fpSpread1_Sheet1.Cells[row, i - 1].CellType = numcell1; } //var 발생 = (double)fpSpread1_Sheet1.GetValue(row, i - 1 - 4); //var 사용 = (double)fpSpread1_Sheet1.GetValue(row, i - 1 - 3); //var 사용률 = 0.0; //if (사용 > 발생) 사용률 = 100; //else if (발생 > 0) 사용률 = Math.Round((사용 / 발생) * 100f, 1); //if (사용률 != 0.0) // fpSpread1_Sheet1.SetValue(row, i - 1, 사용률); } //cellf = numcell1; } fpSpread1_Sheet1.Cells[0, 0, row, grpend2 - 1].HorizontalAlignment = CellHorizontalAlignment.Center; fpSpread1_Sheet1.Cells[0, 0, row, grpend2 - 1].VerticalAlignment = CellVerticalAlignment.Center; //값이없는 컬럼은 숨김처리한다. string title = ""; for (int i = 3; i < fpSpread1_Sheet1.ColumnCount; i++) { if ((i + 4) % subcols.Length == 0) { title = fpSpread1_Sheet1.ColumnHeader.Cells[0, i].Text; } var title2 = fpSpread1_Sheet1.ColumnHeader.Cells[1, i].Text; if (title != "년차" && title != "합계" && title2 == "초과") { fpSpread1_Sheet1.Columns[i].Visible = false; } else if (title != "년차" && title != "합계" && title != "대체" && title2.Contains("이월")) { fpSpread1_Sheet1.Columns[i].Visible = false; } else fpSpread1_Sheet1.Columns[i].Visible = true; } } private void btSearch_Click(object sender, EventArgs e) { refrehData(); } private void toolStripButton8_Click(object sender, EventArgs e) { var sdo = DateTime.Parse(this.tbMon.Text); var sd = sdo.AddMonths(-1); tbMon.Text = sd.ToShortDateString(); } private void toolStripButton7_Click(object sender, EventArgs e) { var sdo = DateTime.Parse(this.tbMon.Text); var sd = sdo.AddMonths(1); tbMon.Text = sd.ToShortDateString(); } private void reportViewer1_Load(object sender, EventArgs e) { } private void lbStt_Click(object sender, EventArgs e) { } private void toolStripButton1_Click(object sender, EventArgs e) { var sd = new SaveFileDialog(); sd.Filter = "excel file|*.xls"; sd.RestoreDirectory = true; sd.FileName = $"휴가이력현황({tbMon.Text}).xls"; if (sd.ShowDialog() != DialogResult.OK) return; this.fpSpread1.SaveExcel(sd.FileName, ExcelSaveFlags.SaveAsViewed | ExcelSaveFlags.SaveBothCustomRowAndColumnHeaders); var dlg = FCOMMON.Util.MsgQ("생성된 파일을 확인 할까요?"); if (dlg != DialogResult.Yes) return; FCOMMON.Util.RunExplorer(sd.FileName); } } }