汇总月达成率表

This commit is contained in:
earo.lau 2025-09-07 17:36:27 +08:00
parent db87d00ead
commit 4ce03e8fda
2 changed files with 108 additions and 16 deletions

View File

@ -21,7 +21,7 @@ namespace KellyReport_D.Model
public string ProductNameEN { get; set; } public string ProductNameEN { get; set; }
public decimal TotalAmount { get; set; } public decimal TotalAmount { get; set; }
public decimal Quantity { get; set; } public decimal Quantity { get; set; }
public List<SalesDetail> Details { get; set; } public IList<SalesDetail> Details { get; set; }
} }
public IEnumerable<GroupedSalesDetailModel> GroupedSalesDetailBySalesName => SalesDetails public IEnumerable<GroupedSalesDetailModel> GroupedSalesDetailBySalesName => SalesDetails

View File

@ -35,6 +35,87 @@ namespace KellyReport_D.Utils
} }
GenSalesTotal(importContext); GenSalesTotal(importContext);
// 更新业务预估表
UpdateEstimatedTable(importContext);
}
private static void UpdateEstimatedTable(ImportContext importContext)
{
var app = importContext.Application;
Worksheet bussenessWorksheet = null;
foreach (Worksheet item in app.Worksheets)
{
if (item.Name == "業務月達成率")
{
bussenessWorksheet = item;
break;
}
};
if (bussenessWorksheet == null)
{
throw new EntryPointNotFoundException("未找到「業務月達成率」工作表,请先生成预估表。");
}
bussenessWorksheet.Activate();
Range usedRange = bussenessWorksheet.UsedRange;
int maxColIndex = usedRange.Columns.Count;
for (int i = 2; i < maxColIndex; i += 4)
{
String salesName = bussenessWorksheet.Cells[1, i].Value2;
if (string.IsNullOrWhiteSpace(salesName))
{
continue;
}
var salesDetails = salesName.ToUpper() == "TOTAL" ?
importContext.SalesDetails :
importContext.GroupedSalesDetailBySalesName.FirstOrDefault(x => x.SalesName.ToUpper() == salesName.ToUpper())?.Details;
if (salesDetails == null)
continue;
salesDetails.GroupBy(x => x.Month)
.Select(grouped => new
{
Month = grouped.Key,
TotalAmount = grouped.Sum(x => x.TotalAmount ?? 0),
})
.ToList()
.ForEach(monthlySales =>
{
int startRowIndex = 3;
for (int rowIndex = startRowIndex; rowIndex < startRowIndex + 12; rowIndex++)
{
var monthCell = bussenessWorksheet.Cells[rowIndex, 1];
if (monthCell.Value2 != null && monthCell.Value2.ToString() == monthlySales.Month)
{
var forecsastColLetter = GetColumnLetter(i);
var turnoverCell = bussenessWorksheet.Cells[rowIndex, i + 1];
var turnoverColLetter = GetColumnLetter(i + 1);
turnoverCell.Value2 = monthlySales.TotalAmount;
turnoverCell.NumberFormat = "#,##0";
var completionCell = bussenessWorksheet.Cells[rowIndex, i + 2];
completionCell.formula = $"={turnoverColLetter}{rowIndex}/{forecsastColLetter}{rowIndex}";
completionCell.NumberFormat = "0.00%";
var accCompletionCell = bussenessWorksheet.Cells[rowIndex, i + 3];
accCompletionCell.formula = $"=SUM(${turnoverColLetter}${startRowIndex}:{turnoverColLetter}{rowIndex})/SUM(${forecsastColLetter}${startRowIndex}:{forecsastColLetter}{rowIndex})";
accCompletionCell.NumberFormat = "0.00%";
break;
}
}
});
}
} }
private static void GenSalesTotal(ImportContext context) private static void GenSalesTotal(ImportContext context)
@ -139,10 +220,15 @@ namespace KellyReport_D.Utils
// 自适应所有已用列宽 // 自适应所有已用列宽
FormatSheetStyle(totalWorksheet); FormatSheetStyle(totalWorksheet);
totalWorksheet.Cells[4, 12].Select();
totalWorksheet.Application.ActiveWindow.FreezePanes = true;
} }
private static void FormatSheetStyle(Worksheet worksheet) private static void FormatSheetStyle(Worksheet worksheet)
{ {
worksheet.Activate();
// 自适应所有已用列宽 // 自适应所有已用列宽
Range usedRange2 = worksheet.UsedRange; Range usedRange2 = worksheet.UsedRange;
if (usedRange2 != null) if (usedRange2 != null)
@ -151,11 +237,6 @@ namespace KellyReport_D.Utils
usedRange2.Borders.LineStyle = XlLineStyle.xlContinuous; usedRange2.Borders.LineStyle = XlLineStyle.xlContinuous;
usedRange2.Borders.Weight = XlBorderWeight.xlThin; usedRange2.Borders.Weight = XlBorderWeight.xlThin;
} }
worksheet.Cells[4, 12].Select();
//worksheet.Application.ActiveWindow.SplitRow = 3;
//worksheet.Application.ActiveWindow.SplitColumn = 10;
worksheet.Application.ActiveWindow.FreezePanes = true;
} }
@ -245,6 +326,9 @@ namespace KellyReport_D.Utils
} }
FormatSheetStyle(userSheet); FormatSheetStyle(userSheet);
userSheet.Cells[4, 12].Select();
userSheet.Application.ActiveWindow.FreezePanes = true;
} }
private static int WriteSalesDetailToSheet(Worksheet userSheet, int rowIndex, ClientContact clientContact, IEnumerable<ImportContext.GroupedSalesDetailModel> salesDetailList) private static int WriteSalesDetailToSheet(Worksheet userSheet, int rowIndex, ClientContact clientContact, IEnumerable<ImportContext.GroupedSalesDetailModel> salesDetailList)
@ -551,17 +635,20 @@ namespace KellyReport_D.Utils
yearRange.Value2 = yearValue.ToString(); yearRange.Value2 = yearValue.ToString();
yearRange.NumberFormat = "@"; // 文本格式 yearRange.NumberFormat = "@"; // 文本格式
int startRowIndex = 1;
// 填入月份 // 填入月份
for (int i = 1; i < monthData.Length; i++) for (int i = 0; i < 12; i++)
{ {
sheet.Cells[i + 2, 1] = monthData[i]; int rowOffset = startRowIndex + 2;
sheet.Cells[i + rowOffset, 1] = $"{i + 1}月";
} }
sheet.Cells[startRowIndex + 14, 1].value2 = "Total";
// B列开始填 salesName 及相关数据 // B列开始填 salesName 及相关数据
int col = 2; // B列 int col = 2; // B列
foreach (var salesForcastData in context.SalesForecastList) foreach (var salesForcastData in context.SalesForecastList)
{ {
int rowIndex = 1; // Excel 行号从1开始 int rowIndex = startRowIndex; // Excel 行号从1开始
int startCol = col; int startCol = col;
int endCol = col + 4; int endCol = col + 4;
@ -576,7 +663,7 @@ namespace KellyReport_D.Utils
// 合并并填入“完成%” // 合并并填入“完成%”
Range finishRange = sheet.Range[ Range finishRange = sheet.Range[
sheet.Cells[rowIndex, startCol + 2], sheet.Cells[rowIndex, startCol + 2],
sheet.Cells[rowIndex, startCol + 2] sheet.Cells[rowIndex + 1, startCol + 2]
]; ];
finishRange.Merge(); finishRange.Merge();
finishRange.Value2 = "完成%"; finishRange.Value2 = "完成%";
@ -584,7 +671,7 @@ namespace KellyReport_D.Utils
// 合并并填入“累積達成率” // 合并并填入“累積達成率”
Range accRange = sheet.Range[ Range accRange = sheet.Range[
sheet.Cells[rowIndex, startCol + 3], sheet.Cells[rowIndex, startCol + 3],
sheet.Cells[rowIndex, startCol + 3] sheet.Cells[rowIndex + 1, startCol + 3]
]; ];
accRange.Merge(); accRange.Merge();
accRange.Value2 = "累積達成率"; accRange.Value2 = "累積達成率";
@ -603,16 +690,21 @@ namespace KellyReport_D.Utils
cell.NumberFormat = "#,##0"; cell.NumberFormat = "#,##0";
rowIndex++; rowIndex++;
} }
var forecastColLetter = GetColumnLetter(col);
var turnoverColLetter = GetColumnLetter(col + 1);
sheet.Cells[rowIndex, col].formula = $"=SUM({forecastColLetter}{startRowIndex}:{forecastColLetter}{rowIndex - 1})";
sheet.Cells[rowIndex, col + 1].formula = $"=SUM({turnoverColLetter}{startRowIndex}:{turnoverColLetter}{rowIndex - 1})";
sheet.Cells[rowIndex, col + 2].formula = $"=SUM({turnoverColLetter}{rowIndex}/{forecastColLetter}{rowIndex})";
sheet.Cells[rowIndex, col + 2].NumberFormat = "0.00%";
col = endCol; col = endCol;
} }
// 自适应所有已用列宽 // 自适应所有已用列宽
Range usedRange2 = sheet.UsedRange; FormatSheetStyle(sheet);
if (usedRange2 != null)
{
usedRange2.Columns.AutoFit();
}
} }
catch (Exception ex) catch (Exception ex)
{ {