Exemple #1
0
        /**
         * Called by the cell value when the cell features are added to the sheet
         */
        public void setCell(int col,
                            int row,
                            ExternalSheet es,
                            WorkbookMethods nt,
                            WorkbookSettings ws)
        {
            // If this is part of an extended cells validation, then do nothing
            // as this will already have been called and parsed when the top left
            // cell was added
            if (hasExtendedCellsValidation)
            {
                return;
            }

            row1    = row;
            row2    = row;
            column1 = col;
            column2 = col;

            formula1 = new FormulaParser(formula1String,
                                         es, nt, ws,
                                         ParseContext.DATA_VALIDATION);
            formula1.parse();

            if (formula2String != null)
            {
                formula2 = new FormulaParser(formula2String,
                                             es, nt, ws,
                                             ParseContext.DATA_VALIDATION);
                formula2.parse();
            }
        }
Exemple #2
0
        /// <summary> Gets the raw bytes for the formula.  This will include the
        /// parsed tokens array.  Used when copying spreadsheets
        ///
        /// </summary>
        /// <returns> the raw record data
        /// </returns>
        /// <exception cref=""> FormulaException
        /// </exception>
        public override sbyte[] getFormulaData()
        {
            // Get the tokens, taking into account the mapping from shared
            // formula specific values into normal values
            FormulaParser fp = new FormulaParser(getTokens(), this, ExternalSheet, NameTable, Sheet.Workbook.Settings);

            fp.parse();
            sbyte[] rpnTokens = fp.Bytes;

            sbyte[] data = new sbyte[rpnTokens.Length + 22];

            // Set the standard info for this cell
            IntegerHelper.getTwoBytes(Row, data, 0);
            IntegerHelper.getTwoBytes(Column, data, 2);
            IntegerHelper.getTwoBytes(XFIndex, data, 4);
            DoubleHelper.getIEEEBytes(Value, data, 6);

            // Now copy in the parsed tokens
            Array.Copy(rpnTokens, 0, data, 22, rpnTokens.Length);
            IntegerHelper.getTwoBytes(rpnTokens.Length, data, 20);

            // Lop off the standard information
            sbyte[] d = new sbyte[data.Length - 6];
            Array.Copy(data, 6, d, 0, data.Length - 6);

            return(d);
        }
 /**
  * This formula was copied from a formula already present in the writable
  * workbook.  Requires special handling to sort out the cell references
  *
  * @param ws the workbook settings
  * @param es the external sheet
  * @param nt the name table
  */
 private void initializeCopiedFormula(WorkbookSettings ws,
                                      ExternalSheet es, WorkbookMethods nt)
 {
     try
     {
         parser = new FormulaParser(formulaBytes, this, es, nt, ws);
         parser.parse();
         parser.adjustRelativeCellReferences
             (getColumn() - copiedFrom.getColumn(),
             getRow() - copiedFrom.getRow());
         formulaString = parser.getFormula();
         formulaBytes  = parser.getBytes();
     }
     catch (FormulaException e)
     {
         try
         {
             // try again, with an error formula
             formulaToParse = "ERROR(1)";
             parser         = new FormulaParser(formulaToParse, es, nt, ws);
             parser.parse();
             formulaString = parser.getFormula();
             formulaBytes  = parser.getBytes();
         }
         catch (FormulaException e2)
         {
             // fail silently
             //logger.error(string.Empty, e2);
         }
     }
 }
        /**
         * Gets the raw bytes for the formula.  This will include the
         * parsed tokens array.  Used when copying spreadsheets
         *
         * @return the raw record data
         * @exception FormulaException
         */
        public override byte[] getFormulaData()
        {
            if (!getSheet().getWorkbookBof().isBiff8())
            {
                throw new FormulaException(FormulaException.BIFF8_SUPPORTED);
            }

            // Get the tokens, taking into account the mapping from shared
            // formula specific values into normal values
            FormulaParser fp = new FormulaParser
                                   (getTokens(), this,
                                   getExternalSheet(), getNameTable(),
                                   getSheet().getWorkbook().getSettings());

            fp.parse();
            byte[] rpnTokens = fp.getBytes();

            byte[] data = new byte[rpnTokens.Length + 22];

            // Set the standard info for this cell
            IntegerHelper.getTwoBytes(getRow(), data, 0);
            IntegerHelper.getTwoBytes(getColumn(), data, 2);
            IntegerHelper.getTwoBytes(getXFIndex(), data, 4);
            DoubleHelper.getIEEEBytes(value, data, 6);

            // Now copy in the parsed tokens
            System.Array.Copy(rpnTokens, 0, data, 22, rpnTokens.Length);
            IntegerHelper.getTwoBytes(rpnTokens.Length, data, 20);

            // Lop off the standard information
            byte[] d = new byte[data.Length - 6];
            System.Array.Copy(data, 6, d, 0, data.Length - 6);

            return(d);
        }
        /**
         * If this formula was on an imported sheet, check that
         * cell references to another sheet are warned appropriately
         *
         * @return TRUE if this formula was able to be imported, FALSE otherwise
         */
        public bool handleImportedCellReferences(ExternalSheet es,
                                                 WorkbookMethods mt,
                                                 WorkbookSettings ws)
        {
            try
            {
                if (parser == null)
                {
                    byte[] formulaData  = formula.getFormulaData();
                    byte[] formulaBytes = new byte[formulaData.Length - 16];
                    System.Array.Copy(formulaData, 16,
                                      formulaBytes, 0, formulaBytes.Length);
                    parser = new FormulaParser(formulaBytes,
                                               this,
                                               es, mt, ws);
                    parser.parse();
                }

                return(parser.handleImportedCellReferences());
            }
            catch (FormulaException e)
            {
                //logger.warn("cannot import formula:  " + e.Message);
                return(false);
            }
        }
        /**
         * Called when a row is inserted on the specified sheet.  Notifies all
         * RCIR cells of this change. The default implementation here does nothing
         *
         * @param s the sheet on which the row was removed
         * @param sheetIndex the sheet index on which the column was removed
         * @param row the column number which was removed
         */
        public override void rowRemoved(Sheet s, int sheetIndex, int row)
        {
            try
            {
                if (parser == null)
                {
                    byte[] formulaData  = formula.getFormulaData();
                    byte[] formulaBytes = new byte[formulaData.Length - 16];
                    System.Array.Copy(formulaData, 16,
                                      formulaBytes, 0, formulaBytes.Length);
                    parser = new FormulaParser(formulaBytes,
                                               this,
                                               getSheet().getWorkbook(),
                                               getSheet().getWorkbook(),
                                               getSheet().getWorkbookSettings());
                    parser.parse();
                }

                parser.rowRemoved(sheetIndex, row, s == getSheet());
            }
            catch (FormulaException e)
            {
                //logger.warn("cannot remove row within formula:  " + e.Message);
            }
        }
        /**
         * string formula specific exception handling.  Can't really create
         * a formula (as it will look for a cell of that name, so just
         * create a STRING record containing the contents
         *
         * @return the bodged data
         */
        public override byte[] handleFormulaException()
        {
            byte[] expressiondata = null;
            byte[] celldata       = base.getCellData();

            // Generate an appropriate dummy formula
            WritableWorkbookImpl w      = getSheet().getWorkbook();
            FormulaParser        parser = new FormulaParser("\"" + getContents() + "\"", w, w,
                                                            w.getSettings());

            // Get the bytes for the dummy formula
            try
            {
                parser.parse();
            }
            catch (FormulaException e2)
            {
                //logger.warn(e2.Message);
                parser = new FormulaParser("\"ERROR\"", w, w, w.getSettings());
                try
                {
                    parser.parse();
                }
                catch (FormulaException e3)
                {
                    Assert.verify(false);
                }
            }
            byte[] formulaBytes = parser.getBytes();
            expressiondata = new byte[formulaBytes.Length + 16];
            IntegerHelper.getTwoBytes(formulaBytes.Length, expressiondata, 14);
            System.Array.Copy(formulaBytes, 0, expressiondata, 16,
                              formulaBytes.Length);

            // Set the recalculate on load bit
            expressiondata[8] |= 0x02;

            byte[] data = new byte[celldata.Length +
                                   expressiondata.Length];
            System.Array.Copy(celldata, 0, data, 0, celldata.Length);
            System.Array.Copy(expressiondata, 0, data,
                              celldata.Length, expressiondata.Length);

            // Set the type bits to indicate a string formula
            data[6] = 0;
            unchecked
            {
                data[12] = (byte)-1;
                data[13] = (byte)-1;
            }

            return(data);
        }
        /**
         * Gets the formula as an excel string
         *
         * @return the formula as an excel string
         * @exception FormulaException
         */
        public string getFormula()
        {
            if (formulaString == null)
            {
                FormulaParser fp = new FormulaParser
                                       (tokens, this, externalSheet, nameTable,
                                       getSheet().getWorkbook().getSettings());
                fp.parse();
                formulaString = fp.getFormula();
            }

            return(formulaString);
        }
        /**
         * Gets the formula as an excel string
         *
         * @return the formula as an excel string
         * @exception FormulaException
         */
        public string getFormula()
        {
            if (formulaString == null)
            {
                byte[] tokens = new byte[data.Length - 22];
                System.Array.Copy(data, 22, tokens, 0, tokens.Length);
                FormulaParser fp = new FormulaParser
                                       (tokens, this, externalSheet, nameTable,
                                       getSheet().getWorkbook().getSettings());
                fp.parse();
                formulaString = fp.getFormula();
            }

            return(formulaString);
        }
        /**
         * Gets the formula as an excel string
         *
         * @return the formula as an excel string
         * @exception FormulaException
         */
        public string getFormula()
        {
            // Note that the standard information was lopped off by the NumberFormula
            // record when creating this formula
            if (formulaString == null)
            {
                byte[] tokens = new byte[data.Length - 16];
                System.Array.Copy(data, 16, tokens, 0, tokens.Length);
                FormulaParser fp = new FormulaParser
                                       (tokens, this, externalSheet, nameTable,
                                       getSheet().getWorkbook().getSettings());
                fp.parse();
                formulaString = fp.getFormula();
            }

            return(formulaString);
        }
        /**
         * Initializes the string and the formula bytes.  In order to get
         * access to the workbook settings, the object is not initialized until
         * it is added to the sheet
         *
         * @param ws the workbook settings
         * @param es the external sheet
         * @param nt the name table
         */
        private void initialize(WorkbookSettings ws, ExternalSheet es,
                                WorkbookMethods nt)
        {
            if (copiedFrom != null)
            {
                initializeCopiedFormula(ws, es, nt);
                return;
            }

            parser = new FormulaParser(formulaToParse, es, nt, ws);

            try
            {
                parser.parse();
                formulaString = parser.getFormula();
                formulaBytes  = parser.getBytes();
            }
            catch (FormulaException e)
            {
                //logger.warn(e.Message + " when parsing formula " + formulaToParse + " in cell " +
                //   getSheet().getName() + "!" +
                //     CellReferenceHelper.getCellReference(getColumn(), getRow()));

                try
                {
                    // try again, with an error formula
                    formulaToParse = "ERROR(1)";
                    parser         = new FormulaParser(formulaToParse, es, nt, ws);
                    parser.parse();
                    formulaString = parser.getFormula();
                    formulaBytes  = parser.getBytes();
                }
                catch (FormulaException e2)
                {
                    // fail silently
                    //logger.error(string.Empty, e2);
                }
            }
        }
