public void UpdateFormulasAfterRowShift(FormulaShifter shifter, int currentExternSheetIndex) { for (int i = 0; i < records.Length; i++) { CellValueRecordInterface[] rowCells = records[i]; if (rowCells == null) { continue; } for (int j = 0; j < rowCells.Length; j++) { CellValueRecordInterface cell = rowCells[j]; if (cell is FormulaRecordAggregate) { FormulaRecordAggregate fra = (FormulaRecordAggregate)cell; Ptg[] ptgs = fra.FormulaTokens; // needs clone() inside this getter? Ptg[] ptgs2 = ((FormulaRecordAggregate)cell).FormulaRecord.ParsedExpression; // needs clone() inside this getter? if (shifter.AdjustFormula(ptgs, currentExternSheetIndex)) { fra.SetParsedExpression(ptgs); } } } } }
public void TestExtraStringRecord_bug46213() { FormulaRecord fr = new FormulaRecord(); fr.Value = (2.0); StringRecord sr = new StringRecord(); sr.String = ("NA"); SharedValueManager svm = SharedValueManager.CreateEmpty(); FormulaRecordAggregate fra; try { fra = new FormulaRecordAggregate(fr, sr, svm); } catch (RecordFormatException e) { if ("String record was supplied but formula record flag is not set".Equals(e.Message)) { throw new AssertionException("Identified bug 46213"); } throw e; } TestCases.HSSF.UserModel.RecordInspector.RecordCollector rc = new TestCases.HSSF.UserModel.RecordInspector.RecordCollector(); fra.VisitContainedRecords(rc); Record[] vraRecs = rc.Records; Assert.AreEqual(1, vraRecs.Length); Assert.AreEqual(fr, vraRecs[0]); }
/** * @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); }
public void TestBasic() { FormulaRecord f = new FormulaRecord(); f.SetCachedResultTypeString(); StringRecord s = new StringRecord(); s.String = ("abc"); FormulaRecordAggregate fagg = new FormulaRecordAggregate(f, s, SharedValueManager.CreateEmpty()); Assert.AreEqual("abc", fagg.StringValue); }
/** * 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); } } // 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.Length; i++) { TableRecord tr = _tableRecords[i]; if (tr.IsFirstCell(row, column)) { return(tr); } } for (int i = 0; i < _arrayRecords.Length; i++) { ArrayRecord ar = _arrayRecords[i]; if (ar.IsFirstCell(row, column)) { return(ar); } } return(null); }
/** * @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); }
public void Add(FormulaRecordAggregate agg) { if (_numberOfFormulas == 0) { if (_firstCell.Row != agg.Row || _firstCell.Col != agg.Column) { throw new InvalidOperationException("shared formula coding error"); } } if (_numberOfFormulas >= _frAggs.Length) { throw new Exception("Too many formula records for shared formula group"); } _frAggs[_numberOfFormulas++] = agg; }
public void TestArrayFormulas() { int rownum = 4; int colnum = 4; FormulaRecord fr = new FormulaRecord(); fr.Row=(rownum); fr.Column=((short)colnum); FormulaRecordAggregate agg = new FormulaRecordAggregate(fr, null, SharedValueManager.CreateEmpty()); Ptg[] ptgsForCell = { new ExpPtg(rownum, colnum) }; agg.SetParsedExpression(ptgsForCell); String formula = "SUM(A1:A3*B1:B3)"; Ptg[] ptgs = HSSFFormulaParser.Parse(formula, null, FormulaType.ARRAY, 0); agg.SetArrayFormula(new CellRangeAddress(rownum, rownum, colnum, colnum), ptgs); Assert.IsTrue(agg.IsPartOfArrayFormula); Assert.AreEqual("E5", agg.GetArrayFormulaRange().FormatAsString()); Ptg[] ptg = agg.FormulaTokens; String fmlaSer = FormulaRenderer.ToFormulaString(null, ptg); Assert.AreEqual(formula, fmlaSer); agg.RemoveArrayFormula(rownum, colnum); Assert.IsFalse(agg.IsPartOfArrayFormula); }