C#でキーブレイク処理をすることになった。
COBOLの時は1件読込み後、キーブレイク変数をセットとして
perform untilで回していたけど、C#の場合は、LINQを使った方がきれいに書ける。
//最初は月度でブレイク
var yearMonths = items.GroupBy(x => x.月度);
foreach (var ym in yearMonths) {
//シート追加&ヘッダ処理
if (ym.Key == pic売上年月_開始.SelectedDate.Value.ToString("yyyyMM")) { //最初の月度ならシート名を編集
sheet.Name = ym.Key.Substring(0, 4) + "年" + ym.Key.Substring(4, 2) + "月";
}
else {
package.Workbook.Worksheets.Add(ym.Key.Substring(0, 4) + "年" + ym.Key.Substring(4, 2) + "月");
vSt++;
sheet = package.Workbook.Worksheets[vSt];
}
sheet.Cells["F1"].Value = ym.Key.Substring(0,4) + " 年 " + ym.Key.Substring(4,2) + " + 月現在";
sheet.Cells["P1"].Value = DateTime.Now.ToString(" yyyy/MM/dd HH:mm:ss");
//列Aから列Eまで非表示
sheet.Column(1).Hidden = true;
sheet.Column(2).Hidden = true;
sheet.Column(3).Hidden = true;
sheet.Column(4).Hidden = true;
sheet.Column(5).Hidden = true;
sheet.Column(7).Hidden = true;
sheet.Column(8).Hidden = true;
sheet.Column(9).Hidden = true;
//ヘッダー項目編集
sheet.Cells["F1"].Value = DateTime.Today.ToString("yyyy 年 MM月現在");
sheet.Cells["K1"].Value = " *** 担当者別売上統計表 ***";
sheet.Cells["P1"].Value = DateTime.Now.ToString(" yyyy/MM/dd HH:mm:ss");
sheet.Cells["A3"].Value = "年月";
sheet.Cells["B3"].Value = "部門";
sheet.Cells["C3"].Value = "部門名";
sheet.Cells["D3"].Value = "課";
sheet.Cells["E3"].Value = "課名";
sheet.Cells["F3"].Value = " コード担当者名";
sheet.Cells["G3"].Value = "担当者名";
sheet.Cells["H3"].Value = "得意先";
sheet.Cells["I3"].Value = "得意先名";
sheet.Cells["J3"].Value = "純売上";
sheet.Cells["K3"].Value = "粗利";
sheet.Cells["L3"].Value = "粗利率";
sheet.Cells["M3"].Value = "売上";
sheet.Cells["N3"].Value = "返品";
sheet.Cells["O3"].Value = "返品率";
sheet.Cells["P3"].Value = "値引";
sheet.Cells["Q3"].Value = "値引率";
sheet.Cells["R3"].Value = "売上目標";
sheet.Cells["S3"].Value = "達成率";
sheet.Cells["K1"].Style.Font.SetFromFont(new Font("MS Mincho", 16, FontStyle.Bold));
sheet.Cells["A3"].Style.Font.SetFromFont(new Font("MS Mincho", 11, FontStyle.Bold));
sheet.Cells["B3"].Style.Font.SetFromFont(new Font("MS Mincho", 11, FontStyle.Bold));
sheet.Cells["C3"].Style.Font.SetFromFont(new Font("MS Mincho", 11, FontStyle.Bold));
sheet.Cells["D3"].Style.Font.SetFromFont(new Font("MS Mincho", 11, FontStyle.Bold));
sheet.Cells["E3"].Style.Font.SetFromFont(new Font("MS Mincho", 11, FontStyle.Bold));
sheet.Cells["F3"].Style.Font.SetFromFont(new Font("MS Mincho", 11, FontStyle.Bold));
sheet.Cells["G3"].Style.Font.SetFromFont(new Font("MS Mincho", 11, FontStyle.Bold));
sheet.Cells["H3"].Style.Font.SetFromFont(new Font("MS Mincho", 11, FontStyle.Bold));
sheet.Cells["I3"].Style.Font.SetFromFont(new Font("MS Mincho", 11, FontStyle.Bold));
sheet.Cells["J3"].Style.Font.SetFromFont(new Font("MS Mincho", 11, FontStyle.Bold));
sheet.Cells["K3"].Style.Font.SetFromFont(new Font("MS Mincho", 11, FontStyle.Bold));
sheet.Cells["L3"].Style.Font.SetFromFont(new Font("MS Mincho", 11, FontStyle.Bold));
sheet.Cells["M3"].Style.Font.SetFromFont(new Font("MS Mincho", 11, FontStyle.Bold));
sheet.Cells["N3"].Style.Font.SetFromFont(new Font("MS Mincho", 11, FontStyle.Bold));
sheet.Cells["O3"].Style.Font.SetFromFont(new Font("MS Mincho", 11, FontStyle.Bold));
sheet.Cells["P3"].Style.Font.SetFromFont(new Font("MS Mincho", 11, FontStyle.Bold));
sheet.Cells["Q3"].Style.Font.SetFromFont(new Font("MS Mincho", 11, FontStyle.Bold));
sheet.Cells["R3"].Style.Font.SetFromFont(new Font("MS Mincho", 11, FontStyle.Bold));
sheet.Cells["S3"].Style.Font.SetFromFont(new Font("MS Mincho", 11, FontStyle.Bold));
sheet.Column(06).Width = 30; //F
sheet.Column(11).Width = 16; //J
sheet.Column(12).Width = 16; //K
sheet.Column(13).Width = 7.5; //L
sheet.Column(14).Width = 16; //M
sheet.Column(15).Width = 16; //N
sheet.Column(16).Width = 7.5; //O
sheet.Column(17).Width = 16; //P
sheet.Column(18).Width = 7.5; //Q
sheet.Column(19).Width = 7.5; //R
//合計初期化
tl1純売上 = 0;
tl1粗利 = 0;
tl1売上 = 0;
tl1返品 = 0;
tl1値引 = 0;
tl1売上目標 = 0;
//自社他社区分のヘッダ編集
vY = 4;
//自社他社区分でブレイク
var v自社他社s = ym.GroupBy(x => x.自社他社区分);
foreach (var v自社他社 in v自社他社s) {
//ヘッダ編集
if (v自社他社.Key == "2") {
sheet.Cells[vY, 06].Value = "【区分 一般売上】";
}
else {
sheet.Cells[vY, 06].Value = "【区分 社内売上】";
}
sheet.Cells[vY, 06].Style.Font.SetFromFont(new Font("MS Mincho", 11, FontStyle.Bold));
vY++;
//初期化
tl2純売上 = 0;
tl2粗利 = 0;
tl2売上 = 0;
tl2返品 = 0;
tl2値引 = 0;
tl2売上目標 = 0;
//部門でブレイク
var v部門s = v自社他社.GroupBy(x => x.部門コード);
foreach (var v部門 in v部門s) {
var s1 = items.Where(x => x.月度 == ym.Key
&& x.自社他社区分 == v自社他社.Key
&& x.部門コード == v部門.Key).FirstOrDefault();
//ヘッダ編集
sheet.Cells[vY, 06].Value = s1.部門コード + " " + s1.部門名;
sheet.Cells[vY, 06].Style.Font.SetFromFont(new Font("MS Mincho", 11, FontStyle.Bold));
vY++;
//初期化
tl3純売上 = 0;
tl3粗利 = 0;
tl3売上 = 0;
tl3返品 = 0;
tl3値引 = 0;
tl3売上目標 = 0;
//課でブレイク
var v課s = v部門.GroupBy(x => x.課コード);
foreach (var v課 in v課s) {
var s2 = items.Where(x => x.月度 == ym.Key
&& x.自社他社区分 == v自社他社.Key
&& x.部門コード == v部門.Key
&& x.課コード == v課.Key).FirstOrDefault();
//初期化
tl4純売上 = 0;
tl4粗利 = 0;
tl4売上 = 0;
tl4返品 = 0;
tl4値引 = 0;
tl4売上目標 = 0;
//担当者でブレイク
var v担当者s = v課.GroupBy(x => x.担当者コード);
foreach (var v担当者 in v担当者s) {
var s3 = items.Where(x => x.月度 == ym.Key
&& x.自社他社区分 == v自社他社.Key
&& x.部門コード == v部門.Key
&& x.課コード == v課.Key).FirstOrDefault();
//初期化
tl5純売上 = 0;
tl5粗利 = 0;
tl5売上 = 0;
tl5返品 = 0;
tl5値引 = 0;
//明細出力
var recs = items.Where(x => x.月度 == ym.Key
&& x.自社他社区分 == v自社他社.Key
&& x.部門コード == v部門.Key
&& x.課コード == v課.Key
&& x.担当者コード == v担当者.Key);
foreach (var rec in recs) {
//明細編集
v純売上 = (rec.売上金額計 + rec.返品金額計);
v粗利率 = func率計算(rec.粗利金額計, v純売上);
v返品率 = func率計算(rec.返品金額計, rec.売上金額計);
v値引率 = func率計算(rec.値引金額計, v純売上);
sheet.Cells[vY, 01].Value = rec.月度;
sheet.Cells[vY, 02].Value = rec.部門コード;
sheet.Cells[vY, 03].Value = rec.部門名;
sheet.Cells[vY, 04].Value = rec.課コード;
sheet.Cells[vY, 05].Value = rec.課名;
sheet.Cells[vY, 06].Value = " " + rec.得意先コード + " " + rec.得意先名;
sheet.Cells[vY, 07].Value = rec.担当者名;
sheet.Cells[vY, 08].Value = rec.得意先コード;
sheet.Cells[vY, 09].Value = rec.得意先名;
sheet.Cells[vY, 10].Value = v純売上;
sheet.Cells[vY, 11].Value = rec.粗利金額計;
sheet.Cells[vY, 12].Value = v粗利率;
sheet.Cells[vY, 13].Value = rec.売上金額計;
sheet.Cells[vY, 14].Value = rec.返品金額計;
sheet.Cells[vY, 15].Value = v返品率;
sheet.Cells[vY, 16].Value = rec.値引金額計;
sheet.Cells[vY, 17].Value = v値引率;
sheet.Cells[vY, 18].Value = "";
sheet.Cells[vY, 19].Value = "";
//集計計算
tl5純売上 += v純売上;
tl5粗利 += rec.粗利金額計;
tl5売上 += rec.売上金額計;
tl5返品 += rec.返品金額計;
tl5値引 += rec.値引金額計;
//セーブ項目
sv売上目標 = rec.目標金額計;
sv担当者Cd = rec.担当者コード;
sv担当者名 = rec.担当者名;
vY++;
}
//集計計算
tl4純売上 += tl5純売上;
tl4粗利 += tl5粗利;
tl4売上 += tl5売上;
tl4返品 += tl5返品;
tl4値引 += tl5値引;
tl4売上目標 += sv売上目標;
//担当者合計出力
set合計Row(ref sheet, vY, " * " + sv担当者Cd + " " + sv担当者名,
tl5純売上,
tl5粗利,
tl5売上,
tl5返品,
tl5値引,
sv売上目標);
vY++;
}
//集計計算
tl3純売上 += tl4純売上;
tl3粗利 += tl4粗利;
tl3売上 += tl4売上;
tl3返品 += tl4返品;
tl3値引 += tl4値引;
tl3売上目標 += tl4売上目標;
//課合計出力
set合計Row(ref sheet, vY, " * " + s2.課コード + " " + s2.課名,
tl4純売上,
tl4粗利,
tl4売上,
tl4返品,
tl4値引,
tl4売上目標);
vY++;
}
//集計計算
tl2純売上 += tl3純売上;
tl2粗利 += tl3粗利;
tl2売上 += tl3売上;
tl2返品 += tl3返品;
tl2値引 += tl3値引;
tl2売上目標 += tl3売上目標;
//部門合計出力
set合計Row(ref sheet, vY, " ** " + s1.部門コード + " " + s1.部門名,
tl3純売上,
tl3粗利,
tl3売上,
tl3返品,
tl3値引,
tl3売上目標);
vY++;
}
//集計計算
tl1純売上 += tl2純売上;
tl1粗利 += tl2粗利;
tl1売上 += tl2売上;
tl1返品 += tl2返品;
tl1値引 += tl2値引;
tl1売上目標 += tl2売上目標;
//自社他社区分合計出力
set合計Row(ref sheet, vY, " *** 区分計",
tl2純売上,
tl2粗利,
tl2売上,
tl2返品,
tl2値引,
tl2売上目標);
vY++;
}
//月度合計出力
set合計Row(ref sheet, vY, " **** 総合計",
tl1純売上,
tl1粗利,
tl1売上,
tl1返品,
tl1値引,
tl1売上目標);
}
package.Save();
}
}
private void set合計Row(ref ExcelWorksheet isheet,
int iY,
string i計名,
decimal i純売上,
decimal i粗利,
decimal i売上,
decimal i返品,
decimal i値引,
decimal i売上目標) {
isheet.Cells[iY, 06].Value = i計名;
isheet.Cells[iY, 06].Style.Font.SetFromFont(new Font("MS Mincho", 11, FontStyle.Bold));
isheet.Cells[iY, 10].Value = i純売上;
isheet.Cells[iY, 11].Value = i粗利;
isheet.Cells[iY, 12].Value = func率計算(i粗利, i純売上);
isheet.Cells[iY, 13].Value = i売上;
isheet.Cells[iY, 14].Value = i返品;
isheet.Cells[iY, 15].Value = func率計算(i返品, i売上);
isheet.Cells[iY, 16].Value = i値引;
isheet.Cells[iY, 17].Value = func率計算(i値引, i純売上);
isheet.Cells[iY, 18].Value = i売上目標;
isheet.Cells[iY, 19].Value = func率計算(i純売上, i売上目標);
}
private decimal func率計算(decimal i1, decimal i2) {
decimal vCal = 0;
try {
vCal = (i1 / i2) * 100;
}
catch { vCal = 0; }
return vCal;
}