spreadsheet
typeScript/javascript spreadsheet parser, with formulas.
git clone https://git.vogt.world/spreadsheet.git
Log | Files | README.md
← Commit log
commit
message
[Text.VALUE] formula added and tested
author
Ben Vogt <[email protected]>
date
2017-10-08 17:05:50
stats
8 file(s) changed, 73 insertions(+), 5 deletions(-)
files
DOCS.md
TODO.md
dist/Formulas/AllFormulas.js
dist/Formulas/Text.js
src/Formulas/AllFormulas.ts
src/Formulas/Text.ts
tests/Formulas/TextTest.ts
tests/SheetFormulaTest.ts
  1diff --git a/DOCS.md b/DOCS.md
  2index 0ca004d..613a1c8 100644
  3--- a/DOCS.md
  4+++ b/DOCS.md
  5@@ -2470,3 +2470,12 @@
  6 @param numberOfReps - The number of repetitions 
  7 @constructor
  8 ```
  9+
 10+### VALUE 
 11+
 12+```
 13+  Converts a value into a number if possible. 
 14+@param value - The value to convert to a number. 
 15+@returns {number} 
 16+@constructor
 17+```
 18diff --git a/TODO.md b/TODO.md
 19index 6496d7e..396e867 100644
 20--- a/TODO.md
 21+++ b/TODO.md
 22@@ -20,6 +20,10 @@ Currently, this `=SERIESSUM([1], [0], [1], [4, 5, 6])` parses, but this `=SERIES
 23 E.g. `01/09/2012 10:04:33.123`
 24 
 25 
 26+### TypeConverter should be able to convert timestamps to numbers.
 27+E.g. `12:00:00` should result in `0.5`.
 28+
 29+
 30 ### Parser should be able to parse arrays without `eval`
 31 Right now, arrays and reference literals in a formula are parsed using JS `eval`. This means, if we have references inside, or non-JS parsing values like TRUE or FALSE, they will cause ReferenceErrors. For example, `=SUM([M1, 10])` would throw `[ReferenceError: M1 is not defined]` because M1 is not a variable. Instead of using `eval`, we should parse the opening of an array, and the closeing of an array, and use recursion to see how deep we are, evaluating the tokens inside in the sam way we parse formulas and functions.
 32 
 33@@ -47,7 +51,6 @@ Many of these formulas can be written by allowing the Sheet and Parser to return
 34 * REGEXREPLACE - May be difficult considering language differences.
 35 * REPLACE
 36 * SUBSTITUTE
 37-* VALUE
 38 
 39 ### Other formulas to write
 40 * CRITBINOM
 41diff --git a/dist/Formulas/AllFormulas.js b/dist/Formulas/AllFormulas.js
 42index cfcfdf1..6215687 100644
 43--- a/dist/Formulas/AllFormulas.js
 44+++ b/dist/Formulas/AllFormulas.js
 45@@ -234,6 +234,7 @@ exports.LEFT = Text_1.LEFT;
 46 exports.RIGHT = Text_1.RIGHT;
 47 exports.SEARCH = Text_1.SEARCH;
 48 exports.REPT = Text_1.REPT;
 49+exports.VALUE = Text_1.VALUE;
 50 var Date_1 = require("./Date");
 51 exports.DATE = Date_1.DATE;
 52 exports.DATEVALUE = Date_1.DATEVALUE;
 53diff --git a/dist/Formulas/Text.js b/dist/Formulas/Text.js
 54index abc96e2..ebd711b 100644
 55--- a/dist/Formulas/Text.js
 56+++ b/dist/Formulas/Text.js
 57@@ -835,3 +835,18 @@ var REPT = function (text, numberOfReps) {
 58     return new Array(numberOfReps + 1).join(text);
 59 };
 60 exports.REPT = REPT;
 61+/**
 62+ * Converts a value into a number if possible.
 63+ * @param value - The value to convert to a number.
 64+ * @returns {number}
 65+ * @constructor
 66+ */
 67+var VALUE = function (value) {
 68+    ArgsChecker_1.ArgsChecker.checkLength(arguments, 1, "VALUE");
 69+    value = TypeConverter_1.TypeConverter.firstValue(value);
 70+    if (typeof value === "boolean") {
 71+        throw new Errors_1.ValueError("VALUE parameter '" + value + "' cannot be parsed to number.");
 72+    }
 73+    return TypeConverter_1.TypeConverter.firstValueAsNumber(value);
 74+};
 75+exports.VALUE = VALUE;
 76diff --git a/src/Formulas/AllFormulas.ts b/src/Formulas/AllFormulas.ts
 77index 1d8209f..6abe939 100644
 78--- a/src/Formulas/AllFormulas.ts
 79+++ b/src/Formulas/AllFormulas.ts
 80@@ -241,7 +241,8 @@ import {
 81   LEFT,
 82   RIGHT,
 83   SEARCH,
 84-  REPT
 85+  REPT,
 86+  VALUE
 87 } from "./Text"
 88 import {
 89   DATE,
 90@@ -543,5 +544,6 @@ export {
 91   LEFT,
 92   RIGHT,
 93   SEARCH,
 94-  REPT
 95+  REPT,
 96+  VALUE
 97 }
 98\ No newline at end of file
 99diff --git a/src/Formulas/Text.ts b/src/Formulas/Text.ts
100index 0cfef32..c80e535 100644
101--- a/src/Formulas/Text.ts
102+++ b/src/Formulas/Text.ts
103@@ -867,6 +867,21 @@ let REPT = function (text, numberOfReps) {
104   return new Array(numberOfReps + 1).join(text);
105 };
106 
107+/**
108+ * Converts a value into a number if possible.
109+ * @param value - The value to convert to a number.
110+ * @returns {number}
111+ * @constructor
112+ */
113+let VALUE = function (value) {
114+  ArgsChecker.checkLength(arguments, 1, "VALUE");
115+  value = TypeConverter.firstValue(value);
116+  if (typeof value === "boolean") {
117+    throw new ValueError("VALUE parameter '" + value + "' cannot be parsed to number.");
118+  }
119+  return TypeConverter.firstValueAsNumber(value);
120+};
121+
122 export {
123   ARABIC,
124   CHAR,
125@@ -886,5 +901,6 @@ export {
126   LEFT,
127   RIGHT,
128   SEARCH,
129-  REPT
130+  REPT,
131+  VALUE
132 }
133\ No newline at end of file
134diff --git a/tests/Formulas/TextTest.ts b/tests/Formulas/TextTest.ts
135index fc9a220..f2e1dbb 100644
136--- a/tests/Formulas/TextTest.ts
137+++ b/tests/Formulas/TextTest.ts
138@@ -17,7 +17,8 @@ import {
139   LEFT,
140   RIGHT,
141   SEARCH,
142-  REPT
143+  REPT,
144+  VALUE
145 } from "../../src/Formulas/Text";
146 import * as ERRORS from "../../src/Errors";
147 import {
148@@ -483,3 +484,19 @@ test("REPT", function(){
149     REPT.apply(this, [1, 2, 3]);
150   }, ERRORS.NA_ERROR);
151 });
152+
153+test("VALUE", function(){
154+  assertEquals(VALUE("10"), 10);
155+  assertEquals(VALUE(10), 10);
156+  assertEquals(VALUE(10.1), 10.1);
157+  assertEquals(VALUE([10]), 10);
158+  assertEquals(VALUE("7/20/1966"), 24308);
159+  // TODO: Should pass once we're able to parse timestamp strings.
160+  // assertEquals(VALUE("12:00:00"), 0.5);
161+  catchAndAssertEquals(function() {
162+    VALUE(true);
163+  }, ERRORS.VALUE_ERROR);
164+  catchAndAssertEquals(function() {
165+    VALUE("str");
166+  }, ERRORS.VALUE_ERROR);
167+});
168diff --git a/tests/SheetFormulaTest.ts b/tests/SheetFormulaTest.ts
169index 844ba5d..37c89ae 100644
170--- a/tests/SheetFormulaTest.ts
171+++ b/tests/SheetFormulaTest.ts
172@@ -1073,6 +1073,10 @@ test("Sheet REPT", function(){
173   assertFormulaEquals('=REPT("a", 2)', "aa");
174 });
175 
176+test("Sheet VALUE", function(){
177+  assertFormulaEquals('=VALUE("10")', 10);
178+});
179+
180 test("Sheet parsing error", function(){
181   assertFormulaEqualsError('= 10e', PARSE_ERROR);
182   assertFormulaEqualsError('= SUM(', PARSE_ERROR);