EPPlus不能正确调用不同工作表上的公式

我一直在使用EPPlus导出一个Excel工作表,logging各种testing的结果,然后做一个基本的总结。 我有这些代码行,运作良好

groupsheet.Cells[3, 5, 3, (25 + (tPts.Count() - 1) * 9) ].Formula = "AVERAGE(E6:E"+(5+ mCount).ToString()+")"; groupsheet.Cells[4, 5, 4, (25 + (tPts.Count() - 1) * 9) ].Formula = "STDEV(E6:E"+(5+ mCount).ToString()+")"; groupsheet.Cells[5, 5, 5, (25 + (tPts.Count() - 1) * 9) ].Formula = "MAX(E6:E"+(5+ mCount).ToString()+")"; 

正如我从EPPlus期待的那样,代码范围。 所以E3得到“=平均值(E6:E8)”(如果mCount是3),F3得到“=平均值(F6:F8)”等到最后(由tPts的长度定义)。 同样,第4行中的所有内容都会获得所需范围的标准偏差,第5行中的所有内容都将获得所需范围的最大值。

我也有一个整体汇总表,logging来自所有单个组表单的数据。 我目前正在通过以下代码复制确切的值。

 summarysheet.Cells[3 + groupCount * 4, 5, 5 + groupCount * 4, (25 + (tPts.Count() - 1) * 9)].Value = groupsheet.Cells[3 , 5, 5 , (25 + (tPts.Count() - 1) * 9)].Value; 

如预期那样工作,将来自个别小组的值放入汇总表的正确位置。 但是,如果每个单元格都包含对单个组工作表(标题为Group1,Group2,Group3 …)上适当单元格的引用,以便汇总表dynamic更改为各个组表单所做的更改。

我的直觉说,正确的做法是通过下面的代码。

 summarysheet.Cells[3 + groupCount * 4, 5, 5 + groupCount * 4, (25 + (tPts.Count() - 1) * 9)].Formula = "Group"+ groupNumKey.ToString() +"!E3"; 

但是,这只是将单元格E3的公式粘贴到每个单元格中。 我不知道如何使公式调用范围类似于它们如何包含在一个工作表中。

非常感谢!

这是我试图用暴力的方法

 // Iterate over each column to put the references in place int currColNum = 5; //Start at 5 (E) string currColName = "E"; int maxColNum = (25 + (tPts.Count() - 1) * 9); // End at the last column while (currColNum <= maxColNum) { currColName = Base26Encode(currColNum); // Finds the excel column name from the row # summarysheet.Cells[3 + groupCount * 4, currColNum].Formula = "Group" + groupNumKey.ToString() + "!" + currColName + "3"; // Grab Average summarysheet.Cells[4 + groupCount * 4, currColNum].Formula = "Group" + groupNumKey.ToString() + "!" + currColName + "4"; // Grab STD summarysheet.Cells[5 + groupCount * 4, currColNum].Formula = "Group" + groupNumKey.ToString() + "!" + currColName + "5"; // Grab Max currColNum++; } 

其中“Base26Encode”是给定1时输出A的代码片段,当给定26时输出Z,当给定27时输出AA等等(将列索引转换为Excel列名称)

如果你想在另一张表格中引用单元格,你似乎有正确的公式,但是你已经编写了!E3代码,所以这个公式将等于“GroupX!E3”,这是有道理的。看起来像所有你需要做的就是改变这个:

 summarysheet.Cells[3 + groupCount * 4, 5, 5 + groupCount * 4, (25 + (tPts.Count() - 1) * 9)].Formula = "Group" + groupNumKey.ToString() +"!E3"; 

对此:

 //Use a variable to save space and avoid repeating the same calculation over and over var row = (25 + (tPts.Count() - 1) * 9); summarysheet.Cells[3 + groupCount * 4, 5, 5 + groupCount * 4, row].Formula = "Group" + groupNumKey.ToString() +"!E" + row; 

让我知道如果我是误解。


