优化Excel导入与年度预估表生成逻辑
- 客户/产品销售明细写入逻辑优化,支持动态插入产品行,合并单元格处理更严谨 - 销售明细导入支持“英文品名”列动态索引,兼容多种表格格式 - 启用产品年度预估表自动生成,支持“產品資料”批量导入 - 客户/产品查找新增特殊字符转义,查找更稳定 - “成長率”列标题改为“達成率” - 项目及程序集版本号提升
This commit is contained in:
parent
f839573712
commit
1d0d183d8a
@ -59,7 +59,7 @@ namespace KellyReport_D
|
|||||||
private void initForecastBtn_Click(object sender, EventArgs e)
|
private void initForecastBtn_Click(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
WorkBookUtils.GenForecast(this.initForecastBtn);
|
WorkBookUtils.GenForecast(this.initForecastBtn);
|
||||||
MessageBox.Show("生成年度预估表完成", "完成", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
MessageBox.Show("生成年度預估表完成", "完成", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void importSalesBtn_Click(object sender, EventArgs e)
|
private void importSalesBtn_Click(object sender, EventArgs e)
|
||||||
@ -68,21 +68,27 @@ namespace KellyReport_D
|
|||||||
|
|
||||||
if (workBook == null)
|
if (workBook == null)
|
||||||
{
|
{
|
||||||
MessageBox.Show("未选择文件或文件打开失败,请重试。", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
MessageBox.Show("未選擇文件或者文件無法打開,請重試。", "錯誤", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String originLabel = this.importSalesBtn.Text;
|
||||||
|
this.importSalesBtn.Text = Resources.GENERATING;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
WorkBookUtils.ImportSalesDetailFromWorkBook(workBook);
|
WorkBookUtils.ImportSalesDetailFromWorkBook(workBook);
|
||||||
|
MessageBox.Show("導入銷售表完成", "完成", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
MessageBox.Show($"导入过程中发生错误:{ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
FileLogger.Error($"導入銷售表错误!", ex);
|
||||||
|
MessageBox.Show($"導入銷售表過程中發生錯誤:{ex.Message}", "錯誤", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
workBook.Close(false); // 关闭工作簿
|
workBook.Close(false); // 关闭工作簿
|
||||||
|
this.importSalesBtn.Text = originLabel;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -34,7 +34,7 @@
|
|||||||
<PublishUrl>publish\</PublishUrl>
|
<PublishUrl>publish\</PublishUrl>
|
||||||
<InstallUrl />
|
<InstallUrl />
|
||||||
<TargetCulture>zh-chs</TargetCulture>
|
<TargetCulture>zh-chs</TargetCulture>
|
||||||
<ApplicationVersion>1.0.0.7</ApplicationVersion>
|
<ApplicationVersion>1.0.0.9</ApplicationVersion>
|
||||||
<AutoIncrementApplicationRevision>true</AutoIncrementApplicationRevision>
|
<AutoIncrementApplicationRevision>true</AutoIncrementApplicationRevision>
|
||||||
<UpdateEnabled>true</UpdateEnabled>
|
<UpdateEnabled>true</UpdateEnabled>
|
||||||
<UpdateInterval>7</UpdateInterval>
|
<UpdateInterval>7</UpdateInterval>
|
||||||
|
|||||||
@ -34,5 +34,5 @@ using System.Security;
|
|||||||
// 方法是按如下所示使用“*”: :
|
// 方法是按如下所示使用“*”: :
|
||||||
// [assembly: AssemblyVersion("1.0.*")]
|
// [assembly: AssemblyVersion("1.0.*")]
|
||||||
[assembly: AssemblyVersion("1.0.0.0")]
|
[assembly: AssemblyVersion("1.0.0.0")]
|
||||||
[assembly: AssemblyFileVersion("1.0.0.6")]
|
[assembly: AssemblyFileVersion("1.0.0.8")]
|
||||||
|
|
||||||
|
|||||||
@ -375,27 +375,46 @@ namespace KellyReport_D.Utils
|
|||||||
}).ToList();
|
}).ToList();
|
||||||
|
|
||||||
Range salesNameCell = userSheet.Cells[clientSalesRowIndex, 1];
|
Range salesNameCell = userSheet.Cells[clientSalesRowIndex, 1];
|
||||||
int curRowCount = 1;
|
int curRowCount = productSalesList.Count + 1;
|
||||||
int clientSalesRowCount = productSalesList.Count + 1;
|
|
||||||
if (salesNameCell.MergeCells)
|
if (salesNameCell.MergeCells)
|
||||||
{
|
{
|
||||||
Range mergedCell = salesNameCell.MergeArea;
|
Range mergedCell = salesNameCell.MergeArea;
|
||||||
curRowCount = mergedCell.Rows.Count;
|
curRowCount = mergedCell.Rows.Count;
|
||||||
}
|
|
||||||
// 添加行数
|
foreach (var productSales in productSalesList)
|
||||||
if (curRowCount < clientSalesRowCount)
|
|
||||||
{
|
|
||||||
for (var i = 0; i < clientSalesRowCount - curRowCount; i++)
|
|
||||||
{
|
{
|
||||||
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++;
|
summaryRowIndex++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
salesNameCell.Value2 = clientSalesDetail.SalesName;
|
salesNameCell.Value2 = clientSalesDetail.SalesName;
|
||||||
int totalRowIndex = clientSalesRowIndex + clientSalesRowCount - 1;
|
int totalRowIndex = clientSalesRowIndex + curRowCount - 1;
|
||||||
userSheet.Range[userSheet.Cells[clientSalesRowIndex, 1], userSheet.Cells[totalRowIndex, 1]].Merge();
|
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<ImportContext.GroupedSalesDetailModel>()
|
var totalSales = new List<ImportContext.GroupedSalesDetailModel>()
|
||||||
{
|
{
|
||||||
@ -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;
|
userSheet.Application.ActiveWindow.FreezePanes = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int WriteSalesDetailToSheet(Worksheet userSheet, int rowIndex, int yearColIndex, ClientContact clientContact, IEnumerable<ImportContext.GroupedSalesDetailModel> salesDetailList)
|
private static int WriteSalesDetailToSheet(Worksheet userSheet, Range clientNameRange, int rowIndex, int yearColIndex, ClientContact clientContact, IEnumerable<ImportContext.GroupedSalesDetailModel> salesDetailList)
|
||||||
{
|
{
|
||||||
Range productNamesCellRange = userSheet.Range[
|
Range productNamesCellRange = userSheet.Range[
|
||||||
userSheet.Cells[rowIndex, 11],
|
userSheet.Cells[clientNameRange.Row, 11],
|
||||||
userSheet.Cells[rowIndex + salesDetailList.Count(), 11]
|
userSheet.Cells[clientNameRange.Row + clientNameRange.Rows.Count - 1, 11]
|
||||||
];
|
];
|
||||||
|
|
||||||
foreach (var productSalesDetail in salesDetailList)
|
foreach (var productSalesDetail in salesDetailList)
|
||||||
@ -472,7 +491,6 @@ namespace KellyReport_D.Utils
|
|||||||
// 如果存在相同产品名称,则写入对应行
|
// 如果存在相同产品名称,则写入对应行
|
||||||
if (productSalesDetail.ProductNameEN != "總銷售額")
|
if (productSalesDetail.ProductNameEN != "總銷售額")
|
||||||
{
|
{
|
||||||
|
|
||||||
var targetProductCell = productNamesCellRange.Find(What: productSalesDetail.ProductNameEN, LookIn: XlFindLookIn.xlValues, LookAt: XlLookAt.xlWhole, SearchOrder: XlSearchOrder.xlByRows, SearchDirection: XlSearchDirection.xlNext, MatchCase: false);
|
var targetProductCell = productNamesCellRange.Find(What: productSalesDetail.ProductNameEN, LookIn: XlFindLookIn.xlValues, LookAt: XlLookAt.xlWhole, SearchOrder: XlSearchOrder.xlByRows, SearchDirection: XlSearchDirection.xlNext, MatchCase: false);
|
||||||
if (targetProductCell != null)
|
if (targetProductCell != null)
|
||||||
{
|
{
|
||||||
@ -516,6 +534,7 @@ namespace KellyReport_D.Utils
|
|||||||
userSheet.Cells[currentRowIndex, 9].Value2 = clientContact.PurchaserPhone;
|
userSheet.Cells[currentRowIndex, 9].Value2 = clientContact.PurchaserPhone;
|
||||||
userSheet.Cells[currentRowIndex, 10].Value2 = clientContact.Address;
|
userSheet.Cells[currentRowIndex, 10].Value2 = clientContact.Address;
|
||||||
userSheet.Cells[currentRowIndex, 11].Value2 = productSalesDetail.ProductNameEN;
|
userSheet.Cells[currentRowIndex, 11].Value2 = productSalesDetail.ProductNameEN;
|
||||||
|
userSheet.Cells[currentRowIndex, 11].NumberFormat = "@";
|
||||||
|
|
||||||
// 计算每月的数量和金额
|
// 计算每月的数量和金额
|
||||||
int monthCol = yearColIndex;
|
int monthCol = yearColIndex;
|
||||||
@ -640,8 +659,8 @@ namespace KellyReport_D.Utils
|
|||||||
userSheet.Cells[3, startCol + 37].Value2 = "總金額";
|
userSheet.Cells[3, startCol + 37].Value2 = "總金額";
|
||||||
|
|
||||||
// 设置所有已用单元格居中
|
// 设置所有已用单元格居中
|
||||||
Range usedRange = userSheet.UsedRange;
|
Range headerRange = userSheet.Rows["1:3"];
|
||||||
usedRange.HorizontalAlignment = XlHAlign.xlHAlignCenter;
|
headerRange.HorizontalAlignment = XlHAlign.xlHAlignCenter;
|
||||||
|
|
||||||
return startCol;
|
return startCol;
|
||||||
}
|
}
|
||||||
@ -721,6 +740,8 @@ namespace KellyReport_D.Utils
|
|||||||
{
|
{
|
||||||
int rowCount = rawSalesDetailData.GetLength(0);
|
int rowCount = rawSalesDetailData.GetLength(0);
|
||||||
int colCount = rawSalesDetailData.GetLength(1);
|
int colCount = rawSalesDetailData.GetLength(1);
|
||||||
|
int colProductNameENIndex = rawSalesDetailData[2, 8].ToString() == "英文品名" ? 8 : 9;
|
||||||
|
|
||||||
|
|
||||||
for (int i = 3; i <= rowCount; i++)
|
for (int i = 3; i <= rowCount; i++)
|
||||||
{
|
{
|
||||||
@ -733,13 +754,13 @@ namespace KellyReport_D.Utils
|
|||||||
InvoiceDate = ResolveExcelDate(rawSalesDetailData[i, 5]),
|
InvoiceDate = ResolveExcelDate(rawSalesDetailData[i, 5]),
|
||||||
InvoiceNumber = rawSalesDetailData[i, 6]?.ToString() ?? "",
|
InvoiceNumber = rawSalesDetailData[i, 6]?.ToString() ?? "",
|
||||||
ClientName = rawSalesDetailData[i, 7]?.ToString() ?? "",
|
ClientName = rawSalesDetailData[i, 7]?.ToString() ?? "",
|
||||||
ProductNameEN = rawSalesDetailData[i, 8]?.ToString() ?? "",
|
ProductNameEN = rawSalesDetailData[i, colProductNameENIndex]?.ToString() ?? "",
|
||||||
Quantity = rawSalesDetailData[i, 9] != null ? Convert.ToDecimal(rawSalesDetailData[i, 9]) : (decimal?)null,
|
Quantity = rawSalesDetailData[i, 9] != null ? Convert.ToDecimal(rawSalesDetailData[i, colProductNameENIndex + 1]) : (decimal?)null,
|
||||||
PriceWithTax = rawSalesDetailData[i, 10] != null ? Convert.ToDecimal(rawSalesDetailData[i, 10]) : (decimal?)null,
|
PriceWithTax = rawSalesDetailData[i, 10] != null ? Convert.ToDecimal(rawSalesDetailData[i, colProductNameENIndex + 2]) : (decimal?)null,
|
||||||
AmountWithoutTax = rawSalesDetailData[i, 11] != null ? Convert.ToDecimal(rawSalesDetailData[i, 11]) : (decimal?)null,
|
AmountWithoutTax = rawSalesDetailData[i, 11] != null ? Convert.ToDecimal(rawSalesDetailData[i, colProductNameENIndex + 3]) : (decimal?)null,
|
||||||
Tax = rawSalesDetailData[i, 12] != null ? Convert.ToDecimal(rawSalesDetailData[i, 12]) : (decimal?)null,
|
Tax = rawSalesDetailData[i, 12] != null ? Convert.ToDecimal(rawSalesDetailData[i, colProductNameENIndex + 4]) : (decimal?)null,
|
||||||
TotalAmount = rawSalesDetailData[i, 13] != null ? Convert.ToDecimal(rawSalesDetailData[i, 13]) : (decimal?)null,
|
TotalAmount = rawSalesDetailData[i, 13] != null ? Convert.ToDecimal(rawSalesDetailData[i, colProductNameENIndex + 5]) : (decimal?)null,
|
||||||
Remark = rawSalesDetailData[i, 14]?.ToString() ?? "",
|
Remark = rawSalesDetailData[i, colProductNameENIndex + 6]?.ToString() ?? "",
|
||||||
};
|
};
|
||||||
salesDatailList.Add(item);
|
salesDatailList.Add(item);
|
||||||
}
|
}
|
||||||
@ -789,7 +810,7 @@ namespace KellyReport_D.Utils
|
|||||||
// 获取「銷售年度預估」工作表
|
// 获取「銷售年度預估」工作表
|
||||||
ReadSalesForecastData(context);
|
ReadSalesForecastData(context);
|
||||||
// 获取「產品年度預估」工作表
|
// 获取「產品年度預估」工作表
|
||||||
// GenProductForecastData(context);
|
GenProductForecastData(context);
|
||||||
GenDepartmentSummary(context);
|
GenDepartmentSummary(context);
|
||||||
|
|
||||||
GenBussenessSheet(context);
|
GenBussenessSheet(context);
|
||||||
@ -965,6 +986,8 @@ namespace KellyReport_D.Utils
|
|||||||
var app = context.Application;
|
var app = context.Application;
|
||||||
|
|
||||||
var clientContactSheet = app.Worksheets["客戶資料"] as Worksheet;
|
var clientContactSheet = app.Worksheets["客戶資料"] as Worksheet;
|
||||||
|
clientContactSheet.Activate();
|
||||||
|
|
||||||
var clientContactRange = clientContactSheet.UsedRange;
|
var clientContactRange = clientContactSheet.UsedRange;
|
||||||
IList<ClientContact> clientContactList = new List<ClientContact>();
|
IList<ClientContact> clientContactList = new List<ClientContact>();
|
||||||
|
|
||||||
@ -1086,7 +1109,7 @@ namespace KellyReport_D.Utils
|
|||||||
productSheet.Cells[2, insertCol + 1].Value2 = "金額(含稅)";
|
productSheet.Cells[2, insertCol + 1].Value2 = "金額(含稅)";
|
||||||
productSheet.Cells[2, insertCol + 2].Value2 = "金額(未稅)";
|
productSheet.Cells[2, insertCol + 2].Value2 = "金額(未稅)";
|
||||||
productSheet.Cells[2, insertCol + 3].Value2 = "平均單價";
|
productSheet.Cells[2, insertCol + 3].Value2 = "平均單價";
|
||||||
productSheet.Cells[2, insertCol + 4].Value2 = "成長率";
|
productSheet.Cells[2, insertCol + 4].Value2 = "達成率";
|
||||||
var growthRange = productSheet.Range[
|
var growthRange = productSheet.Range[
|
||||||
productSheet.Cells[2, insertCol + 4],
|
productSheet.Cells[2, insertCol + 4],
|
||||||
productSheet.Cells[2, insertCol + 5]
|
productSheet.Cells[2, insertCol + 5]
|
||||||
@ -1147,6 +1170,7 @@ namespace KellyReport_D.Utils
|
|||||||
{
|
{
|
||||||
productSheet.Rows[totalRowCount].Insert();
|
productSheet.Rows[totalRowCount].Insert();
|
||||||
productSheet.Cells[totalRowCount, 1].Value2 = curProductName;
|
productSheet.Cells[totalRowCount, 1].Value2 = curProductName;
|
||||||
|
productSheet.Cells[totalRowCount, 1].NumberFormat = "@";
|
||||||
productRange = productSheet.Cells[totalRowCount, 1];
|
productRange = productSheet.Cells[totalRowCount, 1];
|
||||||
|
|
||||||
totalRowCount += 1;
|
totalRowCount += 1;
|
||||||
@ -1183,6 +1207,19 @@ namespace KellyReport_D.Utils
|
|||||||
|
|
||||||
FormatSheetStyle(productSheet);
|
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)
|
public static void GenClientSummarySheet(ImportContext context)
|
||||||
{
|
{
|
||||||
var app = context.Application;
|
var app = context.Application;
|
||||||
@ -1191,9 +1228,15 @@ namespace KellyReport_D.Utils
|
|||||||
Worksheet clientSheet = CreateSheetIfNotExisted(app, sheetName);
|
Worksheet clientSheet = CreateSheetIfNotExisted(app, sheetName);
|
||||||
clientSheet.Activate();
|
clientSheet.Activate();
|
||||||
|
|
||||||
|
// 准备首行标题
|
||||||
|
clientSheet.Cells[2, 1].Value2 = "客戶名稱";
|
||||||
|
clientSheet.Cells[2, 2].Value2 = "產品名稱";
|
||||||
|
|
||||||
|
// 按年写入数据
|
||||||
context.YearList.ForEach(yearNumber =>
|
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);
|
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
|
var clientSalesList = context.SalesDetails
|
||||||
.Where(x => x.InvoiceDate.HasValue && x.InvoiceDate.Value.Year == yearNumber)
|
.Where(x => x.InvoiceDate.HasValue && x.InvoiceDate.Value.Year == yearNumber)
|
||||||
.GroupBy(x => x.ClientName)
|
.GroupBy(x => x.ClientName)
|
||||||
@ -1205,9 +1248,11 @@ namespace KellyReport_D.Utils
|
|||||||
Details = grouped.ToList()
|
Details = grouped.ToList()
|
||||||
})
|
})
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
|
// 目标年份列
|
||||||
if (turnOverRange == null)
|
if (turnOverRange == null)
|
||||||
{
|
{
|
||||||
int insertCol = 2;
|
int insertCol = 3;
|
||||||
|
|
||||||
Range insertRange = clientSheet.Columns[$"{GetColumnLetter(insertCol)}:{GetColumnLetter(insertCol + 5)}"];
|
Range insertRange = clientSheet.Columns[$"{GetColumnLetter(insertCol)}:{GetColumnLetter(insertCol + 5)}"];
|
||||||
insertRange.EntireColumn.Insert(XlInsertShiftDirection.xlShiftToRight);
|
insertRange.EntireColumn.Insert(XlInsertShiftDirection.xlShiftToRight);
|
||||||
@ -1253,16 +1298,17 @@ namespace KellyReport_D.Utils
|
|||||||
foreach (var clientSalesGroup in clientSalesList)
|
foreach (var clientSalesGroup in clientSalesList)
|
||||||
{
|
{
|
||||||
var curClientName = clientSalesGroup.ClientName;
|
var curClientName = clientSalesGroup.ClientName;
|
||||||
// look for the Client row
|
|
||||||
// if not exists then create a new row
|
var clientProductSalesGrouped = clientSalesGroup.Details.GroupBy(x => x.ProductNameEN).Select(grouped => new ImportContext.GroupedSalesDetailModel()
|
||||||
Range clientRange = clientSheet.UsedRange.Find(
|
{
|
||||||
What: curClientName,
|
ClientName = curClientName,
|
||||||
LookIn: XlFindLookIn.xlValues,
|
ProductNameEN = grouped.Key,
|
||||||
LookAt: XlLookAt.xlWhole,
|
Quantity = grouped.Sum(x => x.Quantity ?? 0),
|
||||||
SearchOrder: XlSearchOrder.xlByRows,
|
TotalAmount = grouped.Sum(x => x.TotalAmount ?? 0),
|
||||||
SearchDirection: XlSearchDirection.xlNext,
|
Details = grouped.ToList()
|
||||||
MatchCase: false
|
}).ToList();
|
||||||
);
|
// 查找是否已经存在的客户,存在则直接写入, 否则创建新行
|
||||||
|
Range clientRange = clientSheet.UsedRange.Find(What: EscapeExcelFindValue(curClientName));
|
||||||
|
|
||||||
if (clientRange == null)
|
if (clientRange == null)
|
||||||
{
|
{
|
||||||
@ -1273,18 +1319,97 @@ namespace KellyReport_D.Utils
|
|||||||
totalRowCount += 1;
|
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;
|
foreach (var clientProductSales in clientProductSalesGrouped)
|
||||||
clientSheet.Cells[curRowIndex, startColIndex + 1].Value2 = clientSalesGroup.TotalAmount;
|
{
|
||||||
clientSheet.Cells[curRowIndex, startColIndex + 2].formula = $"={amountColLetter}{curRowIndex}/1.13";
|
Range clientProductNameCells = clientSheet.Range[
|
||||||
clientSheet.Cells[curRowIndex, startColIndex + 3].formula = $"={amountColLetter}{curRowIndex}/${quantityColLetter}{curRowIndex}";
|
clientSheet.Cells[clientSalesRows.Row, 2],
|
||||||
|
clientSheet.Cells[endRowIndex, 2]
|
||||||
|
];
|
||||||
|
|
||||||
clientSheet.Cells[curRowIndex, startColIndex + 4].formula = $"={quantityColLetter}{curRowIndex}/${prevQuantityColLetter}{curRowIndex}";
|
var targetProduct = clientProductNameCells.Find(What: clientProductSales.ProductNameEN);
|
||||||
clientSheet.Cells[curRowIndex, startColIndex + 5].formula = $"={amountColLetter}{curRowIndex}/${prevAmountColLetter}{curRowIndex}";
|
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%";
|
endRowIndex++;
|
||||||
clientSheet.Cells[curRowIndex, startColIndex + 5].NumberFormat = "0.00%";
|
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 = "總計";
|
clientSheet.Cells[totalRowCount, 1].Value2 = "總計";
|
||||||
@ -1411,84 +1536,109 @@ namespace KellyReport_D.Utils
|
|||||||
FormatSheetStyle(deptSheet);
|
FormatSheetStyle(deptSheet);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* public static void GenProductForecastData(GenForecaseContext context)
|
public static void ReadProductData(GenForecaseContext context)
|
||||||
{
|
{
|
||||||
var app = context.Application;
|
var app = context.Application;
|
||||||
|
|
||||||
|
var productDataSheet = app.Worksheets["產品資料"] as Worksheet;
|
||||||
|
productDataSheet.Activate();
|
||||||
|
|
||||||
|
var productRange = productDataSheet.UsedRange;
|
||||||
|
IList<ProductForecastInput> productList = new List<ProductForecastInput>();
|
||||||
|
|
||||||
|
// 第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 = $"產品年度預估";
|
string sheetName = $"產品年度預估";
|
||||||
Worksheet productSheet = CreateSheetIfNotExisted(app, sheetName);
|
Worksheet productSheet = CreateSheetIfNotExisted(app, sheetName);
|
||||||
productSheet.Activate();
|
productSheet.Activate();
|
||||||
|
|
||||||
var yearList = context.SalesForecastList.Select(x => x.Year).Distinct().ToList();
|
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);
|
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)
|
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();
|
||||||
}
|
}
|
||||||
|
|
||||||
*//*
|
productSheet.Cells[1, estimateColIndex].Value2 = $"{yearNumber}-Estimate";
|
||||||
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[2, insertCol].Value2 = "數量";
|
productSheet.Cells[2, estimateColIndex].Value2 = "數量";
|
||||||
productSheet.Cells[2, insertCol + 1].Value2 = "金額(含稅)";
|
productSheet.Cells[2, estimateColIndex + 1].Value2 = "金額(含稅)";
|
||||||
productSheet.Cells[2, insertCol + 2].Value2 = "金額(未稅)";
|
productSheet.Cells[2, estimateColIndex + 2].Value2 = "金額(未稅)";
|
||||||
productSheet.Cells[2, insertCol + 3].Value2 = "平均單價";
|
productSheet.Cells[2, estimateColIndex + 3].Value2 = "平均單價";
|
||||||
productSheet.Cells[2, insertCol + 4].Value2 = "成長率";
|
productSheet.Cells[2, estimateColIndex + 4].Value2 = "成長率";
|
||||||
var growthRange = productSheet.Range[
|
var growthRange = productSheet.Range[
|
||||||
productSheet.Cells[2, insertCol + 4],
|
productSheet.Cells[2, estimateColIndex + 4],
|
||||||
productSheet.Cells[2, insertCol + 5]
|
productSheet.Cells[2, estimateColIndex + 5]
|
||||||
];
|
];
|
||||||
growthRange.Merge();
|
growthRange.Merge();
|
||||||
|
|
||||||
estimateRange = productSheet.Range[
|
estimateRange = productSheet.Range[
|
||||||
productSheet.Cells[1, insertCol],
|
productSheet.Cells[1, estimateColIndex],
|
||||||
productSheet.Cells[1, insertCol + 5]
|
productSheet.Cells[1, estimateColIndex + 5]
|
||||||
];
|
];
|
||||||
estimateRange.Merge();
|
estimateRange.Merge();
|
||||||
|
|
||||||
var productSalesList = context.SalesForecastList
|
// 当前的汇总行
|
||||||
.Where(x => x..HasValue && x.InvoiceDate.Value.Year == yearNumber)
|
Range totalRange = productSheet.UsedRange.Find(What: $"總計", LookIn: XlFindLookIn.xlValues, LookAt: XlLookAt.xlWhole, SearchOrder: XlSearchOrder.xlByRows, SearchDirection: XlSearchDirection.xlNext, MatchCase: false);
|
||||||
.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 = clientSheet.UsedRange.Find(What: $"總計", LookIn: XlFindLookIn.xlValues, LookAt: XlLookAt.xlWhole, SearchOrder: XlSearchOrder.xlByRows, SearchDirection: XlSearchDirection.xlNext, MatchCase: false);
|
int totalRowCount = productSheet.UsedRange.Rows.Count + 1;
|
||||||
|
|
||||||
int totalRowCount = clientSheet.UsedRange.Rows.Count + 1;
|
|
||||||
if (totalRange != null)
|
if (totalRange != null)
|
||||||
{
|
{
|
||||||
totalRowCount = totalRange.Row;
|
totalRowCount = totalRange.Row;
|
||||||
}
|
}
|
||||||
|
|
||||||
int startColIndex = turnOverRange.Column;
|
int startColIndex = estimateColIndex;
|
||||||
var quantityColLetter = GetColumnLetter(startColIndex);
|
var quantityColLetter = GetColumnLetter(startColIndex);
|
||||||
var amountColLetter = GetColumnLetter(startColIndex + 1);
|
var amountColLetter = GetColumnLetter(startColIndex + 1);
|
||||||
var amountNoTaxColLetter = GetColumnLetter(startColIndex + 2);
|
var amountNoTaxColLetter = GetColumnLetter(startColIndex + 2);
|
||||||
|
|
||||||
|
// 上一年的销售
|
||||||
var prevQuantityColLetter = GetColumnLetter(startColIndex + 6);
|
var prevQuantityColLetter = GetColumnLetter(startColIndex + 6);
|
||||||
var prevAmountColLetter = GetColumnLetter(startColIndex + 7);
|
var prevAmountColLetter = GetColumnLetter(startColIndex + 7);
|
||||||
var prevAmountNoTaxColLetter = GetColumnLetter(startColIndex + 8);
|
var prevAmountNoTaxColLetter = GetColumnLetter(startColIndex + 8);
|
||||||
|
Range lastYearEstimateRange = productSheet.UsedRange.Find(What: $"{yearNumber - 1}-Turnover", LookIn: XlFindLookIn.xlValues, LookAt: XlLookAt.xlWhole, SearchOrder: XlSearchOrder.xlByRows, SearchDirection: XlSearchDirection.xlNext, MatchCase: false);
|
||||||
foreach (var productSalesSummary in productSalesList)
|
if (lastYearEstimateRange != null)
|
||||||
{
|
{
|
||||||
var curProductName = productSalesSummary.ProductNameEN;
|
prevQuantityColLetter = GetColumnLetter(lastYearEstimateRange.Column);
|
||||||
// look for the product row
|
prevAmountColLetter = GetColumnLetter(lastYearEstimateRange.Column + 1);
|
||||||
// if not exists then create a new row
|
prevAmountNoTaxColLetter = GetColumnLetter(lastYearEstimateRange.Column + 2);
|
||||||
Range productRange = clientSheet.UsedRange.Find(
|
}
|
||||||
|
|
||||||
|
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,
|
What: curProductName,
|
||||||
LookIn: XlFindLookIn.xlValues,
|
LookIn: XlFindLookIn.xlValues,
|
||||||
LookAt: XlLookAt.xlWhole,
|
LookAt: XlLookAt.xlWhole,
|
||||||
@ -1499,44 +1649,45 @@ namespace KellyReport_D.Utils
|
|||||||
|
|
||||||
if (productRange == null)
|
if (productRange == null)
|
||||||
{
|
{
|
||||||
clientSheet.Rows[totalRowCount].Insert();
|
// 创建新的产品预算行
|
||||||
clientSheet.Cells[totalRowCount, 1].Value2 = curProductName;
|
productSheet.Rows[totalRowCount].Insert();
|
||||||
productRange = clientSheet.Cells[totalRowCount, 1];
|
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;
|
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 = "總計";
|
productSheet.Cells[totalRowCount, 1].Value2 = "總計";
|
||||||
clientSheet.Cells[totalRowCount, startColIndex].formula = $"=SUM({quantityColLetter}5:{quantityColLetter}{totalRowCount - 1})";
|
productSheet.Cells[totalRowCount, startColIndex].formula = $"=SUM({quantityColLetter}5:{quantityColLetter}{totalRowCount - 1})";
|
||||||
clientSheet.Cells[totalRowCount, startColIndex + 1].formula = $"=SUM({amountColLetter}5:{amountColLetter}{totalRowCount - 1})";
|
productSheet.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, startColIndex + 2].formula = $"=SUM({amountNoTaxColLetter}5:{amountNoTaxColLetter}{totalRowCount - 1})";
|
||||||
|
|
||||||
clientSheet.Cells[totalRowCount + 1, 1].Value2 = "備註";
|
productSheet.Cells[totalRowCount + 1, 1].Value2 = "備註";
|
||||||
clientSheet.Cells[totalRowCount + 1, startColIndex].formula = $"={quantityColLetter}{totalRowCount}/{prevQuantityColLetter}{totalRowCount}";
|
productSheet.Cells[totalRowCount + 1, startColIndex].formula = $"={quantityColLetter}{totalRowCount}/{prevQuantityColLetter}{totalRowCount}";
|
||||||
clientSheet.Cells[totalRowCount + 1, startColIndex + 1].formula = $"={amountColLetter}{totalRowCount}/{prevAmountColLetter}{totalRowCount}";
|
productSheet.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, startColIndex + 2].formula = $"={amountNoTaxColLetter}{totalRowCount}/{prevAmountNoTaxColLetter}{totalRowCount}";
|
||||||
|
|
||||||
clientSheet.Cells[totalRowCount + 1, startColIndex].NumberFormat = "0.00%";
|
productSheet.Cells[totalRowCount + 1, startColIndex].NumberFormat = "0.00%";
|
||||||
clientSheet.Cells[totalRowCount + 1, startColIndex + 1].NumberFormat = "0.00%";
|
productSheet.Cells[totalRowCount + 1, startColIndex + 1].NumberFormat = "0.00%";
|
||||||
clientSheet.Cells[totalRowCount + 1, startColIndex + 2].NumberFormat = "0.00%";
|
productSheet.Cells[totalRowCount + 1, startColIndex + 2].NumberFormat = "0.00%";
|
||||||
});
|
|
||||||
FormatSheetStyle(clientSheet);
|
FormatSheetStyle(productSheet);
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
public static void UpdateDeptartmentSummary(ImportContext context)
|
public static void UpdateDeptartmentSummary(ImportContext context)
|
||||||
{
|
{
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user