Exemple #12
0
        /**
         * Error formula specific exception handling.  Can't really create
         * a formula (as it will look for a cell of that name, so just
         * create a STRING record containing the contents
         *
         * @return the bodged data
         */
        public override byte[] handleFormulaException()
        {
            byte[] expressiondata = null;
            byte[] celldata       = base.getCellData();

            // Generate an appropriate dummy formula
            WritableWorkbookImpl w      = getSheet().getWorkbook();
            FormulaParser        parser = new FormulaParser(getValue().ToString(), w, w, w.getSettings());

            // Get the bytes for the dummy formula
            try
            {
                parser.parse();
            }
            catch (FormulaException e2)
            {
                //logger.warn(e2.Message);
            }
            byte[] formulaBytes = parser.getBytes();
            expressiondata = new byte[formulaBytes.Length + 16];
            IntegerHelper.getTwoBytes(formulaBytes.Length, expressiondata, 14);
            System.Array.Copy(formulaBytes, 0, expressiondata, 16,
                              formulaBytes.Length);

            // Set the recalculate on load bit
            expressiondata[8] |= 0x02;

            byte[] data = new byte[celldata.Length +
                                   expressiondata.Length];
            System.Array.Copy(celldata, 0, data, 0, celldata.Length);
            System.Array.Copy(expressiondata, 0, data,
                              celldata.Length, expressiondata.Length);

            // Store the value in the formula
            DoubleHelper.getIEEEBytes(getValue(), data, 6);

            return(data);
        }
