private bool CircularReferenceChecker(CellClass cell, List <CellClass> cells) { if (cell.Text == string.Empty) { return(false); } if (cell.Text[0] != '=') { return(false); } ExpressionTree expression = new ExpressionTree(cell.Text.Substring(1)); List <string> variableList = expression.GetVariableNames(); if (cells.Contains(cell)) { return(true); } cells.Add(cell); List <CellClass> cellList = new List <CellClass>(); foreach (string variable in variableList) { cellList.Add(this.GetCellFromIndex(variable)); } foreach (CellClass cellClass in cellList) { if (cellClass != null) { if (cellClass.Text != " " || cellClass.Text != null) { var newCellList = new List <CellClass>(cells); if (this.CircularReferenceChecker(cellClass, newCellList)) { return(true); } } } } return(false); }
/// <summary> /// Function initialize the expression tree /// and set the cell reference for the expression tree. /// </summary> /// <param name="expression"> expression that needs to be evaluated.</param> public void InitializeTree(string expression) { this.expression = new ExpressionTree(expression); this.expression.SetCellForTree(this); }
/// <summary> /// envent to change cell. /// </summary> /// <param name="sender">sender.</param> /// <param name="e">e.</param> private void CellPropertyChanges(object sender, PropertyChangedEventArgs e) { SpreadsheetCell spreadsheet = sender as SpreadsheetCell; Dictionary <int, char> alp = new Dictionary <int, char>(); int count = 0; for (char i = 'A'; i <= 'Z'; i++) { alp[count] = i; count++; } string changeCell = alp[spreadsheet.ColumIndex].ToString() + (spreadsheet.RowIndex + 1).ToString(); if (e.PropertyName == "Text") { if (spreadsheet.Text.StartsWith("=") == false) { spreadsheet.Value = spreadsheet.Text; } else { // if equal to the expreesion which need to cal by expression tree. if (spreadsheet.Text.Length > 3) { string expression = spreadsheet.Text.Substring(1); ExpressionTree tree = new ExpressionTree(expression); List <string> strlist = tree.GetVaribles(expression); foreach (string var in strlist) { SpreadsheetCell cell = this.GetSingleValue(var); if (cell != null) { if (this.GetSingleValue(changeCell) == this.GetSingleValue(var)) { spreadsheet.Value = "!self reference"; } else if (this.GetSingleValue(var).Value != "!self reference") { double value = Convert.ToDouble(this.GetSingleValue(var).Value); tree.SetVariable(var, value); spreadsheet.Value = tree.Evaluate().ToString(); } else { spreadsheet.Value = Convert.ToString(0); } cell.PropertyChanged += spreadsheet.CellPropertyChanged; } else { spreadsheet.Value = "!bad reference"; } } } // if = like B1,A1 just single cell value. else { string name = spreadsheet.Text.Substring(1); SpreadsheetCell cell = this.GetSingleValue(name); // cell will be null if catch FormatException case which return to null,if not, just normall to get value else will be bad reference. if (cell != null) { // if equal self cell value if (this.GetSingleValue(changeCell) == this.GetSingleValue(name)) { spreadsheet.Value = "!self reference"; } // if equal the cell value which is no self reference, else is equal zero. else if (this.GetSingleValue(name).Value != "!self reference") { spreadsheet.Value = this.GetSingleValue(name).Value; } else { spreadsheet.Value = Convert.ToString(0); } cell.PropertyChanged += spreadsheet.CellPropertyChanged; } else { spreadsheet.Value = "!bad reference"; } } } } this.CellPropertyChanged?.Invoke(sender, new PropertyChangedEventArgs("Value")); }
public void TestVariableDefaultZero() { var tree = new ExpressionTree("alpha+beta"); Assert.AreEqual(tree.Variables.Length, 2); }