回应评论: @Iassac我仍然有一点点麻烦理解你在做什么。 也许发布更多的代码,因为它是有点难以把握没有更多。 如果有帮助的话,这是一个unit testing,我想出了一个unit testing,它允许我在另一个表单中使用一个公式:

 [TestMethod] public void SheetReferenceTest() { //https://stackoverflow.com/questions/47144930 var file = new FileInfo(@"c:\temp\SheetReferenceTest.xlsx"); if (file.Exists) file.Delete(); using (var pck = new ExcelPackage(file)) { var group = 1; var workbook = pck.Workbook; var group1 = workbook.Worksheets.Add($"group{group}"); var summarysheet = workbook.Worksheets.Add("summarysheet"); group1.Cells["A1"].Value = 2; group1.Cells["A2"].Value = 3; group1.Cells["A3"].Value = 6; group1.Cells["A4"].Value = 27; group1.Cells["A5"].Formula = "Average(A1:A4)"; //This shows "=group1!A5" in Excel when the cell is selected summarysheet.Cells["A1"].Formula = $"group{group}!A5"; pck.Save(); } } 

回应编辑

好的,现在我明白你的意思了。 似乎你是正确的,我不能得到excel处理共享string公式。 我不确定这是一个Epplus问题,因为我甚至不知道这是不是excel可以做的事情? 下面是我提出的显示问题的unit testing:

 [TestMethod] public void SheetReferenceTest() { //https://stackoverflow.com/questions/47144930 var file = new FileInfo(@"c:\temp\SheetReferenceTest.xlsx"); if (file.Exists) file.Delete(); using (var pck = new ExcelPackage(file)) { var group = 1; var workbook = pck.Workbook; var group1 = workbook.Worksheets.Add($"group{group}"); var summarysheet = workbook.Worksheets.Add("summarysheet"); var random = new Random(); const int rows = 10; const int cols = 15; for (var r = 0; r < rows; r++) for (var c = 0; c < cols; c++) group1.Cells[r + 1, c + 1].Value = random.Next(100); //This works fine and auto increments the formala to B1:B10, C1:C10, etc. group1.Cells[rows + 1, 1, rows + 1, cols].Formula = $"AVERAGE(A1:A{rows})"; //This does not, it just does group1!A1:A10 for all cells. summarysheet.Cells[rows + 1, 1, rows + 1, cols].Formula = $"AVERAGE(group1!A1:A{rows})"; pck.Save(); } } 

以下是xml在工作表中的样子:

 <row r="11"> <cr="A11" s="0"> <f ref="A11:O11" t="shared" si="1">AVERAGE(A1:A10)</f> </c><cr="B11" s="0"> <ft="shared" si="1"/> </c><cr="C11" s="0"> <ft="shared" si="1"/> </c><cr="D11" s="0"> <ft="shared" si="1"/> </c><cr="E11" s="0"> <ft="shared" si="1"/> </c><cr="F11" s="0"> <ft="shared" si="1"/> </c><cr="G11" s="0"> <ft="shared" si="1"/> </c><cr="H11" s="0"> <ft="shared" si="1"/> </c><cr="I11" s="0"> <ft="shared" si="1"/> </c><cr="J11" s="0"> <ft="shared" si="1"/> </c><cr="K11" s="0"> <ft="shared" si="1"/> </c><cr="L11" s="0"> <ft="shared" si="1"/> </c><cr="M11" s="0"> <ft="shared" si="1"/> </c><cr="N11" s="0"> <ft="shared" si="1"/> </c><cr="O11" s="0"> <ft="shared" si="1"/> </c> </row> 

但对于非工作汇总表:

 <row r="11"> <cr="A11" s="0"> <f ref="A11:O11" t="shared" si="1">AVERAGE(group1!A1:A10)</f> </c><cr="B11" s="0"> <ft="shared" si="1"/> </c><cr="C11" s="0"> <ft="shared" si="1"/> </c><cr="D11" s="0"> <ft="shared" si="1"/> </c><cr="E11" s="0"> <ft="shared" si="1"/> </c><cr="F11" s="0"> <ft="shared" si="1"/> </c><cr="G11" s="0"> <ft="shared" si="1"/> </c><cr="H11" s="0"> <ft="shared" si="1"/> </c><cr="I11" s="0"> <ft="shared" si="1"/> </c><cr="J11" s="0"> <ft="shared" si="1"/> </c><cr="K11" s="0"> <ft="shared" si="1"/> </c><cr="L11" s="0"> <ft="shared" si="1"/> </c><cr="M11" s="0"> <ft="shared" si="1"/> </c><cr="N11" s="0"> <ft="shared" si="1"/> </c><cr="O11" s="0"> <ft="shared" si="1"/> </c> </row>