Exemple #1
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);
        }
        /**
         * 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);
        }
Exemple #3
0
 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);
        }
Exemple #5
0
        /**
         * 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();
        }
Exemple #6
0
        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;
        }