// Evaluate cell ref by evaluating the cell referred to public override Value Eval(Sheet sheet, int col, int row) { CellAddr ca = raref.Addr(col, row); Cell cell = (this.sheet ?? sheet)[ca]; return(cell == null ? null : cell.Eval(sheet, ca.col, ca.row)); }
public ArrayView MakeArrayView(Sheet sheet, int col, int row) { CellAddr ulCa = ul.Addr(col, row), lrCa = lr.Addr(col, row); ArrayView view = ArrayView.Make(ulCa, lrCa, this.sheet ?? sheet); // Forcing the evaluation of all cells in an array view value. // TODO: Doing this repeatedly, as in ManyDependents.xml, is costly for (int c = 0; c < view.Cols; c++) { for (int r = 0; r < view.Rows; r++) { // Value ignore = view[c, r]; } } return(view); }
private int ParseRow(XmlReader rowreader, Workbook wb, Sheet sheet, int row, IDictionary<string, Cell> cellParsingCache) { /* XMLSS has origin at (1,1) = (A,1) whereas Corecalc internal * representation has origin at (0,0) = (A,1). Hence the col * and row indices are 1 higher in this method. */ int cellCount = 0; int col = 0; XmlReader cellreader = rowreader.ReadSubtree(); while (cellreader.ReadToFollowing("Cell")) { String colindexstr = cellreader.GetAttribute("ss:Index"); String arrayrangestr = cellreader.GetAttribute("ss:ArrayRange"); String formulastr = cellreader.GetAttribute("ss:Formula"); String typestr = ""; String dataval = ""; if (colindexstr != null) { if (!int.TryParse(colindexstr, out col)) { col = 0; // Looks wrong, should be 1? } } else { col++; } cellCount++; // If an array result occupies cells, do not overwrite // the formula with precomputed and cached data from // the XMLSS file. Instead skip the parsing and sheet update. if (sheet[col - 1, row - 1] != null) { continue; } using (XmlReader datareader = cellreader.ReadSubtree()) { if (datareader.ReadToFollowing("Data")) { typestr = datareader.GetAttribute("ss:Type"); datareader.MoveToContent(); dataval = datareader.ReadElementContentAsString(); } } String cellString; if (formulastr != null) { cellString = formulastr; } else { // Anything else than formulas are values. // If XMLSS tells us it is a String we believe it if (typestr == "String") { dataval = "'" + dataval; } cellString = dataval; } // Skip blank cells if (cellString == "") { continue; } Cell cell; if (cellParsingCache.TryGetValue(cellString, out cell)) { // Copy the cell (both for mutable Formula cells and for cell-specific // metadata) and but share any sharable contents. cell = cell.CloneCell(col - 1, row - 1); } else { // Cell contents not seen before: scan, parse and cache cell = Cell.Parse(cellString, wb, col, row); if (cell == null) { Console.WriteLine("BAD: Null cell from \"{0}\"", cellString); } else { cellParsingCache.Add(cellString, cell); } } if (arrayrangestr != null && cell is Formula) { // Array formula string[] split = arrayrangestr.Split(":".ToCharArray()); RARef raref1 = new RARef(split[0]); RARef raref2; if (split.Length == 1) { // FIXME: single cell result, but still array raref2 = new RARef(split[0]); } else { raref2 = new RARef(split[1]); } CellAddr ulCa = raref1.Addr(col - 1, row - 1); CellAddr lrCa = raref2.Addr(col - 1, row - 1); // This also updates support sets, but that's useless, because // they will subsequently be reset by RebuildSupportGraph sheet.SetArrayFormula(cell, col - 1, row - 1, ulCa, lrCa); } else { // One-cell formula, or constant sheet[col - 1, row - 1] = cell; } } cellreader.Close(); return cellCount; }
private int ParseRow(XmlReader rowreader, Workbook wb, Sheet sheet, int row, IDictionary <string, Cell> cellParsingCache) { /* XMLSS has origin at (1,1) = (A,1) whereas Corecalc internal * representation has origin at (0,0) = (A,1). Hence the col * and row indices are 1 higher in this method. */ int cellCount = 0; int col = 0; XmlReader cellreader = rowreader.ReadSubtree(); while (cellreader.ReadToFollowing("Cell")) { String colindexstr = cellreader.GetAttribute("ss:Index"); String arrayrangestr = cellreader.GetAttribute("ss:ArrayRange"); String formulastr = cellreader.GetAttribute("ss:Formula"); String typestr = ""; String dataval = ""; if (colindexstr != null) { if (!int.TryParse(colindexstr, out col)) { col = 0; // Looks wrong, should be 1? } } else { col++; } cellCount++; // If an array result occupies cells, do not overwrite // the formula with precomputed and cached data from // the XMLSS file. Instead skip the parsing and sheet update. if (sheet[col - 1, row - 1] != null) { continue; } using (XmlReader datareader = cellreader.ReadSubtree()) { if (datareader.ReadToFollowing("Data")) { typestr = datareader.GetAttribute("ss:Type"); datareader.MoveToContent(); dataval = datareader.ReadElementContentAsString(); } } String cellString; if (formulastr != null) { cellString = formulastr; } else { // Anything else than formulas are values. // If XMLSS tells us it is a String we believe it if (typestr == "String") { dataval = "'" + dataval; } cellString = dataval; } // Skip blank cells if (cellString == "") { continue; } Cell cell; if (cellParsingCache.TryGetValue(cellString, out cell)) { // Copy the cell (both for mutable Formula cells and for cell-specific // metadata) and but share any sharable contents. cell = cell.CloneCell(col - 1, row - 1); } else { // Cell contents not seen before: scan, parse and cache cell = Cell.Parse(cellString, wb, col, row); if (cell == null) { Console.WriteLine("BAD: Null cell from \"{0}\"", cellString); } else { cellParsingCache.Add(cellString, cell); } } if (arrayrangestr != null && cell is Formula) // Array formula { string[] split = arrayrangestr.Split(":".ToCharArray()); RARef raref1 = new RARef(split[0]); RARef raref2; if (split.Length == 1) { // FIXME: single cell result, but still array raref2 = new RARef(split[0]); } else { raref2 = new RARef(split[1]); } CellAddr ulCa = raref1.Addr(col - 1, row - 1); CellAddr lrCa = raref2.Addr(col - 1, row - 1); // This also updates support sets, but that's useless, because // they will subsequently be reset by RebuildSupportGraph sheet.SetArrayFormula(cell, col - 1, row - 1, ulCa, lrCa); } else // One-cell formula, or constant { sheet[col - 1, row - 1] = cell; } } cellreader.Close(); return(cellCount); }