Quantcast
Channel: EPPlus Issue Tracker Rss Feed
Viewing all articles
Browse latest Browse all 2262

Commented Issue: Shared formulas can be handled better [14523]

$
0
0
To be more specific, in ExcelRangeBase.Set_Value and Set_Formula methods _sharedFormulaID is compared to 0 with greater than (>) operator to determine, if there is a shared formula associated with the cell. I suggest that >= is used instead in both cases, as specification states that "The possible values for this attribute are defined by the W3C XML Schema unsignedInt datatype." -- thus allowing zero as a valid value.

The ExcelRangeBase.SplitFormula(int ix) method internally uses SetSharedFormulaID(int id), expecting that all cells in the shared formula range share that formula. This might not always be the case, as specification states that "A cell is shared only when si is used and t is shared." and "If a master cell of a shared formula range specifies that a particular cell is part of the shared formula range, and that particular cell does not use the si and t attributes to indicate that it is shared, then the particular cell's formula shall override the shared master formula.". I suggest to use something with ReplaceSharedFormulaID(int oldid, int id) semantics to leave independent formulas inside master formula's range intact. There are three calls to SetSharedFormulaID(f.Index) in SplitFormula. All three should better be changed to ReplaceSharedFormulaID(ix,f.Index) in my opinion. Whereas ReplaceSharedFormulaID can be implemented as follows:
internal void ReplaceSharedFormulaID(int oldid, int id)
{
for (int col = _fromCol; col <= _toCol; col++)
for (int row = _fromRow; row <= _toRow; row++)
if (_worksheet.Cell(row, col).SharedFormulaID == oldid)
_worksheet.Cell(row, col).SharedFormulaID = id;
}

The changes suggested are useful in scenarios when some template is prepared in Excel and then populated with data by means of EPPlus. Excel seemingly prefers to start indexing shared formulas from zero. And if a single cell inside shared formula's range is edited manually, Excel doesn't bother with splitting the range -- it rather changes just that particular cell to override the shared formula setting.

Here's how to get error messages and unexpected behavior using EPPlus and Excel Starter 2010 (got it bundled with my laptop):
1) Generate a stupid-simple xlsx
FileInfo myFileInfo = new FileInfo(FilePath);
if (myFileInfo.Exists) myFileInfo.Delete();
using (ExcelPackage package = new ExcelPackage(myFileInfo))
{
var ws = package.Workbook.Worksheets.Add("SHAFTEST");
ws.Cells["B2:D4"].Formula = "A1+1";
ws.Cells["F2:H4"].Formula = "E1+1";
package.Save();
}
2) Open it in Excel, edit G3 to have some different value and save. Excel is likely to start indexing shared formulas from zero.
3) Now change one of the "master" cells via EPPlus:
FileInfo existingFile = new FileInfo(FilePath);
System.Diagnostics.Trace.Assert(existingFile.Exists);
using (ExcelPackage package = new ExcelPackage(existingFile))
{
//package.Workbook.Worksheets["SHAFTEST"].Cells["B2"].Value = 2048;
package.Workbook.Worksheets["SHAFTEST"].Cells["F2"].Value = 2048;
package.Save();
}
4) Now, if only F2 is modified, you'll likely be able to open the modified file in Excel, but your manual change to G3 will be lost, as it was reverted to have shared formula. If B2 is modified, Excel will likely not be able to open the file immediately, but will offer you a recovery option and will likely loose the shared formula in the first block eventually.

It must be clear by now, what happened and why and hence my suggestions, but if a more thorough explanation is necessary, please request.
Comments: What is the status on this one? I'm suffering pretty badly in a project due to shared formulas generating a corrupt xml when trying to add manually added values and removing a formula that is in a shared formula range. It rehydrates the shared formulas but adds in the cells that were in the range, but didn't have a reference to the shared formulas. Hope that makes sense...

Viewing all articles
Browse latest Browse all 2262

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>