Exemple #13
0
        /**
         * Constructor
         */
        public DVParser(byte[] data,
                        ExternalSheet es,
                        WorkbookMethods nt,
                        WorkbookSettings ws)
        {
            Assert.verify(nt != null);

            wasCopied = false;
            int options = IntegerHelper.getInt(data[0], data[1], data[2], data[3]);

            int typeVal = options & 0xf;

            type = DVType.getType(typeVal);

            int errorStyleVal = (options & 0x70) >> 4;

            errorStyle = ErrorStyle.getErrorStyle(errorStyleVal);

            int conditionVal = (options & 0xf00000) >> 20;

            condition = Condition.getCondition(conditionVal);

            stringListGiven   = (options & STRING_LIST_GIVEN_MASK) != 0;
            emptyCellsAllowed = (options & EMPTY_CELLS_ALLOWED_MASK) != 0;
            suppressArrow     = (options & SUPPRESS_ARROW_MASK) != 0;
            showPrompt        = (options & SHOW_PROMPT_MASK) != 0;
            showError         = (options & SHOW_ERROR_MASK) != 0;

            int pos    = 4;
            int length = IntegerHelper.getInt(data[pos], data[pos + 1]);

            if (length > 0 && data[pos + 2] == 0)
            {
                promptTitle = StringHelper.getString(data, length, pos + 3, ws);
                pos        += length + 3;
            }
            else if (length > 0)
            {
                promptTitle = StringHelper.getUnicodeString(data, length, pos + 3);
                pos        += length * 2 + 3;
            }
            else
            {
                pos += 3;
            }

            length = IntegerHelper.getInt(data[pos], data[pos + 1]);
            if (length > 0 && data[pos + 2] == 0)
            {
                errorTitle = StringHelper.getString(data, length, pos + 3, ws);
                pos       += length + 3;
            }
            else if (length > 0)
            {
                errorTitle = StringHelper.getUnicodeString(data, length, pos + 3);
                pos       += length * 2 + 3;
            }
            else
            {
                pos += 3;
            }

            length = IntegerHelper.getInt(data[pos], data[pos + 1]);
            if (length > 0 && data[pos + 2] == 0)
            {
                promptText = StringHelper.getString(data, length, pos + 3, ws);
                pos       += length + 3;
            }
            else if (length > 0)
            {
                promptText = StringHelper.getUnicodeString(data, length, pos + 3);
                pos       += length * 2 + 3;
            }
            else
            {
                pos += 3;
            }

            length = IntegerHelper.getInt(data[pos], data[pos + 1]);
            if (length > 0 && data[pos + 2] == 0)
            {
                errorText = StringHelper.getString(data, length, pos + 3, ws);
                pos      += length + 3;
            }
            else if (length > 0)
            {
                errorText = StringHelper.getUnicodeString(data, length, pos + 3);
                pos      += length * 2 + 3;
            }
            else
            {
                pos += 3;
            }

            int formula1Length = IntegerHelper.getInt(data[pos], data[pos + 1]);

            pos += 4;
            int formula1Pos = pos;

            pos += formula1Length;

            int formula2Length = IntegerHelper.getInt(data[pos], data[pos + 1]);

            pos += 4;
            int formula2Pos = pos;

            pos += formula2Length;

            pos += 2;

            row1 = IntegerHelper.getInt(data[pos], data[pos + 1]);
            pos += 2;

            row2 = IntegerHelper.getInt(data[pos], data[pos + 1]);
            pos += 2;

            column1 = IntegerHelper.getInt(data[pos], data[pos + 1]);
            pos    += 2;

            column2 = IntegerHelper.getInt(data[pos], data[pos + 1]);
            pos    += 2;

            hasExtendedCellsValidation = (row1 == row2 && column1 == column2) ? false : true;

            // Do the formulas
            try
            {
                // First, create a temporary  blank cell for any formula relative
                // references
                EmptyCell tmprt = new EmptyCell(column1, row1);

                if (formula1Length != 0)
                {
                    byte[] tokens = new byte[formula1Length];
                    System.Array.Copy(data, formula1Pos, tokens, 0, formula1Length);
                    formula1 = new FormulaParser(tokens, tmprt, es, nt, ws,
                                                 ParseContext.DATA_VALIDATION);
                    formula1.parse();
                }

                if (formula2Length != 0)
                {
                    byte[] tokens = new byte[formula2Length];
                    System.Array.Copy(data, formula2Pos, tokens, 0, formula2Length);
                    formula2 = new FormulaParser(tokens, tmprt, es, nt, ws,
                                                 ParseContext.DATA_VALIDATION);
                    formula2.parse();
                }
            }
            catch (FormulaException e)
            {
                //logger.warn(e.Message + " for cells " +
                //    CellReferenceHelper.getCellReference(column1,row1) + "-" +
                //    CellReferenceHelper.getCellReference(column2,row2));
            }
        }
