无法将值和公式分配给 excel 单元格(即使以正常的交互方式使用 excel,您也不能这样做),因为结果是未定义的,即如果公式的结果不同于你会在单元格中显示什么值?
由于您想保留公式以供将来重用,您可以使用 Recalculate 方法应用公式,将它们保存到字典中(并且您已经有了类似的东西,不是吗?),然后设置具有当前值的单元格(根据公式计算)。
也许这就是你已经在这里做的,但不是很清楚,因为我不明白 evalResults 是什么。无论如何,我的意思是这样的:
private Dictionary<int,Dictionary<int,string>> formulas = new Dictionary<int,Dictionary<int,string>>(); // this has to be initialized according to your formulas
public void Recalculate()
{
XL.Worksheet worksheet = Globals.ThisAddIn.Application.ActiveSheet;
XL.Range range = worksheet.UsedRange;
for (int iRow = 1; iRow <= arrValue.GetLength(0); iRow++)
{
for (int iCol = 1; iCol <= arrValue.GetLength(1); iCol++)
{
range.Cells[iRow, iCol].Formula = "=" + formulas[iRow][iCol];
range.Cells[iRow, iCol].Value = range.Cells[iRow, iCol].Value;
}
}
}
如果您想将公式保留在 excel 工作簿中而不是内存中(在字典中),一个解决方案可能是有一个隐藏的工作表,您可以在其中将公式存储为字符串(即没有“=”)以避免它们评估和绩效问题。因此,您将拥有与您的代码非常相似的 SetFormulas 和 Recalculate 方法:
public void SetFormulas()
{
XL.Worksheet worksheet = Globals.ThisAddIn.Application.ActiveSheet;
XL.Worksheet formulasWorksheet = Globals.ThisAddIn.Application.ActiveWorkbook.Worksheets["formulas"];
XL.Range range = worksheet.UsedRange;
arrValue = (object[,])range.get_Value(XL.XlRangeValueDataType.xlRangeValueDefault);
for (int iRow = 1; iRow <= arrValue.GetLength(0); iRow++)
{
for (int iCol = 1; iCol <= arrValue.GetLength(1); iCol++)
{
if (range.Cells[iRow, iCol].Formula != null)
{
range.Cells[iRow, iCol].Formula = "=" + kvp.Value.ToString(); // assign underlying formula (kvp is keyValuePair of dictionary) to the cell
formulasWorksheet.Cells[iRow, iCol].Value = kvp.Value.ToString(); // storing the formula here
}
range.Cells[iRow, iCol].Value = evalResults[count].ToString(); // assign value to the cell
count++;
}
}
}
public void Recalculate()
{
XL.Worksheet worksheet = Globals.ThisAddIn.Application.ActiveSheet;
XL.Worksheet formulasWorksheet = Globals.ThisAddIn.Application.ActiveWorkbook.Worksheets["formulas"];
XL.Range range = worksheet.UsedRange;
arrValue = (object[,])range.get_Value(XL.XlRangeValueDataType.xlRangeValueDefault);
for (int iRow = 1; iRow <= arrValue.GetLength(0); iRow++)
{
for (int iCol = 1; iCol <= arrValue.GetLength(1); iCol++)
{
if (!string.IsNullOrEmpty(formulasWorksheet.Cells[iRow, iCol].Text))
{
range.Cells[iRow, iCol].Formula = "=" + formulasWorksheet.Cells[iRow, iCol].Text; // restoring the formula
range.Cells[iRow, iCol].Value = range.Cells[iRow, iCol].Value // replacing the formula with the value
}
}
}
}