Ejemplo n.º 1
0
        /// <summary>
        /// Used to set the contents of a given cell to a formula
        /// </summary>
        /// <param name="name">Cell's name</param>
        /// <param name="formula">Cell's contents</param>
        /// <returns>a set of all cells affected by the given cell</returns>
        protected override ISet <string> SetCellContents(string name, string text)
        {
            if (name == null || !couldBeAVariable(name))
            {
                throw new InvalidNameException();
            }

            if (text == null)
            {
                throw new ArgumentNullException();
            }

            if (cells.ContainsKey(name))//check to see if the cell used to have some other data in it
            {
                removeDependencies(name);
            }

            if (text != "") //we don't want blank cells in the dictionary
            {
                cells[name] = text;
            }
            valueDictionary[name] = new FormulaError("Can not evaluate a string");

            return(new HashSet <string>(GetCellsToRecalculate(name)));
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Requires that all of the variables in formula are valid cell names.
        ///
        /// If name is null or invalid, throws an InvalidNameException.
        ///
        /// Otherwise, if changing the contents of the named cell to be the formula would cause a
        /// circular dependency, throws a CircularException.
        ///
        /// Otherwise, the contents of the named cell becomes formula. The method returns a Set
        /// consisting of name plus the names of all other cells whose value depends, directly or
        /// indirectly, on the named cell.
        ///
        /// For example, if name is A1, B1 contains A1*2, and C1 contains B1+A1, the set {A1, B1, C1}
        /// is returned.
        /// </summary>
        /// <param name="name">The name of the cell whose contents will be set.</param>
        /// <param name="formula">The desired contents for the cell.</param>
        /// <returns>Returns a set of all cells that now depend on the provided cell.</returns>
        protected override ISet <string> SetCellContents(string name, Formula formula)
        {
            // Add in all of our new dependencies.
            foreach (string s in formula.GetVariables())
            {
                dependencies.AddDependency(name, s);
            }
            // Try and evaluate the formula.
            object value;

            try
            {
                value = formula.Evaluate(EvalLookup);
            }
            // The value will simply be a FormulaError if the formula can't be evaluated.
            catch (FormulaEvaluationException e)
            {
                value = new FormulaError(e.Message);
            }
            // Set the cell contents.
            try
            {
                return(SetCellContentsGeneric(name, new Cell(formula, value)));
            }
            catch (CircularException e)
            {
                foreach (string s in formula.GetVariables())
                {
                    dependencies.RemoveDependency(name, s);
                }
                throw e;
            }
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Requires that all of the variables in formula are valid cell names.
        ///
        /// If name is null or invalid, throws an InvalidNameException.
        ///
        /// Otherwise, if changing the contents of the named cell to be the formula would cause a
        /// circular dependency, throws a CircularException.
        ///
        /// Otherwise, the contents of the named cell becomes formula.  The method returns a
        /// Set consisting of name plus the names of all other cells whose value depends,
        /// directly or indirectly, on the named cell.
        ///
        /// For example, if name is A1, B1 contains A1*2, and C1 contains B1+A1, the
        /// set {A1, B1, C1} is returned.
        /// </summary>
        protected override ISet <string> SetCellContents(string name, Formula formula)
        {
            //Stores dependents incase it is circular
            IEnumerable <string> backup = dg.GetDependents(name);

            //Resets dependency
            dg.ReplaceDependents(name, new HashSet <string>());

            foreach (string itr in formula.GetVariables())
            {
                dg.AddDependency(name, itr);
            }

            HashSet <string> rtn = new HashSet <string>();

            if (sheet.ContainsKey(name))
            {
                object value;
                try
                {
                    value = formula.Evaluate(LookUpDub);
                }
                catch
                {
                    value = new FormulaError();
                }
                sheet[name] = new Cell(formula, value);
            }
            else
            {
                object value;
                try
                {
                    value = formula.Evaluate(LookUpDub);
                }
                catch
                {
                    value = new FormulaError();
                }
                sheet.Add(name, new Cell(formula, value));
            }

            //Check for circular dependency
            try
            {
                foreach (string itr in GetCellsToRecalculate(name))
                {
                    sheet[itr].cellContents = sheet[itr].cellContents;
                }
            }
            catch (CircularException)
            {
                //Revert back if circular
                dg.ReplaceDependents(name, backup);
                throw new CircularException();
            }
            rtn     = new HashSet <string>(GetCellsToRecalculate(name));
            Changed = true;
            return(rtn);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// If name is null or invalid, throws an InvalidNameException.
        ///
        /// Otherwise, returns the value (as opposed to the contents) of the named cell.  The return
        /// value should be either a string, a double, or a FormulaError.
        /// </summary>
        public override object GetCellValue(string name)
        {
            if (name == null || !isValid.IsMatch(name) || !CellNamePattern.IsMatch(name))
            {
                throw new InvalidNameException();
            }
            name = name.ToUpper();
            if (!Cells.ContainsKey(name))
            {
                return("");
            }

            if (Cells[name].Value != null)
            {
                return(Cells[name].Value);
            }

            object result = GetCellContents(name);

            if (result.GetType().Equals(typeof(double)))
            {
                Cells[name].Value = result;
                return(result);
            }
            if (result.GetType().Equals(new Formula().GetType()))
            {
                try
                {
                    result            = ((Formula)result).Evaluate(s => double.Parse(GetCellValue(s).ToString()));
                    Cells[name].Value = result;
                    return(result);
                }
                catch (FormulaEvaluationException)
                {
                    result = new FormulaError("The formula could not be evaluated");
                }
                catch (FormatException)
                {
                    result = new FormulaError("The formula could not be evaluated");
                }
            }
            if (result.Equals(""))
            {
                result = new FormulaError("The formula is referencing an empty cell");
            }
            Cells[name].Value = result;
            return(result);
        }
Ejemplo n.º 5
0
        protected override IList <string> SetCellContents(string name, Formula formula)
        {
            foreach (string var in formula.GetVariables())
            {
                if (!IsValid(var))
                {
                    throw new FormulaFormatException("invalid variable " + var);
                }
            }

            // Try Catch in case of Circular Exception
            try
            {
                // Adding dependencies for the variables within formula to name
                foreach (string var in formula.GetVariables())
                {
                    depGraph.AddDependency(var, name);
                }

                // Our list to return as well as check for CircularException
                List <string> toReturn = GetCellsToRecalculate(name).ToList();

                // Adding as a new Cell and grabbing it's value.
                object value;
                try
                {
                    value = formula.Evaluate(lookup);
                }
                catch (ArgumentException)
                {
                    value = new FormulaError();
                }

                if (!(Cells.ContainsKey(name)))
                {
                    Cells.Add(name, new Cell(name, formula, value));
                }

                // Overwriting the Cell to a formula
                else
                {
                    Cells[name] = new Cell(name, formula, value);
                }

                // Recalculate dependents
                RecalculateDependents(name);

                Changed = true;
                return(toReturn);
            }

            // Resetting dependencies SS is unchanged.
            catch (CircularException)
            {
                foreach (string var in formula.GetVariables())
                {
                    depGraph.RemoveDependency(var, name);
                }

                // Then we throw the Exception.
                throw new CircularException();
            }
        }
Ejemplo n.º 6
0
 /// <summary>
 /// Sets the value of the cell
 /// </summary>
 public void SetValue(FormulaError e)
 {
     Value = new object();
     Value = e;
 }