spreadsheet
typeScript/javascript spreadsheet parser, with formulas.
git clone https://git.vogt.world/spreadsheet.git
Log | Files | README.md
← Commit log
commit
message
[ISERROR] formula added and tested (pending correct calling from Parser/Sheet)
author
Ben Vogt <[email protected]>
date
2017-07-09 18:45:16
stats
8 file(s) changed, 100 insertions(+), 6 deletions(-)
files
DOCS.md
TODO.md
dist/Formulas/AllFormulas.js
dist/Formulas/Info.js
src/Formulas/AllFormulas.ts
src/Formulas/Info.ts
tests/Formulas/InfoTest.ts
tests/SheetFormulaTest.ts
  1diff --git a/DOCS.md b/DOCS.md
  2index 638059d..59e6060 100644
  3--- a/DOCS.md
  4+++ b/DOCS.md
  5@@ -647,6 +647,15 @@
  6 @returns {boolean} 
  7 @constructor TODO: This formula needs to be called from inside a try-catch-block in the SheetParser, like ERROR.TYPE.
  8 ```
  9+
 10+### ISERROR 
 11+
 12+```
 13+  Tests if the cells contain general error values. ISERROR recognizes the #NA error value. If an error occurs, the function returns a logical or numerical value. 
 14+@param value - is any value where a test is performed to determine whether it is an error value. 
 15+@returns {boolean} 
 16+@constructor TODO: This formula needs to be called from inside a try-catch-block in the SheetParser, like ERROR.TYPE.
 17+```
 18 ## Logical
 19 
 20 
 21diff --git a/TODO.md b/TODO.md
 22index e389f96..f652c0f 100644
 23--- a/TODO.md
 24+++ b/TODO.md
 25@@ -38,7 +38,6 @@ See documentation for ERROR.TYPE for more information.
 26 ### Meta-Formulas to write
 27 Many of these formulas can be written by allowing the Sheet and Parser to return Cell objects in addition to primitive types. There are some memory issues with doing this. If a user calls something like `ISNA(A1:A99999)` we really only need the first cell. So we should return cell objects in some cases, but it would be easier in most cases to have context aware formulas, so if they need a cell, or a reference, we simply skip looking up a reference, and instead return a reference, or just a single cell. One way to do this would be to have formula functions, and then on the side have formula args. So before we lookup a large range of cells, we can check to see if it needs all of them, or if it just cares about the first one. So for `ISNA` we could look at `FormulaArgs.ISNA[0]` to get `Value` so we know that it needs only a single argument that is not an array, so if we call it with `ISNA(A1:A99999)`, it would really only lookup `A1`. This might be premature optimization however.
 28 
 29-* ISERROR - See ISERR.
 30 * ISFORMULA - Requires changes to Parser/Sheet to fetch a cell, and check the formula field to see if it contains a formula.
 31 * ISNA - Requires changes to Parser/Sheet for similar reasons to ISERR; check reference cell value or error field.
 32 * TYPE - Requires changes to Parser/Sheet to allow for values or cells to be returned to the function. If it's a value, return the value type. If it's a cell, return the value or error inside it.
 33diff --git a/dist/Formulas/AllFormulas.js b/dist/Formulas/AllFormulas.js
 34index 4689911..64c3dc7 100644
 35--- a/dist/Formulas/AllFormulas.js
 36+++ b/dist/Formulas/AllFormulas.js
 37@@ -92,6 +92,7 @@ exports.ISREF = Info_1.ISREF;
 38 exports.ERRORTYPE = Info_1.ERRORTYPE;
 39 exports.ISBLANK = Info_1.ISBLANK;
 40 exports.ISERR = Info_1.ISERR;
 41+exports.ISERROR = Info_1.ISERROR;
 42 var Lookup_1 = require("./Lookup");
 43 exports.CHOOSE = Lookup_1.CHOOSE;
 44 var Logical_1 = require("./Logical");
 45diff --git a/dist/Formulas/Info.js b/dist/Formulas/Info.js
 46index 5d180ff..2a93609 100644
 47--- a/dist/Formulas/Info.js
 48+++ b/dist/Formulas/Info.js
 49@@ -205,9 +205,36 @@ exports.ISBLANK = ISBLANK;
 50  * TODO: This formula needs to be called from inside a try-catch-block in the Sheet/Parser, like ERROR.TYPE.
 51  */
 52 var ISERR = function (value) {
 53+    if (value instanceof Cell_1.Cell) {
 54+        if (value.hasError()) {
 55+            return value.getError().name !== Errors_1.NA_ERROR;
 56+        }
 57+        return false;
 58+    }
 59     if (value instanceof Error) {
 60         return value.name !== Errors_1.NA_ERROR;
 61     }
 62     return false;
 63 };
 64 exports.ISERR = ISERR;
 65+/**
 66+ * Tests if the cells contain general error values. ISERROR recognizes the #N/A error value. If an error occurs, the
 67+ * function returns a logical or numerical value.
 68+ * @param value - is any value where a test is performed to determine whether it is an error value.
 69+ * @returns {boolean}
 70+ * @constructor
 71+ * TODO: This formula needs to be called from inside a try-catch-block in the Sheet/Parser, like ERROR.TYPE.
 72+ */
 73+var ISERROR = function (value) {
 74+    try {
 75+        value = TypeConverter_1.TypeConverter.firstValue(value);
 76+    }
 77+    catch (e) {
 78+        return true;
 79+    }
 80+    if (value instanceof Cell_1.Cell) {
 81+        return value.hasError();
 82+    }
 83+    return value instanceof Error;
 84+};
 85+exports.ISERROR = ISERROR;
 86diff --git a/src/Formulas/AllFormulas.ts b/src/Formulas/AllFormulas.ts
 87index 17f4009..32e1b65 100644
 88--- a/src/Formulas/AllFormulas.ts
 89+++ b/src/Formulas/AllFormulas.ts
 90@@ -91,7 +91,8 @@ import {
 91   ISREF,
 92   ERRORTYPE,
 93   ISBLANK,
 94-  ISERR
 95+  ISERR,
 96+  ISERROR
 97 } from "./Info";
 98 import {
 99   CHOOSE
100@@ -433,5 +434,6 @@ export {
101   ISREF,
102   ERRORTYPE,
103   ISBLANK,
104-  ISERR
105+  ISERR,
106+  ISERROR
107 }
108\ No newline at end of file
109diff --git a/src/Formulas/Info.ts b/src/Formulas/Info.ts
110index c23eefe..fe8b4de 100644
111--- a/src/Formulas/Info.ts
112+++ b/src/Formulas/Info.ts
113@@ -222,12 +222,38 @@ var ISBLANK = function (value) {
114  * TODO: This formula needs to be called from inside a try-catch-block in the Sheet/Parser, like ERROR.TYPE.
115  */
116 var ISERR = function (value) {
117+  if (value instanceof Cell) {
118+    if (value.hasError()) {
119+      return value.getError().name !== NA_ERROR;
120+    }
121+    return false;
122+  }
123   if (value instanceof Error) {
124     return value.name !== NA_ERROR;
125   }
126   return false;
127 };
128 
129+/**
130+ * Tests if the cells contain general error values. ISERROR recognizes the #N/A error value. If an error occurs, the
131+ * function returns a logical or numerical value.
132+ * @param value - is any value where a test is performed to determine whether it is an error value.
133+ * @returns {boolean}
134+ * @constructor
135+ * TODO: This formula needs to be called from inside a try-catch-block in the Sheet/Parser, like ERROR.TYPE.
136+ */
137+var ISERROR = function (value) {
138+  try {
139+    value = TypeConverter.firstValue(value);
140+  } catch (e) {
141+    return true;
142+  }
143+  if (value instanceof Cell) {
144+    return value.hasError();
145+  }
146+  return value instanceof Error;
147+};
148+
149 
150 export {
151   NA,
152@@ -241,5 +267,6 @@ export {
153   ISREF,
154   ERRORTYPE,
155   ISBLANK,
156-  ISERR
157+  ISERR,
158+  ISERROR
159 }
160\ No newline at end of file
161diff --git a/tests/Formulas/InfoTest.ts b/tests/Formulas/InfoTest.ts
162index 1b1f77b..00cf213 100644
163--- a/tests/Formulas/InfoTest.ts
164+++ b/tests/Formulas/InfoTest.ts
165@@ -10,7 +10,8 @@ import {
166   ISREF,
167   ERRORTYPE,
168   ISBLANK,
169-  ISERR
170+  ISERR,
171+  ISERROR
172 } from "../../src/Formulas/Info";
173 import * as ERRORS from "../../src/Errors";
174 import {
175@@ -167,6 +168,10 @@ test("ISBLANK", function(){
176 
177 
178 test("ISERR", function(){
179+  var errorCell = new Cell("A1");
180+  errorCell.setError(new DivZeroError("err"));
181+  assertEquals(ISERR(errorCell), true);
182+  assertEquals(ISERR(Cell.BuildFrom("A1", 10)), false);
183   assertEquals(ISERR(10), false);
184   assertEquals(ISERR([]), false);
185   assertEquals(ISERR(new NAError("error")), false);
186@@ -174,3 +179,19 @@ test("ISERR", function(){
187   assertEquals(ISERR(new NameError("error")), true);
188   assertEquals(ISERR(new RefError("error")), true);
189 });
190+
191+
192+test("ISERROR", function(){
193+  var errorCell = new Cell("A1");
194+  errorCell.setError(new DivZeroError("err"));
195+  assertEquals(ISERROR(errorCell), true);
196+  assertEquals(ISERROR(Cell.BuildFrom("A1", 10)), false);
197+  assertEquals(ISERROR(new Cell("A1")), false);
198+  assertEquals(ISERROR("10"), false);
199+  assertEquals(ISERROR(10), false);
200+  assertEquals(ISERROR([]), true);
201+  assertEquals(ISERROR(new NAError("error")), true);
202+  assertEquals(ISERROR(new DivZeroError("error")), true);
203+  assertEquals(ISERROR(new NameError("error")), true);
204+  assertEquals(ISERROR(new RefError("error")), true);
205+});
206diff --git a/tests/SheetFormulaTest.ts b/tests/SheetFormulaTest.ts
207index 32510bd..b87ae5d 100644
208--- a/tests/SheetFormulaTest.ts
209+++ b/tests/SheetFormulaTest.ts
210@@ -844,6 +844,10 @@ test("Sheet ISERR", function(){
211   assertFormulaEquals('=ISERR(10)', false);
212 });
213 
214+test("Sheet ISERROR", function(){
215+  assertFormulaEquals('=ISERROR(10)', false);
216+});
217+
218 test("Sheet *", function(){
219   assertFormulaEquals('= 10 * 10', 100);
220   assertFormulaEquals('= 10 * 0', 0);