diff --git a/JQSalesSummaryPanel.cs b/JQSalesSummaryPanel.cs
index c0b2a77..e5daa1b 100644
--- a/JQSalesSummaryPanel.cs
+++ b/JQSalesSummaryPanel.cs
@@ -59,7 +59,7 @@ namespace KellyReport_D
private void initForecastBtn_Click(object sender, EventArgs e)
{
WorkBookUtils.GenForecast(this.initForecastBtn);
- MessageBox.Show("生成年度预估表完成", "完成", MessageBoxButtons.OK, MessageBoxIcon.Information);
+ MessageBox.Show("生成年度預估表完成", "完成", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
private void importSalesBtn_Click(object sender, EventArgs e)
@@ -68,21 +68,27 @@ namespace KellyReport_D
if (workBook == null)
{
- MessageBox.Show("未选择文件或文件打开失败,请重试。", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
+ MessageBox.Show("未選擇文件或者文件無法打開,請重試。", "錯誤", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
+ String originLabel = this.importSalesBtn.Text;
+ this.importSalesBtn.Text = Resources.GENERATING;
+
try
{
WorkBookUtils.ImportSalesDetailFromWorkBook(workBook);
+ MessageBox.Show("導入銷售表完成", "完成", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
catch (Exception ex)
{
- MessageBox.Show($"导入过程中发生错误:{ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
+ FileLogger.Error($"導入銷售表错误!", ex);
+ MessageBox.Show($"導入銷售表過程中發生錯誤:{ex.Message}", "錯誤", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
finally
{
workBook.Close(false); // 关闭工作簿
+ this.importSalesBtn.Text = originLabel;
}
}
}
diff --git a/KellyReport_D.csproj b/KellyReport_D.csproj
index 7b147fc..455ac76 100644
--- a/KellyReport_D.csproj
+++ b/KellyReport_D.csproj
@@ -34,7 +34,7 @@
publish\
zh-chs
- 1.0.0.7
+ 1.0.0.9
true
true
7
diff --git a/Properties/AssemblyInfo.cs b/Properties/AssemblyInfo.cs
index 54a36a3..7ba2652 100644
--- a/Properties/AssemblyInfo.cs
+++ b/Properties/AssemblyInfo.cs
@@ -34,5 +34,5 @@ using System.Security;
// 方法是按如下所示使用“*”: :
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.6")]
+[assembly: AssemblyFileVersion("1.0.0.8")]
diff --git a/Utils/WorkBookUtils.cs b/Utils/WorkBookUtils.cs
index 84a62c9..83213b8 100644
--- a/Utils/WorkBookUtils.cs
+++ b/Utils/WorkBookUtils.cs
@@ -375,27 +375,46 @@ namespace KellyReport_D.Utils
}).ToList();
Range salesNameCell = userSheet.Cells[clientSalesRowIndex, 1];
- int curRowCount = 1;
- int clientSalesRowCount = productSalesList.Count + 1;
+ int curRowCount = productSalesList.Count + 1;
+
if (salesNameCell.MergeCells)
{
Range mergedCell = salesNameCell.MergeArea;
curRowCount = mergedCell.Rows.Count;
- }
- // 添加行数
- if (curRowCount < clientSalesRowCount)
- {
- for (var i = 0; i < clientSalesRowCount - curRowCount; i++)
+
+ foreach (var productSales in productSalesList)
{
- userSheet.Rows[clientSalesRowIndex + curRowCount - 1].Insert(XlInsertShiftDirection.xlShiftDown);
+ Range productNameRows = userSheet.Range[
+ userSheet.Cells[mergedCell.Row, 11],
+ userSheet.Cells[mergedCell.Row + curRowCount - 1, 11]
+ ];
+ var targetProductName = productNameRows.Find(What: productSales.ProductNameEN, LookIn: XlFindLookIn.xlValues, LookAt: XlLookAt.xlWhole, SearchOrder: XlSearchOrder.xlByRows, SearchDirection: XlSearchDirection.xlNext, MatchCase: false);
+
+ if (targetProductName == null)
+ {
+ // 原有客户,新增产品行
+ userSheet.Rows[clientSalesRowIndex + curRowCount - 1].Insert(XlInsertShiftDirection.xlShiftDown);
+
+ curRowCount++;
+ summaryRowIndex++;
+ }
+ }
+ }
+ else
+ {
+ foreach (var productSales in productSalesList)
+ {
+ // 新的客户行
+ userSheet.Rows[clientSalesRowIndex + 1].Insert(XlInsertShiftDirection.xlShiftDown);
summaryRowIndex++;
}
}
salesNameCell.Value2 = clientSalesDetail.SalesName;
- int totalRowIndex = clientSalesRowIndex + clientSalesRowCount - 1;
- userSheet.Range[userSheet.Cells[clientSalesRowIndex, 1], userSheet.Cells[totalRowIndex, 1]].Merge();
+ int totalRowIndex = clientSalesRowIndex + curRowCount - 1;
+ Range clientNameRange = userSheet.Range[userSheet.Cells[clientSalesRowIndex, 1], userSheet.Cells[totalRowIndex, 1]];
+ clientNameRange.Merge();
- WriteSalesDetailToSheet(userSheet, clientSalesRowIndex, yearColIndex, clientContact, productSalesList);
+ WriteSalesDetailToSheet(userSheet, clientNameRange, clientSalesRowIndex, yearColIndex, clientContact, productSalesList);
// 客户销量汇总
var totalSales = new List()
{
@@ -437,7 +456,7 @@ namespace KellyReport_D.Utils
}
};
- WriteSalesDetailToSheet(userSheet, totalRowIndex, yearColIndex, clientContact, totalSales);
+ WriteSalesDetailToSheet(userSheet, clientNameRange, totalRowIndex, yearColIndex, clientContact, totalSales);
}
// 计算总结
@@ -459,11 +478,11 @@ namespace KellyReport_D.Utils
userSheet.Application.ActiveWindow.FreezePanes = true;
}
- private static int WriteSalesDetailToSheet(Worksheet userSheet, int rowIndex, int yearColIndex, ClientContact clientContact, IEnumerable salesDetailList)
+ private static int WriteSalesDetailToSheet(Worksheet userSheet, Range clientNameRange, int rowIndex, int yearColIndex, ClientContact clientContact, IEnumerable salesDetailList)
{
Range productNamesCellRange = userSheet.Range[
- userSheet.Cells[rowIndex, 11],
- userSheet.Cells[rowIndex + salesDetailList.Count(), 11]
+ userSheet.Cells[clientNameRange.Row, 11],
+ userSheet.Cells[clientNameRange.Row + clientNameRange.Rows.Count - 1, 11]
];
foreach (var productSalesDetail in salesDetailList)
@@ -472,7 +491,6 @@ namespace KellyReport_D.Utils
// 如果存在相同产品名称,则写入对应行
if (productSalesDetail.ProductNameEN != "總銷售額")
{
-
var targetProductCell = productNamesCellRange.Find(What: productSalesDetail.ProductNameEN, LookIn: XlFindLookIn.xlValues, LookAt: XlLookAt.xlWhole, SearchOrder: XlSearchOrder.xlByRows, SearchDirection: XlSearchDirection.xlNext, MatchCase: false);
if (targetProductCell != null)
{
@@ -516,6 +534,7 @@ namespace KellyReport_D.Utils
userSheet.Cells[currentRowIndex, 9].Value2 = clientContact.PurchaserPhone;
userSheet.Cells[currentRowIndex, 10].Value2 = clientContact.Address;
userSheet.Cells[currentRowIndex, 11].Value2 = productSalesDetail.ProductNameEN;
+ userSheet.Cells[currentRowIndex, 11].NumberFormat = "@";
// 计算每月的数量和金额
int monthCol = yearColIndex;
@@ -640,8 +659,8 @@ namespace KellyReport_D.Utils
userSheet.Cells[3, startCol + 37].Value2 = "總金額";
// 设置所有已用单元格居中
- Range usedRange = userSheet.UsedRange;
- usedRange.HorizontalAlignment = XlHAlign.xlHAlignCenter;
+ Range headerRange = userSheet.Rows["1:3"];
+ headerRange.HorizontalAlignment = XlHAlign.xlHAlignCenter;
return startCol;
}
@@ -721,6 +740,8 @@ namespace KellyReport_D.Utils
{
int rowCount = rawSalesDetailData.GetLength(0);
int colCount = rawSalesDetailData.GetLength(1);
+ int colProductNameENIndex = rawSalesDetailData[2, 8].ToString() == "英文品名" ? 8 : 9;
+
for (int i = 3; i <= rowCount; i++)
{
@@ -733,13 +754,13 @@ namespace KellyReport_D.Utils
InvoiceDate = ResolveExcelDate(rawSalesDetailData[i, 5]),
InvoiceNumber = rawSalesDetailData[i, 6]?.ToString() ?? "",
ClientName = rawSalesDetailData[i, 7]?.ToString() ?? "",
- ProductNameEN = rawSalesDetailData[i, 8]?.ToString() ?? "",
- Quantity = rawSalesDetailData[i, 9] != null ? Convert.ToDecimal(rawSalesDetailData[i, 9]) : (decimal?)null,
- PriceWithTax = rawSalesDetailData[i, 10] != null ? Convert.ToDecimal(rawSalesDetailData[i, 10]) : (decimal?)null,
- AmountWithoutTax = rawSalesDetailData[i, 11] != null ? Convert.ToDecimal(rawSalesDetailData[i, 11]) : (decimal?)null,
- Tax = rawSalesDetailData[i, 12] != null ? Convert.ToDecimal(rawSalesDetailData[i, 12]) : (decimal?)null,
- TotalAmount = rawSalesDetailData[i, 13] != null ? Convert.ToDecimal(rawSalesDetailData[i, 13]) : (decimal?)null,
- Remark = rawSalesDetailData[i, 14]?.ToString() ?? "",
+ ProductNameEN = rawSalesDetailData[i, colProductNameENIndex]?.ToString() ?? "",
+ Quantity = rawSalesDetailData[i, 9] != null ? Convert.ToDecimal(rawSalesDetailData[i, colProductNameENIndex + 1]) : (decimal?)null,
+ PriceWithTax = rawSalesDetailData[i, 10] != null ? Convert.ToDecimal(rawSalesDetailData[i, colProductNameENIndex + 2]) : (decimal?)null,
+ AmountWithoutTax = rawSalesDetailData[i, 11] != null ? Convert.ToDecimal(rawSalesDetailData[i, colProductNameENIndex + 3]) : (decimal?)null,
+ Tax = rawSalesDetailData[i, 12] != null ? Convert.ToDecimal(rawSalesDetailData[i, colProductNameENIndex + 4]) : (decimal?)null,
+ TotalAmount = rawSalesDetailData[i, 13] != null ? Convert.ToDecimal(rawSalesDetailData[i, colProductNameENIndex + 5]) : (decimal?)null,
+ Remark = rawSalesDetailData[i, colProductNameENIndex + 6]?.ToString() ?? "",
};
salesDatailList.Add(item);
}
@@ -789,7 +810,7 @@ namespace KellyReport_D.Utils
// 获取「銷售年度預估」工作表
ReadSalesForecastData(context);
// 获取「產品年度預估」工作表
- // GenProductForecastData(context);
+ GenProductForecastData(context);
GenDepartmentSummary(context);
GenBussenessSheet(context);
@@ -965,6 +986,8 @@ namespace KellyReport_D.Utils
var app = context.Application;
var clientContactSheet = app.Worksheets["客戶資料"] as Worksheet;
+ clientContactSheet.Activate();
+
var clientContactRange = clientContactSheet.UsedRange;
IList clientContactList = new List();
@@ -1086,7 +1109,7 @@ namespace KellyReport_D.Utils
productSheet.Cells[2, insertCol + 1].Value2 = "金額(含稅)";
productSheet.Cells[2, insertCol + 2].Value2 = "金額(未稅)";
productSheet.Cells[2, insertCol + 3].Value2 = "平均單價";
- productSheet.Cells[2, insertCol + 4].Value2 = "成長率";
+ productSheet.Cells[2, insertCol + 4].Value2 = "達成率";
var growthRange = productSheet.Range[
productSheet.Cells[2, insertCol + 4],
productSheet.Cells[2, insertCol + 5]
@@ -1147,6 +1170,7 @@ namespace KellyReport_D.Utils
{
productSheet.Rows[totalRowCount].Insert();
productSheet.Cells[totalRowCount, 1].Value2 = curProductName;
+ productSheet.Cells[totalRowCount, 1].NumberFormat = "@";
productRange = productSheet.Cells[totalRowCount, 1];
totalRowCount += 1;
@@ -1183,6 +1207,19 @@ namespace KellyReport_D.Utils
FormatSheetStyle(productSheet);
}
+ private static string EscapeExcelFindValue(string input)
+ {
+ if (string.IsNullOrEmpty(input))
+ {
+ return input;
+ }
+
+ return input
+ .Replace("~", "~~")
+ .Replace("*", "~*")
+ .Replace("?", "~?");
+ }
+
public static void GenClientSummarySheet(ImportContext context)
{
var app = context.Application;
@@ -1191,9 +1228,15 @@ namespace KellyReport_D.Utils
Worksheet clientSheet = CreateSheetIfNotExisted(app, sheetName);
clientSheet.Activate();
+ // 准备首行标题
+ clientSheet.Cells[2, 1].Value2 = "客戶名稱";
+ clientSheet.Cells[2, 2].Value2 = "產品名稱";
+
+ // 按年写入数据
context.YearList.ForEach(yearNumber =>
{
Range turnOverRange = clientSheet.UsedRange.Find(What: $"{yearNumber}-Turnover", LookIn: XlFindLookIn.xlValues, LookAt: XlLookAt.xlWhole, SearchOrder: XlSearchOrder.xlByRows, SearchDirection: XlSearchDirection.xlNext, MatchCase: false);
+
var clientSalesList = context.SalesDetails
.Where(x => x.InvoiceDate.HasValue && x.InvoiceDate.Value.Year == yearNumber)
.GroupBy(x => x.ClientName)
@@ -1205,9 +1248,11 @@ namespace KellyReport_D.Utils
Details = grouped.ToList()
})
.ToList();
+
+ // 目标年份列
if (turnOverRange == null)
{
- int insertCol = 2;
+ int insertCol = 3;
Range insertRange = clientSheet.Columns[$"{GetColumnLetter(insertCol)}:{GetColumnLetter(insertCol + 5)}"];
insertRange.EntireColumn.Insert(XlInsertShiftDirection.xlShiftToRight);
@@ -1253,16 +1298,17 @@ namespace KellyReport_D.Utils
foreach (var clientSalesGroup in clientSalesList)
{
var curClientName = clientSalesGroup.ClientName;
- // look for the Client row
- // if not exists then create a new row
- Range clientRange = clientSheet.UsedRange.Find(
- What: curClientName,
- LookIn: XlFindLookIn.xlValues,
- LookAt: XlLookAt.xlWhole,
- SearchOrder: XlSearchOrder.xlByRows,
- SearchDirection: XlSearchDirection.xlNext,
- MatchCase: false
- );
+
+ var clientProductSalesGrouped = clientSalesGroup.Details.GroupBy(x => x.ProductNameEN).Select(grouped => new ImportContext.GroupedSalesDetailModel()
+ {
+ ClientName = curClientName,
+ ProductNameEN = grouped.Key,
+ Quantity = grouped.Sum(x => x.Quantity ?? 0),
+ TotalAmount = grouped.Sum(x => x.TotalAmount ?? 0),
+ Details = grouped.ToList()
+ }).ToList();
+ // 查找是否已经存在的客户,存在则直接写入, 否则创建新行
+ Range clientRange = clientSheet.UsedRange.Find(What: EscapeExcelFindValue(curClientName));
if (clientRange == null)
{
@@ -1273,18 +1319,97 @@ namespace KellyReport_D.Utils
totalRowCount += 1;
}
- int curRowIndex = clientRange.Row;
+ int clientTotalRowIndex = clientRange.Row;
+ // 处理产品名称行以及总销售行
+ if (clientRange.MergeCells)
+ {
+ Range clientSalesRows = clientRange.MergeArea;
+ int endRowIndex = clientSalesRows.End[XlDirection.xlDown].Row - 1;
- clientSheet.Cells[curRowIndex, startColIndex].Value2 = clientSalesGroup.Quantity;
- clientSheet.Cells[curRowIndex, startColIndex + 1].Value2 = clientSalesGroup.TotalAmount;
- clientSheet.Cells[curRowIndex, startColIndex + 2].formula = $"={amountColLetter}{curRowIndex}/1.13";
- clientSheet.Cells[curRowIndex, startColIndex + 3].formula = $"={amountColLetter}{curRowIndex}/${quantityColLetter}{curRowIndex}";
+ foreach (var clientProductSales in clientProductSalesGrouped)
+ {
+ Range clientProductNameCells = clientSheet.Range[
+ clientSheet.Cells[clientSalesRows.Row, 2],
+ clientSheet.Cells[endRowIndex, 2]
+ ];
- clientSheet.Cells[curRowIndex, startColIndex + 4].formula = $"={quantityColLetter}{curRowIndex}/${prevQuantityColLetter}{curRowIndex}";
- clientSheet.Cells[curRowIndex, startColIndex + 5].formula = $"={amountColLetter}{curRowIndex}/${prevAmountColLetter}{curRowIndex}";
+ var targetProduct = clientProductNameCells.Find(What: clientProductSales.ProductNameEN);
+ if (targetProduct == null)
+ {
+ clientSheet.Rows[endRowIndex].Insert(XlInsertShiftDirection.xlShiftDown);
+ clientSheet.Cells[endRowIndex, 2].Value2 = clientProductSales.ProductNameEN;
+ clientSheet.Cells[endRowIndex, 2].NumberFormat = "@";
- clientSheet.Cells[curRowIndex, startColIndex + 4].NumberFormat = "0.00%";
- clientSheet.Cells[curRowIndex, startColIndex + 5].NumberFormat = "0.00%";
+ endRowIndex++;
+ totalRowCount++;
+ }
+ }
+ clientTotalRowIndex = endRowIndex;
+ }
+ else
+ {
+ for (int i = 0; i < clientProductSalesGrouped.Count(); i++)
+ {
+ var clientProductSales = clientProductSalesGrouped[i];
+
+ clientSheet.Cells[clientRange.Row + i, 2].Value2 = clientProductSales.ProductNameEN;
+ clientSheet.Cells[clientRange.Row + i, 2].NumberFormat = "@";
+ clientSheet.Rows[clientRange.Row + i + 1].Insert();
+
+ clientTotalRowIndex++;
+ totalRowCount++;
+ }
+ }
+ clientSheet.Cells[clientTotalRowIndex, 2].Value2 = "總銷售額";
+ clientSheet.Range[
+ clientSheet.Cells[clientRange.Row, 1],
+ clientSheet.Cells[clientTotalRowIndex, 1]
+ ].Merge();
+
+ // 重新选择合并后单元格
+ clientRange = clientSheet.Cells[clientRange.Row, 1];
+
+ foreach (var clientProductSales in clientProductSalesGrouped)
+ {
+ Range clientProductNameCells = clientSheet.Range[
+ clientSheet.Cells[clientRange.Row, 2],
+ clientSheet.Cells[clientTotalRowIndex, 2]
+ ];
+
+ var targetProduct = clientProductNameCells.Find(What: clientProductSales.ProductNameEN);
+ if (targetProduct == null)
+ {
+ FileLogger.Error($"无法找到客户 {curClientName} 的产品行 {clientProductSales.ProductNameEN},请检查数据完整性。");
+
+ MessageBox.Show($"无法找到客户 {curClientName} 的产品行 {clientProductSales.ProductNameEN},请检查数据完整性。", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
+ continue;
+ }
+
+ int productRowIndex = targetProduct.Row;
+ clientSheet.Cells[productRowIndex, startColIndex].Value2 = clientProductSales.Quantity;
+ clientSheet.Cells[productRowIndex, startColIndex + 1].Value2 = clientProductSales.TotalAmount;
+ clientSheet.Cells[productRowIndex, startColIndex + 2].formula = $"={amountColLetter}{productRowIndex}/1.13";
+ clientSheet.Cells[productRowIndex, startColIndex + 3].formula = $"={amountColLetter}{productRowIndex}/${quantityColLetter}{productRowIndex}";
+
+ clientSheet.Cells[productRowIndex, startColIndex + 4].formula = $"={quantityColLetter}{productRowIndex}/${prevQuantityColLetter}{productRowIndex}";
+ clientSheet.Cells[productRowIndex, startColIndex + 5].formula = $"={amountColLetter}{productRowIndex}/${prevAmountColLetter}{productRowIndex}";
+
+ clientSheet.Cells[productRowIndex, startColIndex + 4].NumberFormat = "0.00%";
+ clientSheet.Cells[productRowIndex, startColIndex + 5].NumberFormat = "0.00%";
+ }
+
+ // 填写总销售额行
+ int totalRowIndex = clientRange.Row + clientProductSalesGrouped.Count();
+ clientSheet.Cells[clientTotalRowIndex, startColIndex].Value2 = clientSalesGroup.Quantity;
+ clientSheet.Cells[clientTotalRowIndex, startColIndex + 1].Value2 = clientSalesGroup.TotalAmount;
+ clientSheet.Cells[clientTotalRowIndex, startColIndex + 2].formula = $"={amountColLetter}{clientTotalRowIndex}/1.13";
+ clientSheet.Cells[clientTotalRowIndex, startColIndex + 3].formula = $"={amountColLetter}{clientTotalRowIndex}/${quantityColLetter}{clientTotalRowIndex}";
+
+ clientSheet.Cells[clientTotalRowIndex, startColIndex + 4].formula = $"={quantityColLetter}{clientTotalRowIndex}/${prevQuantityColLetter}{clientTotalRowIndex}";
+ clientSheet.Cells[clientTotalRowIndex, startColIndex + 5].formula = $"={amountColLetter}{clientTotalRowIndex}/${prevAmountColLetter}{clientTotalRowIndex}";
+
+ clientSheet.Cells[clientTotalRowIndex, startColIndex + 4].NumberFormat = "0.00%";
+ clientSheet.Cells[clientTotalRowIndex, startColIndex + 5].NumberFormat = "0.00%";
}
clientSheet.Cells[totalRowCount, 1].Value2 = "總計";
@@ -1411,84 +1536,109 @@ namespace KellyReport_D.Utils
FormatSheetStyle(deptSheet);
}
-/* public static void GenProductForecastData(GenForecaseContext context)
+ public static void ReadProductData(GenForecaseContext context)
{
var app = context.Application;
+ var productDataSheet = app.Worksheets["產品資料"] as Worksheet;
+ productDataSheet.Activate();
+
+ var productRange = productDataSheet.UsedRange;
+ IList productList = new List();
+
+ // 第2行开始
+ int rowIndex = 2;
+
+ while (rowIndex <= productRange.Rows.Count)
+ {
+ productList.Add(new ProductForecastInput() { Name = productDataSheet.Cells[rowIndex, 1].Value2.ToString() });
+ rowIndex++;
+ }
+
+ context.ProductForecastList = productList;
+ }
+
+ public static void GenProductForecastData(GenForecaseContext context)
+ {
+ var app = context.Application;
+ ReadProductData(context);
+
string sheetName = $"產品年度預估";
Worksheet productSheet = CreateSheetIfNotExisted(app, sheetName);
productSheet.Activate();
var yearList = context.SalesForecastList.Select(x => x.Year).Distinct().ToList();
- string yearNumber = yearList[0].ToString();
+ int yearNumber = yearList[0];
+ // 准备标题行
Range estimateRange = productSheet.UsedRange.Find(What: $"{yearNumber}-Estimate", LookIn: XlFindLookIn.xlValues, LookAt: XlLookAt.xlWhole, SearchOrder: XlSearchOrder.xlByRows, SearchDirection: XlSearchDirection.xlNext, MatchCase: false);
- int insertCol = 2;
+ int estimateColIndex = 2;
if (estimateRange != null)
{
- insertCol = estimateRange.Column;
+ estimateColIndex = estimateRange.Column;
+ }
+ else
+ {
+ Range insertRange = productSheet.Columns[$"{GetColumnLetter(estimateColIndex)}:{GetColumnLetter(estimateColIndex + 5)}"];
+ insertRange.EntireColumn.Insert(XlInsertShiftDirection.xlShiftToRight);
+ insertRange = productSheet.Columns[$"{GetColumnLetter(estimateColIndex)}:{GetColumnLetter(estimateColIndex + 5)}"];
+ insertRange.ClearFormats();
}
- *//*
- Range insertRange = productSheet.Columns[$"{GetColumnLetter(insertCol)}:{GetColumnLetter(insertCol + 5)}"];
- insertRange.EntireColumn.Insert(XlInsertShiftDirection.xlShiftToRight);
- insertRange = productSheet.Columns[$"{GetColumnLetter(insertCol)}:{GetColumnLetter(insertCol + 5)}"];
- insertRange.ClearFormats();
- *//*
- productSheet.Cells[1, insertCol].Value2 = $"{yearNumber}-Estimate";
+ productSheet.Cells[1, estimateColIndex].Value2 = $"{yearNumber}-Estimate";
- productSheet.Cells[2, insertCol].Value2 = "數量";
- productSheet.Cells[2, insertCol + 1].Value2 = "金額(含稅)";
- productSheet.Cells[2, insertCol + 2].Value2 = "金額(未稅)";
- productSheet.Cells[2, insertCol + 3].Value2 = "平均單價";
- productSheet.Cells[2, insertCol + 4].Value2 = "成長率";
+ productSheet.Cells[2, estimateColIndex].Value2 = "數量";
+ productSheet.Cells[2, estimateColIndex + 1].Value2 = "金額(含稅)";
+ productSheet.Cells[2, estimateColIndex + 2].Value2 = "金額(未稅)";
+ productSheet.Cells[2, estimateColIndex + 3].Value2 = "平均單價";
+ productSheet.Cells[2, estimateColIndex + 4].Value2 = "成長率";
var growthRange = productSheet.Range[
- productSheet.Cells[2, insertCol + 4],
- productSheet.Cells[2, insertCol + 5]
+ productSheet.Cells[2, estimateColIndex + 4],
+ productSheet.Cells[2, estimateColIndex + 5]
];
growthRange.Merge();
estimateRange = productSheet.Range[
- productSheet.Cells[1, insertCol],
- productSheet.Cells[1, insertCol + 5]
+ productSheet.Cells[1, estimateColIndex],
+ productSheet.Cells[1, estimateColIndex + 5]
];
estimateRange.Merge();
- var productSalesList = context.SalesForecastList
- .Where(x => x..HasValue && x.InvoiceDate.Value.Year == yearNumber)
- .GroupBy(x => x.ProductNameEN)
- .Select(grouped => new ImportContext.GroupedSalesDetailModel()
- {
- ProductNameEN = grouped.Key,
- Quantity = grouped.Sum(x => x.Quantity ?? 0),
- TotalAmount = grouped.Sum(x => x.TotalAmount ?? 0),
- Details = grouped.ToList()
- })
- .ToList();
+ // 当前的汇总行
+ Range totalRange = productSheet.UsedRange.Find(What: $"總計", LookIn: XlFindLookIn.xlValues, LookAt: XlLookAt.xlWhole, SearchOrder: XlSearchOrder.xlByRows, SearchDirection: XlSearchDirection.xlNext, MatchCase: false);
- Range totalRange = clientSheet.UsedRange.Find(What: $"總計", LookIn: XlFindLookIn.xlValues, LookAt: XlLookAt.xlWhole, SearchOrder: XlSearchOrder.xlByRows, SearchDirection: XlSearchDirection.xlNext, MatchCase: false);
-
- int totalRowCount = clientSheet.UsedRange.Rows.Count + 1;
+ int totalRowCount = productSheet.UsedRange.Rows.Count + 1;
if (totalRange != null)
{
totalRowCount = totalRange.Row;
}
- int startColIndex = turnOverRange.Column;
+ int startColIndex = estimateColIndex;
var quantityColLetter = GetColumnLetter(startColIndex);
var amountColLetter = GetColumnLetter(startColIndex + 1);
var amountNoTaxColLetter = GetColumnLetter(startColIndex + 2);
+
+ // 上一年的销售
var prevQuantityColLetter = GetColumnLetter(startColIndex + 6);
var prevAmountColLetter = GetColumnLetter(startColIndex + 7);
var prevAmountNoTaxColLetter = GetColumnLetter(startColIndex + 8);
-
- foreach (var productSalesSummary in productSalesList)
+ Range lastYearEstimateRange = productSheet.UsedRange.Find(What: $"{yearNumber - 1}-Turnover", LookIn: XlFindLookIn.xlValues, LookAt: XlLookAt.xlWhole, SearchOrder: XlSearchOrder.xlByRows, SearchDirection: XlSearchDirection.xlNext, MatchCase: false);
+ if (lastYearEstimateRange != null)
{
- var curProductName = productSalesSummary.ProductNameEN;
- // look for the product row
- // if not exists then create a new row
- Range productRange = clientSheet.UsedRange.Find(
+ prevQuantityColLetter = GetColumnLetter(lastYearEstimateRange.Column);
+ prevAmountColLetter = GetColumnLetter(lastYearEstimateRange.Column + 1);
+ prevAmountNoTaxColLetter = GetColumnLetter(lastYearEstimateRange.Column + 2);
+ }
+
+ for (int i = 0; i < context.ProductForecastList.Count; i++)
+ {
+ ProductForecastInput productData = context.ProductForecastList[i];
+ var curProductName = productData.Name;
+
+ // 查找产品列,如已存在,无需处理
+ // 否则创建新的产品行,并初始化预算
+ Range productRange = productSheet.UsedRange.Find(
What: curProductName,
LookIn: XlFindLookIn.xlValues,
LookAt: XlLookAt.xlWhole,
@@ -1499,44 +1649,45 @@ namespace KellyReport_D.Utils
if (productRange == null)
{
- clientSheet.Rows[totalRowCount].Insert();
- clientSheet.Cells[totalRowCount, 1].Value2 = curProductName;
- productRange = clientSheet.Cells[totalRowCount, 1];
+ // 创建新的产品预算行
+ productSheet.Rows[totalRowCount].Insert();
+ productSheet.Cells[totalRowCount, 1].Value2 = curProductName;
+ productRange = productSheet.Cells[totalRowCount, 1];
+
+ int curRowIndex = totalRowCount;
+
+ productSheet.Cells[curRowIndex, startColIndex].Value2 = 0;
+ productSheet.Cells[curRowIndex, startColIndex + 1].Value2 = 0;
+ productSheet.Cells[curRowIndex, startColIndex + 2].formula = $"={amountColLetter}{curRowIndex}/1.13";
+ productSheet.Cells[curRowIndex, startColIndex + 3].formula = $"={amountColLetter}{curRowIndex}/${quantityColLetter}{curRowIndex}";
+
+ productSheet.Cells[curRowIndex, startColIndex + 4].formula = $"={quantityColLetter}{curRowIndex}/${prevQuantityColLetter}{curRowIndex}";
+
+ productSheet.Cells[curRowIndex, startColIndex + 5].formula = $"={amountColLetter}{curRowIndex}/${prevAmountColLetter}{curRowIndex}";
+
+ productSheet.Cells[curRowIndex, startColIndex + 4].NumberFormat = "0.00%";
+ productSheet.Cells[curRowIndex, startColIndex + 5].NumberFormat = "0.00%";
totalRowCount += 1;
}
-
- int curRowIndex = productRange.Row;
-
- clientSheet.Cells[curRowIndex, startColIndex].Value2 = productSalesSummary.Quantity;
- clientSheet.Cells[curRowIndex, startColIndex + 1].Value2 = productSalesSummary.TotalAmount;
- clientSheet.Cells[curRowIndex, startColIndex + 2].formula = $"={amountColLetter}{curRowIndex}/1.13";
- clientSheet.Cells[curRowIndex, startColIndex + 3].formula = $"={amountColLetter}{curRowIndex}/${quantityColLetter}{curRowIndex}";
-
- clientSheet.Cells[curRowIndex, startColIndex + 4].formula = $"={quantityColLetter}{curRowIndex}/${prevQuantityColLetter}{curRowIndex}";
- clientSheet.Cells[curRowIndex, startColIndex + 5].formula = $"={amountColLetter}{curRowIndex}/${prevAmountColLetter}{curRowIndex}";
-
- clientSheet.Cells[curRowIndex, startColIndex + 4].NumberFormat = "0.00%";
- clientSheet.Cells[curRowIndex, startColIndex + 5].NumberFormat = "0.00%";
}
- clientSheet.Cells[totalRowCount, 1].Value2 = "總計";
- clientSheet.Cells[totalRowCount, startColIndex].formula = $"=SUM({quantityColLetter}5:{quantityColLetter}{totalRowCount - 1})";
- clientSheet.Cells[totalRowCount, startColIndex + 1].formula = $"=SUM({amountColLetter}5:{amountColLetter}{totalRowCount - 1})";
- clientSheet.Cells[totalRowCount, startColIndex + 2].formula = $"=SUM({amountNoTaxColLetter}5:{amountNoTaxColLetter}{totalRowCount - 1})";
+ productSheet.Cells[totalRowCount, 1].Value2 = "總計";
+ productSheet.Cells[totalRowCount, startColIndex].formula = $"=SUM({quantityColLetter}5:{quantityColLetter}{totalRowCount - 1})";
+ productSheet.Cells[totalRowCount, startColIndex + 1].formula = $"=SUM({amountColLetter}5:{amountColLetter}{totalRowCount - 1})";
+ productSheet.Cells[totalRowCount, startColIndex + 2].formula = $"=SUM({amountNoTaxColLetter}5:{amountNoTaxColLetter}{totalRowCount - 1})";
- clientSheet.Cells[totalRowCount + 1, 1].Value2 = "備註";
- clientSheet.Cells[totalRowCount + 1, startColIndex].formula = $"={quantityColLetter}{totalRowCount}/{prevQuantityColLetter}{totalRowCount}";
- clientSheet.Cells[totalRowCount + 1, startColIndex + 1].formula = $"={amountColLetter}{totalRowCount}/{prevAmountColLetter}{totalRowCount}";
- clientSheet.Cells[totalRowCount + 1, startColIndex + 2].formula = $"={amountNoTaxColLetter}{totalRowCount}/{prevAmountNoTaxColLetter}{totalRowCount}";
+ productSheet.Cells[totalRowCount + 1, 1].Value2 = "備註";
+ productSheet.Cells[totalRowCount + 1, startColIndex].formula = $"={quantityColLetter}{totalRowCount}/{prevQuantityColLetter}{totalRowCount}";
+ productSheet.Cells[totalRowCount + 1, startColIndex + 1].formula = $"={amountColLetter}{totalRowCount}/{prevAmountColLetter}{totalRowCount}";
+ productSheet.Cells[totalRowCount + 1, startColIndex + 2].formula = $"={amountNoTaxColLetter}{totalRowCount}/{prevAmountNoTaxColLetter}{totalRowCount}";
- clientSheet.Cells[totalRowCount + 1, startColIndex].NumberFormat = "0.00%";
- clientSheet.Cells[totalRowCount + 1, startColIndex + 1].NumberFormat = "0.00%";
- clientSheet.Cells[totalRowCount + 1, startColIndex + 2].NumberFormat = "0.00%";
- });
- FormatSheetStyle(clientSheet);
+ productSheet.Cells[totalRowCount + 1, startColIndex].NumberFormat = "0.00%";
+ productSheet.Cells[totalRowCount + 1, startColIndex + 1].NumberFormat = "0.00%";
+ productSheet.Cells[totalRowCount + 1, startColIndex + 2].NumberFormat = "0.00%";
+
+ FormatSheetStyle(productSheet);
}
-*/
public static void UpdateDeptartmentSummary(ImportContext context)
{