为什么Excel公式没有公式化?
Why is the Excel formula not formulating?
我正在使用 EPPlus 创建点差sheet。我正在尝试使用以下代码获取公式来计算值的总和:
using (var totalOccurrencesCell = priceComplianceWorksheet.Cells[rowToPopulate, 2])
{
totalOccurrencesCell.Style.Font.Size = DATA_FONT_SIZE;
totalOccurrencesCell.Style.Numberformat.Format = NUMBER_FORMAT_THOUSANDS;
if (rowToPopulate <= SUMMARY_HEADING_ROW + 1)
{
totalOccurrencesCell.Value = "0";
}
else
{
//totalOccurrencesCell.Formula = string.Format("SUM(B5:B{0})", rowToPopulate - 1);
// TODO: Comment out or remove below after finding out why the above is not working
totalOccurrencesCell.Formula = "SUM(B5:B19)";
totalOccurrencesCell.Calculate();
}
}
我认为正确的是应用于该单元格,如此处所示,即“=SUM(B5:B19)”:
那么为什么结果是“0”? C 列也是如此,D 列也出于某种原因被猛烈地破坏了。
此类似代码 在 sheet 的其他地方工作:
using (var totalVarianceCell = priceComplianceWorksheet.Cells[rowToPopulate, DETAIL_TOTALVARIANCE_COL])
{
totalVarianceCell.Style.Font.Size = DATA_FONT_SIZE;
totalVarianceCell.Style.Numberformat.Format = NUMBER_FORMAT_CURRENCY;
totalVarianceCell.Formula = string.Format("SUM(J{0}:J{1})", _firstDetailDataRow, rowToPopulate - 1);
totalVarianceCell.Calculate();
}
它对列 J (10) 的适当范围内的值求和,当单击 "sum" 单元格时,它显示“=SUM(J23:J39)”作为那里的值。
为什么它在一种情况下有效,但在其他情况下却失败了?
注意:我像这样填充单元格("total" 是一个整数):
totalOccurrencesCell.Value = total.ToString("N0", CultureInfo.CurrentCulture);
更新
这很不雅而且有点令人失望,但至少到现在为止,我必须 "brute force it" 这样:
totalOccurrencesCell.Value = SumCellVals(2, 5, rowToPopulate - 1);
. . .
private string SumCellVals(int colNum, int firstRow, int lastRow)
{
double runningTotal = 0.0;
double currentVal;
for (int i = firstRow; i <= lastRow; i++)
{
using (var taterTotCell = priceComplianceWorksheet.Cells[i, colNum])
{
currentVal = Convert.ToDouble(taterTotCell.Value);
runningTotal = runningTotal + currentVal;
}
}
return runningTotal.ToString();
}
该行为的线索在您问题的这句话中:
NOTE: I am populating the cells like so ("total" is an int):
totalOccurrencesCell.Value = total.ToString("N0", CultureInfo.CurrentCulture);
在将数值分配给单元格的值 属性 之前,无需将数值转换为字符串。
我可以通过 运行 这个 MCVE:
重现你所看到的
static void test4()
{
var fs = new System.IO.FileInfo(@"c:\temp\test4.xlsx");
if (fs.Exists) fs.Delete();
using (ExcelPackage package = new ExcelPackage(fs))
{
ExcelWorksheet worksheet = package.Workbook.Worksheets["Test"];
if (worksheet == null) worksheet = package.Workbook.Worksheets.Add("Test");
var WS = worksheet;
WS.Workbook.CalcMode = ExcelCalcMode.Manual;
// strings with .
WS.Cells[1, 1].Value = "100.0";
WS.Cells[2, 1].Value = "42.1";
using (var sum = WS.Cells[3, 1])
{
sum.Formula = "SUM(A1:A2)";
sum.Calculate();
}
// strings with ,
WS.Cells[1, 2].Value = "100,0";
WS.Cells[2, 2].Value = "42,1";
using (var sum = WS.Cells[3, 2])
{
sum.Formula = "SUM(B1:B2)";
sum.Calculate();
}
// strings with ,
WS.Cells[1, 3].Value = "1,100";
WS.Cells[2, 3].Value = "42";
using (var sum = WS.Cells[3, 3])
{
sum.Formula = "SUM(C1:C2)";
sum.Calculate();
}
// let EPPLUS handle it
WS.Cells[1, 4].Value = 100; // int
WS.Cells[2, 4].Value = 42.1d; // double
using (var sum = WS.Cells[3, 4])
{
sum.Formula = "SUM(D1:D2)";
sum.Calculate();
}
package.Save();
}
}
这是我在 Excel sheet 中得到的结果:
您注意到有些单元格有错误指示器,但有些没有。这很容易被误导。此效果受分隔符设置的影响:
但是在我的测试中,总是计算 D 列,无论我如何更改千位和小数点分隔符,总是计算 SUM。特别是如果您要转换为字符串,使用当前文化并不能保证这会起作用,因为 Excel 中的设置可能已被覆盖。
tl;dr; 不将数字(整数、双精度、浮点数)转换为字符串,而是将它们按原样分配给单元格的值。 EPPLUS 和 Excel 都将处理正确的表示。
我正在使用 EPPlus 创建点差sheet。我正在尝试使用以下代码获取公式来计算值的总和:
using (var totalOccurrencesCell = priceComplianceWorksheet.Cells[rowToPopulate, 2])
{
totalOccurrencesCell.Style.Font.Size = DATA_FONT_SIZE;
totalOccurrencesCell.Style.Numberformat.Format = NUMBER_FORMAT_THOUSANDS;
if (rowToPopulate <= SUMMARY_HEADING_ROW + 1)
{
totalOccurrencesCell.Value = "0";
}
else
{
//totalOccurrencesCell.Formula = string.Format("SUM(B5:B{0})", rowToPopulate - 1);
// TODO: Comment out or remove below after finding out why the above is not working
totalOccurrencesCell.Formula = "SUM(B5:B19)";
totalOccurrencesCell.Calculate();
}
}
我认为正确的是应用于该单元格,如此处所示,即“=SUM(B5:B19)”:
那么为什么结果是“0”? C 列也是如此,D 列也出于某种原因被猛烈地破坏了。
此类似代码 在 sheet 的其他地方工作:
using (var totalVarianceCell = priceComplianceWorksheet.Cells[rowToPopulate, DETAIL_TOTALVARIANCE_COL])
{
totalVarianceCell.Style.Font.Size = DATA_FONT_SIZE;
totalVarianceCell.Style.Numberformat.Format = NUMBER_FORMAT_CURRENCY;
totalVarianceCell.Formula = string.Format("SUM(J{0}:J{1})", _firstDetailDataRow, rowToPopulate - 1);
totalVarianceCell.Calculate();
}
它对列 J (10) 的适当范围内的值求和,当单击 "sum" 单元格时,它显示“=SUM(J23:J39)”作为那里的值。
为什么它在一种情况下有效,但在其他情况下却失败了?
注意:我像这样填充单元格("total" 是一个整数):
totalOccurrencesCell.Value = total.ToString("N0", CultureInfo.CurrentCulture);
更新
这很不雅而且有点令人失望,但至少到现在为止,我必须 "brute force it" 这样:
totalOccurrencesCell.Value = SumCellVals(2, 5, rowToPopulate - 1);
. . .
private string SumCellVals(int colNum, int firstRow, int lastRow)
{
double runningTotal = 0.0;
double currentVal;
for (int i = firstRow; i <= lastRow; i++)
{
using (var taterTotCell = priceComplianceWorksheet.Cells[i, colNum])
{
currentVal = Convert.ToDouble(taterTotCell.Value);
runningTotal = runningTotal + currentVal;
}
}
return runningTotal.ToString();
}
该行为的线索在您问题的这句话中:
NOTE: I am populating the cells like so ("total" is an int):
totalOccurrencesCell.Value = total.ToString("N0", CultureInfo.CurrentCulture);
在将数值分配给单元格的值 属性 之前,无需将数值转换为字符串。
我可以通过 运行 这个 MCVE:
重现你所看到的static void test4()
{
var fs = new System.IO.FileInfo(@"c:\temp\test4.xlsx");
if (fs.Exists) fs.Delete();
using (ExcelPackage package = new ExcelPackage(fs))
{
ExcelWorksheet worksheet = package.Workbook.Worksheets["Test"];
if (worksheet == null) worksheet = package.Workbook.Worksheets.Add("Test");
var WS = worksheet;
WS.Workbook.CalcMode = ExcelCalcMode.Manual;
// strings with .
WS.Cells[1, 1].Value = "100.0";
WS.Cells[2, 1].Value = "42.1";
using (var sum = WS.Cells[3, 1])
{
sum.Formula = "SUM(A1:A2)";
sum.Calculate();
}
// strings with ,
WS.Cells[1, 2].Value = "100,0";
WS.Cells[2, 2].Value = "42,1";
using (var sum = WS.Cells[3, 2])
{
sum.Formula = "SUM(B1:B2)";
sum.Calculate();
}
// strings with ,
WS.Cells[1, 3].Value = "1,100";
WS.Cells[2, 3].Value = "42";
using (var sum = WS.Cells[3, 3])
{
sum.Formula = "SUM(C1:C2)";
sum.Calculate();
}
// let EPPLUS handle it
WS.Cells[1, 4].Value = 100; // int
WS.Cells[2, 4].Value = 42.1d; // double
using (var sum = WS.Cells[3, 4])
{
sum.Formula = "SUM(D1:D2)";
sum.Calculate();
}
package.Save();
}
}
这是我在 Excel sheet 中得到的结果:
您注意到有些单元格有错误指示器,但有些没有。这很容易被误导。此效果受分隔符设置的影响:
但是在我的测试中,总是计算 D 列,无论我如何更改千位和小数点分隔符,总是计算 SUM。特别是如果您要转换为字符串,使用当前文化并不能保证这会起作用,因为 Excel 中的设置可能已被覆盖。
tl;dr; 不将数字(整数、双精度、浮点数)转换为字符串,而是将它们按原样分配给单元格的值。 EPPLUS 和 Excel 都将处理正确的表示。