commit
message
[Text.FIND] formula added and tested
author
Ben Vogt <[email protected]>
date
2017-10-08 00:06:58
stats
8 file(s) changed,
99 insertions(+),
6 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 4a2593e..3ac35be 100644
3--- a/DOCS.md
4+++ b/DOCS.md
5@@ -2402,3 +2402,14 @@
6 @param format - Text which defines the format. "0" forces the display of zeros, while "#" suppresses the display of zeros. For example TEXT(22.1,"000.00") produces 022.10, while TEXT(22.1,"###.##") produces 22.1, and TEXT(22.405,"00.00") results in 22.41. To format days: "dddd" indicates full name of the day of the week, "ddd" hort name of the day of the week, "dd" indicates the day of the month as two digits, "d" indicates day of the month as one or two digits, "mmmmm" indicates the first letter in the month of the year, "mmmm" indicates the full name of the month of the year, "mmm" indicates short name of the month of the year, "mm" indicates month of the year as two digits or the number of minutes in a time, depending on whether it follows yy or dd, or if it follows hh, "m" month of the year as one or two digits or the number of minutes in a time, depending on whether it follows yy or dd, or if it follows hh, "yyyy" indicates year as four digits, "yy" and "y" indicate year as two digits, "hh" indicates hour on a 24-hour clock, "h" indicates hour on a 12-hour clock, "ss.000" indicates milliseconds in a time, "ss" indicates econds in a time, "AM/PM" or "A/P" indicate displaying hours based on a 12-hour clock and showing AM or PM depending on the time of day. Eg: `TEXT("01/09/2012 10:04:33AM", "mmmm-dd-yyyy, hh:mm AM/PM")` would result in "January-09-2012, 10:04 AM".
7 @constructor if (format.match(/^.(d|D|M|m|yy|Y|HH|hh|h|s|S|AM|PM|am|pm|A\/P|\).$/g)) { const POUND_SIGN_FORMAT_CAPTURE = /^([$
8 ```
9+
10+### FIND
11+
12+```
13+ Looks for a string of text within another string. Where to begin the search can also be defined. The search term can be a number or any string of characters. The search is case-sensitive.
14+@param searchFor - The text to be found.
15+@param searchIn - The text where the search takes place.
16+@param startAt - [OPTIONAL defaults to 1] - The position in the text from which the search starts.
17+@returns {number}
18+@constructor
19+```
20diff --git a/TODO.md b/TODO.md
21index cdc319e..49b421e 100644
22--- a/TODO.md
23+++ b/TODO.md
24@@ -40,7 +40,6 @@ Many of these formulas can be written by allowing the Sheet and Parser to return
25
26 ### Easy formulas to write
27 * CLEAN
28-* FIND
29 * JOIN
30 * LEFT
31 * LEN
32diff --git a/dist/Formulas/AllFormulas.js b/dist/Formulas/AllFormulas.js
33index 507582a..3326bf4 100644
34--- a/dist/Formulas/AllFormulas.js
35+++ b/dist/Formulas/AllFormulas.js
36@@ -227,6 +227,7 @@ exports.UPPER = Text_1.UPPER;
37 exports.T = Text_1.T;
38 exports.ROMAN = Text_1.ROMAN;
39 exports.TEXT = Text_1.TEXT;
40+exports.FIND = Text_1.FIND;
41 var Date_1 = require("./Date");
42 exports.DATE = Date_1.DATE;
43 exports.DATEVALUE = Date_1.DATEVALUE;
44diff --git a/dist/Formulas/Text.js b/dist/Formulas/Text.js
45index 790ba46..e3e9833 100644
46--- a/dist/Formulas/Text.js
47+++ b/dist/Formulas/Text.js
48@@ -703,3 +703,27 @@ var TEXT = function (value, format) {
49 }
50 };
51 exports.TEXT = TEXT;
52+/**
53+ * Looks for a string of text within another string. Where to begin the search can also be defined. The search term can
54+ * be a number or any string of characters. The search is case-sensitive.
55+ * @param searchFor - The text to be found.
56+ * @param searchIn - The text where the search takes place.
57+ * @param startAt - [OPTIONAL defaults to 1] - The position in the text from which the search starts.
58+ * @returns {number}
59+ * @constructor
60+ */
61+var FIND = function (searchFor, searchIn, startAt) {
62+ ArgsChecker_1.ArgsChecker.checkLengthWithin(arguments, 2, 3, "FIND");
63+ searchFor = TypeConverter_1.TypeConverter.firstValueAsString(searchFor);
64+ searchIn = TypeConverter_1.TypeConverter.firstValueAsString(searchIn);
65+ startAt = MoreUtils_1.isUndefined(startAt) ? 1 : TypeConverter_1.TypeConverter.firstValueAsNumber(startAt);
66+ if (startAt < 1) {
67+ throw new Errors_1.ValueError("FIND parameter 3 value is " + startAt + ", but should be greater than or equal to 1.");
68+ }
69+ var index = searchIn.indexOf(searchFor, startAt - 1);
70+ if (index > -1) {
71+ return index + 1;
72+ }
73+ throw new Errors_1.ValueError("For FIND cannot find '" + searchFor + "' within '" + searchIn + "'.");
74+};
75+exports.FIND = FIND;
76diff --git a/src/Formulas/AllFormulas.ts b/src/Formulas/AllFormulas.ts
77index 31b36ed..ab5ad6c 100644
78--- a/src/Formulas/AllFormulas.ts
79+++ b/src/Formulas/AllFormulas.ts
80@@ -234,7 +234,8 @@ import {
81 UPPER,
82 T,
83 ROMAN,
84- TEXT
85+ TEXT,
86+ FIND
87 } from "./Text"
88 import {
89 DATE,
90@@ -529,5 +530,6 @@ export {
91 RATE,
92 SUBTOTAL,
93 HYPGEOMDIST,
94- ZTEST
95+ ZTEST,
96+ FIND
97 }
98\ No newline at end of file
99diff --git a/src/Formulas/Text.ts b/src/Formulas/Text.ts
100index 04c9334..6a68e4f 100644
101--- a/src/Formulas/Text.ts
102+++ b/src/Formulas/Text.ts
103@@ -14,7 +14,7 @@ import {
104 Filter
105 } from "../Utilities/Filter";
106 import {
107- isDefined,
108+ isDefined, isUndefined,
109 NumberStringBuilder
110 } from "../Utilities/MoreUtils";
111 import {ROUND} from "./Math";
112@@ -739,6 +739,30 @@ let TEXT = function (value, format) {
113 }
114 };
115
116+/**
117+ * Looks for a string of text within another string. Where to begin the search can also be defined. The search term can
118+ * be a number or any string of characters. The search is case-sensitive.
119+ * @param searchFor - The text to be found.
120+ * @param searchIn - The text where the search takes place.
121+ * @param startAt - [OPTIONAL defaults to 1] - The position in the text from which the search starts.
122+ * @returns {number}
123+ * @constructor
124+ */
125+let FIND = function (searchFor, searchIn, startAt?) {
126+ ArgsChecker.checkLengthWithin(arguments, 2, 3, "FIND");
127+ searchFor = TypeConverter.firstValueAsString(searchFor);
128+ searchIn = TypeConverter.firstValueAsString(searchIn);
129+ startAt = isUndefined(startAt) ? 1 : TypeConverter.firstValueAsNumber(startAt);
130+ if (startAt < 1) {
131+ throw new ValueError("FIND parameter 3 value is " + startAt + ", but should be greater than or equal to 1.");
132+ }
133+ let index = searchIn.indexOf(searchFor, startAt - 1);
134+ if (index > -1) {
135+ return index + 1;
136+ }
137+ throw new ValueError("For FIND cannot find '" + searchFor + "' within '" + searchIn + "'.");
138+};
139+
140 export {
141 ARABIC,
142 CHAR,
143@@ -751,5 +775,6 @@ export {
144 UPPER,
145 T,
146 ROMAN,
147- TEXT
148+ TEXT,
149+ FIND
150 }
151\ No newline at end of file
152diff --git a/tests/Formulas/TextTest.ts b/tests/Formulas/TextTest.ts
153index 8bb2e19..79282a6 100644
154--- a/tests/Formulas/TextTest.ts
155+++ b/tests/Formulas/TextTest.ts
156@@ -10,7 +10,8 @@ import {
157 UPPER,
158 T,
159 ROMAN,
160- TEXT
161+ TEXT,
162+ FIND
163 } from "../../src/Formulas/Text";
164 import * as ERRORS from "../../src/Errors";
165 import {
166@@ -349,3 +350,28 @@ test("TEXT", function(){
167 TEXT.apply(this, [100, "0", 10])
168 }, ERRORS.NA_ERROR);
169 });
170+
171+test("FIND", function(){
172+ assertEquals(FIND("s", "soup", 1), 1);
173+ assertEquals(FIND("s", "soup"), 1);
174+ assertEquals(FIND("o", "soup"), 2);
175+ assertEquals(FIND("u", "soup"), 3);
176+ assertEquals(FIND("p", "soup"), 4);
177+ assertEquals(FIND("s", "soup soup", 5), 6);
178+ assertEquals(FIND("o", "soup soup", 5), 7);
179+ assertEquals(FIND("u", "soup soup", 5), 8);
180+ assertEquals(FIND("p", "soup soup", 5), 9);
181+ assertEquals(FIND("p", "soup soup", 4), 4);
182+ catchAndAssertEquals(function() {
183+ FIND("m", "soup", -1);
184+ }, ERRORS.VALUE_ERROR);
185+ catchAndAssertEquals(function() {
186+ FIND("m", "soup");
187+ }, ERRORS.VALUE_ERROR);
188+ catchAndAssertEquals(function() {
189+ FIND.apply(this, [2])
190+ }, ERRORS.NA_ERROR);
191+ catchAndAssertEquals(function() {
192+ FIND.apply(this, [2, 3, 4, 5])
193+ }, ERRORS.NA_ERROR);
194+});
195diff --git a/tests/SheetFormulaTest.ts b/tests/SheetFormulaTest.ts
196index 65f485c..35416e6 100644
197--- a/tests/SheetFormulaTest.ts
198+++ b/tests/SheetFormulaTest.ts
199@@ -1045,6 +1045,10 @@ test("Sheet ZTEST", function(){
200 assertFormulaEquals('=ZTEST([1, 2, 3, 4, 5, 6, 7], 5.6, 1.1)', 0.9999405457342111);
201 });
202
203+test("Sheet FIND", function(){
204+ assertFormulaEquals('=FIND("s", "soup")', 1);
205+});
206+
207 test("Sheet parsing error", function(){
208 assertFormulaEqualsError('= 10e', PARSE_ERROR);
209 assertFormulaEqualsError('= SUM(', PARSE_ERROR);