Exemple #14
0
        /**
         * Error formula specific exception handling.  Can't really create
         * a formula (as it will look for a cell of that name, so just
         * create a STRING record containing the contents
         *
         * @return the bodged data
         */
        public override byte[] handleFormulaException()
        {
            byte[] expressiondata = null;
            byte[] celldata       = base.getCellData();

            int    errorCode     = getErrorCode();
            string formulaString = null;

            if (errorCode == FormulaErrorCode.DIV0.getCode())
            {
                formulaString = "1/0";
            }
            else if (errorCode == FormulaErrorCode.VALUE.getCode())
            {
                formulaString = "\"\"/0";
            }
            else if (errorCode == FormulaErrorCode.REF.getCode())
            {
                formulaString = "\"#REF!\"";
            }
            else
            {
                formulaString = "\"ERROR\"";
            }

            // Generate an appropriate dummy formula
            WritableWorkbookImpl w      = getSheet().getWorkbook();
            FormulaParser        parser = new FormulaParser(formulaString, w, w,
                                                            w.getSettings());

            // Get the bytes for the dummy formula
            try
            {
                parser.parse();
            }
            catch (FormulaException e2)
            {
                //logger.warn(e2.Message);
            }

            byte[] formulaBytes = parser.getBytes();
            expressiondata = new byte[formulaBytes.Length + 16];
            IntegerHelper.getTwoBytes(formulaBytes.Length, expressiondata, 14);
            System.Array.Copy(formulaBytes, 0, expressiondata, 16, formulaBytes.Length);

            // Set the recalculate on load bit
            expressiondata[8] |= 0x02;

            byte[] data = new byte[celldata.Length + expressiondata.Length];
            System.Array.Copy(celldata, 0, data, 0, celldata.Length);
            System.Array.Copy(expressiondata, 0, data, celldata.Length, expressiondata.Length);

            // Set the type bits to indicate an error
            data[6]  = 2;
            data[12] = (byte)0xff;
            data[13] = (byte)0xff;

            // Set the error code
            data[8] = (byte)errorCode;

            return(data);
        }