public void add(FormulaRecordAggregate agg) { if (_numberOfFormulas == 0) { if (_firstCell.getRow() != agg.getRow() || _firstCell.getCol() != agg.getColumn()) { throw new IllegalStateException( "shared formula coding error: " + _firstCell.getCol() + '/' + _firstCell.getRow() + " != " + agg.getColumn() + '/' + agg.getRow()); } } if (_numberOfFormulas >= _frAggs.length) { throw new RuntimeException("Too many formula records for shared formula group"); } _frAggs[_numberOfFormulas++] = agg; }
/** * 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.getFormulaRecord().getFormula().getExpReference(); // 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.getRow(); int column = firstCell.getCol(); if (agg.getRow() != row || agg.getColumn() != column) { // not the first formula cell in the group return null; } if (!_groupsBySharedFormulaRecord.isEmpty()) { SharedFormulaGroup sfg = findFormulaGroupForCell(firstCell); if (null != sfg) { return sfg.getSFR(); } } // 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 (TableRecord tr : _tableRecords) { if (tr.isFirstCell(row, column)) { return tr; } } for (ArrayRecord ar : _arrayRecords) { if (ar.isFirstCell(row, column)) { return ar; } } return null; }