spreadsheet
typeScript/javascript spreadsheet parser, with formulas.
git clone https://git.vogt.world/spreadsheet.git
Log | Files | README.md
← Commit log
commit
message
Only parsing cell formulas/values beginning with '='
author
Ben Vogt <[email protected]>
date
2016-12-31 22:14:50
stats
6 file(s) changed, 61 insertions(+), 33 deletions(-)
files
README.md
src/Cell.ts
src/Main.ts
src/Sheet.ts
tests/CellTest.ts
tests/SheetTest.ts
  1diff --git a/README.md b/README.md
  2index 982c11f..a2ea5d7 100644
  3--- a/README.md
  4+++ b/README.md
  5@@ -4,13 +4,8 @@ TypeScript implementation of a spreadsheet.
  6 ## TODO
  7 Things I should do.
  8 
  9-### When adding a cell to the matrix, not everything should be parsed as a formula.
 10-Only inputs starting with `=` should be formulas. Eg: `=SUM(A1:A8, B12, MAX(22))`
 11-
 12 ### Rename anything referencing an "item"
 13 
 14-### `setValue()`, `getValue()` on a sheet
 15-
 16 ### Remove A1CellKey. It is unnecessary.
 17 
 18 ### Write documentation for A1CellKey
 19diff --git a/src/Cell.ts b/src/Cell.ts
 20index a21290b..971c07d 100644
 21--- a/src/Cell.ts
 22+++ b/src/Cell.ts
 23@@ -8,10 +8,10 @@ class Cell {
 24   public id: string;
 25   public row: number;
 26   public col: number;
 27-  constructor(formula: string, id: string) {
 28+  constructor(id: string) {
 29     var key = new A1CellKey(id);
 30 
 31-    this.formula = formula;
 32+    this.formula = null;
 33     this.value = "";
 34     this.dependencies = [];
 35     this.error = null;
 36@@ -26,6 +26,9 @@ class Cell {
 37       }
 38     }
 39   }
 40+  setFormula(formula: string) {
 41+    this.formula = formula;
 42+  }
 43   setValue(value: string) {
 44     this.value = value;
 45   }
 46@@ -38,6 +41,9 @@ class Cell {
 47     }
 48     return this.error.toString()
 49   }
 50+  toString() : string {
 51+    return "id=" + this.id + ", value=" + this.value + ", formula=" + this.formula + ", error=" + this.error;
 52+  }
 53 }
 54 
 55 export {
 56diff --git a/src/Main.ts b/src/Main.ts
 57index 9aa00fa..ea2af3c 100644
 58--- a/src/Main.ts
 59+++ b/src/Main.ts
 60@@ -1,12 +1,12 @@
 61 import { Sheet } from "./Sheet"
 62 
 63 var input = [
 64-  [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, "SUM(A1:D1, H1)"],
 65-  [-1, -10, 2, 4, 100, 1, 50, 20, 200, -100, "MAX(A2:J2)"],
 66-  [-1, -40, -53, 1, 10, 30, 10, 301, -1, -20, "MIN(A3:J3)"],
 67-  [20, 50, 100, 20, 1, 5, 15, 25, 45, 23, "AVERAGE(A4:J4)"],
 68-  [0, 10, 1, 10, 2, 10, 3, 10, 4, 10, "SUMIF(A5:J5,'>5')"],
 69-  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "SUM(K1, K2, K3, K4)"]
 70+  [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, "=SUM(A1:D1, H1)"],
 71+  [-1, -10, 2, 4, 100, 1, 50, 20, 200, -100, "=MAX(A2:J2)"],
 72+  [-1, -40, -53, 1, 10, 30, 10, 301, -1, -20, "=MIN(A3:J3)"],
 73+  [20, 50, 100, 20, 1, 5, 15, 25, 45, 23, "=AVERAGE(A4:J4)"],
 74+  [0, 10, 1, 10, 2, 10, 3, 10, 4, 10, "=SUMIF(A5:J5,'>5')"],
 75+  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "=SUM(K1, K2, K3, K4)"]
 76 ];
 77 var sheet = new Sheet();
 78 sheet.load(input);
 79diff --git a/src/Sheet.ts b/src/Sheet.ts
 80index e966b5c..9d4525d 100644
 81--- a/src/Sheet.ts
 82+++ b/src/Sheet.ts
 83@@ -110,7 +110,12 @@ var Sheet = (function () {
 84       return this.getDependencies(cell.id);
 85     }
 86     setCell(cellKeyString: string, formula: string) {
 87-      var cell = new Cell(formula, cellKeyString);
 88+      var cell = new Cell(cellKeyString);
 89+      if (formula.charAt(0) === "=") {
 90+        cell.setFormula(formula.substr(1));
 91+      } else {
 92+        cell.setValue(formula);
 93+      }
 94       registerCellInMatrix(cell);
 95       recalculateCellDependencies(cell);
 96     }
 97@@ -141,7 +146,9 @@ var Sheet = (function () {
 98 
 99   var registerCellInMatrix = function (cell: Cell) {
100     instance.matrix.addItem(cell);
101-    calculateCellFormula(cell);
102+    if (cell.formula !== null) {
103+      calculateCellFormula(cell);
104+    }
105   };
106 
107   var utils = {
108@@ -535,7 +542,7 @@ var Sheet = (function () {
109   this.toString = function () {
110     var toReturn = "";
111     for (var key in this.matrix.data) {
112-      toReturn += this.matrix.data[key].id + " " + this.matrix.data[key].formula + " " + this.matrix.data[key].value + " " + this.matrix.data[key].error + "\n";
113+      toReturn += this.matrix.data[key].toString() + "\n";
114     }
115     return toReturn;
116   };
117diff --git a/tests/CellTest.ts b/tests/CellTest.ts
118index 2a4dbbb..dbead72 100644
119--- a/tests/CellTest.ts
120+++ b/tests/CellTest.ts
121@@ -2,21 +2,21 @@ import { Cell } from "../src/Cell"
122 import { assertEquals, assertArrayEquals } from "./utils/Asserts"
123 
124 //Test constructor
125-var cell = new Cell("0", "A1");
126+var cell = new Cell("A1");
127 assertEquals(cell.col, 0);
128 assertEquals(cell.row, 0);
129 assertArrayEquals(cell.dependencies, []);
130 assertEquals(cell.id, "A1");
131-assertEquals(cell.formula, "0");
132+assertEquals(cell.formula, null);
133 
134 //Test updateDependencies
135-var one = new Cell("0", "A1");
136+var one = new Cell("A1");
137 one.updateDependencies(["B2", "C1", "D12", "D13"]);
138 assertArrayEquals(one.dependencies, ["B2", "C1", "D12", "D13"]);
139 one.updateDependencies(["M4"]);
140 assertArrayEquals(one.dependencies, ["B2", "C1", "D12", "D13", "M4"]);
141 
142 //Test setValue
143-var v = new Cell("0", "A1");
144+var v = new Cell("A1");
145 v.setValue("100");
146 assertEquals("100", v.value);
147diff --git a/tests/SheetTest.ts b/tests/SheetTest.ts
148index 207d073..9bfa791 100644
149--- a/tests/SheetTest.ts
150+++ b/tests/SheetTest.ts
151@@ -6,7 +6,7 @@ import { Errors } from "../src/Errors"
152 var sheet = new Sheet();
153 sheet.setCell("A2", "22");
154 var cell = sheet.getCell("A2");
155-assertEquals("22", cell.formula);
156+assertEquals(null, cell.formula);
157 assertEquals(22, cell.value);
158 assertEquals("A2", cell.id);
159 assertEquals(1, cell.row);
160@@ -20,26 +20,27 @@ assertEquals(null, nullCell);
161 
162 // Test setCell, with formula
163 var sheet = new Sheet();
164+var SUM_FORM = "=SUM(A1:A4)";
165 sheet.setCell("A1", "1");
166 sheet.setCell("A2", "20");
167 sheet.setCell("A3", "3.4");
168 sheet.setCell("A4", "45");
169-sheet.setCell("A5", "SUM(A1:A4)");
170+sheet.setCell("A5", "=SUM(A1:A4)");
171 var A5 = sheet.getCell("A5");
172 assertEquals("69.4", A5.value);
173-assertEquals("SUM(A1:A4)", A5.formula);
174+assertEquals(SUM_FORM.substr(1), A5.formula);
175 assertEquals(null, cell.error);
176 assertArrayEquals(['A1', 'A2', 'A3', 'A4'], A5.dependencies);
177 
178 
179 // Test load
180 var sheet = new Sheet();
181-var SUM_FORMULA = "SUM(A1:D1, H1)";
182-var MAX_FORMULA = "MAX(A2:J2)";
183-var MIN_FORMULA = "MIN(A3:J3)";
184-var AVERAGE_FORMULA = "AVERAGE(A4:J4)";
185-var SUM_IF_FORMULA = "SUMIF(A5:J5,'>5')";
186-var SUM_REF_FORMULA = "SUM(K1, K2, K3, K4)";
187+var SUM_FORMULA = "=SUM(A1:D1, H1)";
188+var MAX_FORMULA = "=MAX(A2:J2)";
189+var MIN_FORMULA = "=MIN(A3:J3)";
190+var AVERAGE_FORMULA = "=AVERAGE(A4:J4)";
191+var SUM_IF_FORMULA = "=SUMIF(A5:J5,'>5')";
192+var SUM_REF_FORMULA = "=SUM(K1, K2, K3, K4)";
193 sheet.load([[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, SUM_FORMULA],
194   [-1, -10, 2, 4, 100, 1, 50, 20, 200, -100, MAX_FORMULA],
195   [-1, -40, -53, 1, 10, 30, 10, 301, -1, -20, MIN_FORMULA],
196@@ -48,32 +49,32 @@ sheet.load([[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, SUM_FORMULA],
197   [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, SUM_REF_FORMULA]]);
198 var K1 = sheet.getCell("K1");
199 assertEquals("18", K1.value);
200-assertEquals(SUM_FORMULA, K1.formula);
201+assertEquals(SUM_FORMULA.substr(1), K1.formula);
202 assertEquals(null, K1.error);
203 assertArrayEquals(['A1', 'B1', 'C1', 'D1', 'H1'], K1.dependencies);
204 var K2 = sheet.getCell("K2");
205 assertEquals("200", K2.value);
206-assertEquals(MAX_FORMULA, K2.formula);
207+assertEquals(MAX_FORMULA.substr(1), K2.formula);
208 assertEquals(null, K2.error);
209 assertArrayEquals(['A2', 'B2', 'C2', 'D2', 'E2', 'F2', 'G2', 'H2', 'I2', 'J2'], K2.dependencies);
210 var K3 = sheet.getCell("K3");
211 assertEquals("-53", K3.value);
212-assertEquals(MIN_FORMULA, K3.formula);
213+assertEquals(MIN_FORMULA.substr(1), K3.formula);
214 assertEquals(null, K3.error);
215 assertArrayEquals(['A3', 'B3', 'C3', 'D3', 'E3', 'F3', 'G3', 'H3', 'I3', 'J3'], K3.dependencies);
216 var K4 = sheet.getCell("K4");
217 assertEquals("30.4", K4.value);
218-assertEquals(AVERAGE_FORMULA, K4.formula);
219+assertEquals(AVERAGE_FORMULA.substr(1), K4.formula);
220 assertEquals(null, K4.error);
221 assertArrayEquals(['A4', 'B4', 'C4', 'D4', 'E4', 'F4', 'G4', 'H4', 'I4', 'J4'], K4.dependencies);
222 var K5 = sheet.getCell("K5");
223 assertEquals("50", K5.value);
224-assertEquals(SUM_IF_FORMULA, K5.formula);
225+assertEquals(SUM_IF_FORMULA.substr(1), K5.formula);
226 assertEquals(null, K5.error);
227 assertArrayEquals(['A5', 'B5', 'C5', 'D5', 'E5', 'F5', 'G5', 'H5', 'I5', 'J5'], K5.dependencies);
228 var K6 = sheet.getCell("K6");
229 assertEquals("195.4", K6.value);
230-assertEquals(SUM_REF_FORMULA, K6.formula);
231+assertEquals(SUM_REF_FORMULA.substr(1), K6.formula);
232 assertEquals(null, K6.error);
233 assertArrayEquals(['K1', 'K2', 'K3', 'K4'], K6.dependencies);
234 
235@@ -81,9 +82,9 @@ assertArrayEquals(['K1', 'K2', 'K3', 'K4'], K6.dependencies);
236 var sheet  = new Sheet();
237 sheet.setCell("A1", "200");
238 sheet.setCell("A2", "200");
239-sheet.setCell("A3", "SUM(A1, A2)");
240-sheet.setCell("B1", "SUM(A3, B2)");
241-sheet.setCell("B2", "SUM(A1, B1)");
242+sheet.setCell("A3", "=SUM(A1, A2)");
243+sheet.setCell("B1", "=SUM(A3, B2)");
244+sheet.setCell("B2", "=SUM(A1, B1)");
245 var B1 = sheet.getCell("B1");
246 assertEquals(null, B1.value);
247 assertEquals(Errors.get("REF"), B1.error);
248@@ -96,7 +97,7 @@ assertArrayEquals(['A1', 'B1'], B2.dependencies);
249 // Test NAME error
250 var sheet  = new Sheet();
251 sheet.setCell("A1", "1");
252-sheet.setCell("A2", "SUM(A1, NN)");
253+sheet.setCell("A2", "=SUM(A1, NN)");
254 var A2 = sheet.getCell("A2");
255 assertEquals(null, A2.value);
256 assertEquals(Errors.get("NAME"), A2.error);
257@@ -105,8 +106,20 @@ assertArrayEquals(['A1'], A2.dependencies);
258 // Test unsupported formula
259 var sheet  = new Sheet();
260 sheet.setCell("A1", "1");
261-sheet.setCell("A2", "BEN(A1)");
262+sheet.setCell("A2", "=BEN(A1)");
263 var A2 = sheet.getCell("A2");
264 assertEquals(null, A2.value);
265 assertEquals(Errors.get("NAME"), A2.error);
266 assertArrayEquals(['A1'], A2.dependencies);
267+
268+// Test nested formulas
269+var sheet  = new Sheet();
270+sheet.setCell("A1", "1");
271+sheet.setCell("A2", "10");
272+sheet.setCell("A3", "44.4");
273+sheet.setCell("A4", "=SUM(A1:A3, MAX(A1, A3))");
274+var A4 = sheet.getCell("A4");
275+assertEquals("99.8", A4.value);
276+assertEquals("SUM(A1:A3, MAX(A1, A3))", A4.formula);
277+assertEquals(null, A4.error);
278+assertArrayEquals(['A1', 'A2', 'A3'], A4.dependencies);
279\ No newline at end of file