/** * @param firstCell as extracted from the {@link ExpPtg} from the cell's formula. * @return never <code>null</code> */ public SharedFormulaRecord LinkSharedFormulaRecord(CellReference firstCell, FormulaRecordAggregate agg) { SharedFormulaGroup result = FindFormulaGroup(GetGroups(), firstCell); result.Add(agg); return(result.SFR); }
/** * Gets the {@link SharedValueRecordBase} record if it should be encoded immediately after the * formula record Contained in the specified {@link FormulaRecordAggregate} agg. Note - the * shared value record always appears after the first formula record in the group. For arrays * and tables the first formula is always the in the top left cell. However, since shared * formula groups can be sparse and/or overlap, the first formula may not actually be in the * top left cell. * * @return the SHRFMLA, TABLE or ARRAY record for the formula cell, if it is the first cell of * a table or array region. <code>null</code> if the formula cell is not shared/array/table, * or if the specified formula is not the the first in the group. */ public SharedValueRecordBase GetRecordForFirstCell(FormulaRecordAggregate agg) { CellReference firstCell = agg.FormulaRecord.Formula.ExpReference; // perhaps this could be optimised by consulting the (somewhat unreliable) isShared flag // and/or distinguishing between tExp and tTbl. if (firstCell == null) { // not a shared/array/table formula return(null); } int row = firstCell.Row; int column = firstCell.Col; if (agg.Row != row || agg.Column != column) { // not the first formula cell in the group return(null); } //SharedFormulaGroup[] groups = GetGroups(); //for (int i = 0; i < groups.Length; i++) //{ // // note - logic for Finding correct shared formula group is slightly // // more complicated since the first cell // SharedFormulaGroup sfg = groups[i]; // if (sfg.IsFirstCell(row, column)) // { // return sfg.SFR; // } //} if (!(_groupsBySharedFormulaRecord.Count == 0)) { SharedFormulaGroup sfg = FindFormulaGroupForCell(firstCell); if (null != sfg) { return(sfg.SFR); } } // Since arrays and tables cannot be sparse (all cells in range participate) // The first cell will be the top left in the range. So we can match the // ARRAY/TABLE record directly. for (int i = 0; i < _tableRecords.Count; i++) { TableRecord tr = _tableRecords[i]; if (tr.IsFirstCell(row, column)) { return(tr); } } foreach (ArrayRecord ar in _arrayRecords) { if (ar.IsFirstCell(row, column)) { return(ar); } } return(null); }
private SharedFormulaGroup[] GetGroups() { if (_groups == null) { SharedFormulaGroup[] groups = new SharedFormulaGroup[_groupsBySharedFormulaRecord.Count]; _groupsBySharedFormulaRecord.Values.CopyTo(groups, 0); Array.Sort(groups, SVGComparator); // make search behaviour more deterministic _groups = groups; } return(_groups); }
/** * @param firstCell as extracted from the {@link ExpPtg} from the cell's formula. * @return never <code>null</code> */ public SharedFormulaRecord LinkSharedFormulaRecord(CellReference firstCell, FormulaRecordAggregate agg) { SharedFormulaGroup result = FindFormulaGroupForCell(firstCell); if (null == result) { throw new RuntimeException("Failed to find a matching shared formula record"); } result.Add(agg); return(result.SFR); }
/** * Converts all {@link FormulaRecord}s handled by <c>sharedFormulaRecord</c> * to plain unshared formulas */ public void Unlink(SharedFormulaRecord sharedFormulaRecord) { SharedFormulaGroup svg = _groupsBySharedFormulaRecord[sharedFormulaRecord]; _groupsBySharedFormulaRecord.Remove(sharedFormulaRecord); _groups = null; // be sure to reset cached value if (svg == null) { throw new InvalidOperationException("Failed to find formulas for shared formula"); } svg.UnlinkSharedFormulas(); }
private static SharedFormulaGroup FindFormulaGroup(SharedFormulaGroup[] groups, CellReference firstCell) { int row = firstCell.Row; int column = firstCell.Col; // Traverse the list of shared formulas and try to find the correct one for us // perhaps this could be optimised to some kind of binary search for (int i = 0; i < groups.Length; i++) { SharedFormulaGroup svg = groups[i]; if (svg.IsFirstCell(row, column)) { return(svg); } } // TODO - fix file "15228.xls" so it opens in Excel after rewriting with POI throw new Exception("Failed to find a matching shared formula record"); }
private SharedFormulaGroup FindFormulaGroupForCell(CellReference cellRef) { if (null == _groupsCache) { _groupsCache = new Dictionary <int, SharedFormulaGroup>(_groupsBySharedFormulaRecord.Count); foreach (SharedFormulaGroup group in _groupsBySharedFormulaRecord.Values) { _groupsCache.Add(GetKeyForCache(group.FirstCell), group); } } int key = GetKeyForCache(cellRef); SharedFormulaGroup sfg = null; if (_groupsCache.ContainsKey(key)) { sfg = _groupsCache[key]; } return(sfg); }
private SharedValueManager(SharedFormulaRecord[] sharedFormulaRecords, CellReference[] firstCells, ArrayRecord[] arrayRecords, TableRecord[] tableRecords) { int nShF = sharedFormulaRecords.Length; if (nShF != firstCells.Length) { throw new ArgumentException("array sizes don't match: " + nShF + "!=" + firstCells.Length + "."); } _arrayRecords = arrayRecords; _tableRecords = tableRecords; Dictionary <SharedFormulaRecord, SharedFormulaGroup> m = new Dictionary <SharedFormulaRecord, SharedFormulaGroup>(nShF * 3 / 2); for (int i = 0; i < nShF; i++) { SharedFormulaRecord sfr = sharedFormulaRecords[i]; m[sfr] = new SharedFormulaGroup(sfr, firstCells[i]); } _groupsBySharedFormulaRecord = m; }