/// <summary> /// A helper method to obtain all direct and indirect cells, whose values depends /// on the named cell. /// </summary> /// <param name="name">Named cell</param> /// <returns>Set of all direct and indirect cells whose value depends on "name"</returns> private ISet <string> GetAllDependees(string name) { HashSet <string> AllDependees = new HashSet <string>(); AllDependees.Add(name); if (!Graph.HasDependees(name)) { return(AllDependees); } GetDependeesRecursive(name, AllDependees); return(AllDependees); }
/// <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) { if (!IsValidCellName(name, IsValid)) { throw new InvalidNameException(); } if (!Cells.ContainsKey(name)) { Cells.Add(name, new Cell()); } // Set consisting of variables in formula ISet <string> variables = formula.GetVariables(); object oldVal = Cells[name.ToUpper()].GetContent(); bool hadFormula = Cells[name.ToUpper()].hasFormula; Cells[name.ToUpper()].SetContent(formula); // Remove dependess that aren't there in the formula if (Graph.HasDependees(name)) { foreach (string dependee in Graph.GetDependees(name).ToList()) { if (!variables.Contains(dependee)) { Graph.RemoveDependency(dependee, name); } } } // Add dependees that don't already exist foreach (string variable in variables) { Graph.AddDependency(variable, name); } ISet <string> changedSet = new HashSet <string>(); changedSet = GetAllRelatedDependents(name); // changedSet.Add(name); // if (Graph.HasDependents(name)) // { // foreach (string dependent in Graph.GetDependents(name)) // { // changedSet.Add(dependent); // } // } // To check for Circular Dependency try { GetCellsToRecalculate(changedSet); } catch (CircularException e) { Cells[name.ToUpper()].SetContent(oldVal); Cells[name.ToUpper()].hasFormula = hadFormula; throw e; } return(changedSet); }