spreadsheet
typeScript/javascript spreadsheet parser, with formulas.
git clone https://git.vogt.world/spreadsheet.git
Log | Files | README.md
← Commit log
commit
message
Added Formulas.DB
author
Ben Vogt <[email protected]>
date
2017-02-18 22:54:59
stats
3 file(s) changed, 81 insertions(+), 5 deletions(-)
files
src/RawFormulas/RawFormulas.ts
tests/FormulasTest.ts
tests/SheetFormulaTest.ts
  1diff --git a/src/RawFormulas/RawFormulas.ts b/src/RawFormulas/RawFormulas.ts
  2index 4a1cd1a..b1f5aba 100644
  3--- a/src/RawFormulas/RawFormulas.ts
  4+++ b/src/RawFormulas/RawFormulas.ts
  5@@ -107,7 +107,6 @@ var DATEVALUE = function (dateString: string) : Date {
  6 var DAY = Formula["DAY"];
  7 var DAYS = Formula["DAYS"];
  8 var DAYS360 = Formula["DAYS360"];
  9-var DB = Formula["DB"];
 10 var DDB = Formula["DDB"];
 11 var DEVSQ = Formula["DEVSQ"];
 12 var DOLLAR = Formula["DOLLAR"];
 13@@ -130,6 +129,72 @@ var __COMPLEX = {
 14 };
 15 var YEARFRAC = Formula["YEARFRAC"];
 16 
 17+/**
 18+ * Calculates the depreciation of an asset for a specified period using the arithmetic declining balance method.
 19+ * @param values[0] cost - The initial cost of the asset.
 20+ * @param values[1] salvage - The value of the asset at the end of depreciation.
 21+ * @param values[2] life - The number of periods over which the asset is depreciated.
 22+ * @param values[3] period - The single period within life for which to calculate depreciation.
 23+ * @param values[4] month - [ OPTIONAL - 12 by default ] - The number of months in the first year of depreciation.
 24+ * @returns {number} depreciated value
 25+ * @constructor
 26+ */
 27+var DB = function (...values) : number {
 28+  ArgsChecker.checkLengthWithin(values, 4, 5);
 29+  var cost = TypeCaster.firstValueAsNumber(values[0]);
 30+  var salvage = TypeCaster.firstValueAsNumber(values[1]);
 31+  var life = TypeCaster.firstValueAsNumber(values[2]);
 32+  var period = TypeCaster.firstValueAsNumber(values[3]);
 33+  var month = 12;
 34+  if (values.length === 5) {
 35+    month = Math.floor(TypeCaster.firstValueAsNumber(values[4]));
 36+  }
 37+  if (cost < 0) {
 38+    throw new CellError(ERRORS.NUM_ERROR, "Function DB parameter 1 value is "
 39+      + cost + ". It should be greater than or equal to 0.");
 40+  }
 41+  if (salvage < 0) {
 42+    throw new CellError(ERRORS.NUM_ERROR, "Function DB parameter 2 value is "
 43+      + salvage + ". It should be greater than or equal to 0.");
 44+  }
 45+  if (life < 0) {
 46+    throw new CellError(ERRORS.NUM_ERROR, "Function DB parameter 3 value is "
 47+      + life + ". It should be greater than or equal to 0.");
 48+  }
 49+  if (period < 0) {
 50+    throw new CellError(ERRORS.NUM_ERROR, "Function DB parameter 4 value is "
 51+      + period + ". It should be greater than or equal to 0.");
 52+  }
 53+  if (month > 12 || month < 1) {
 54+    throw new CellError(ERRORS.NUM_ERROR, "Function DB parameter 5 value is "
 55+      + month + ". Valid values are between 1 and 12 inclusive.");
 56+  }
 57+  if (period > life) {
 58+    throw new CellError(ERRORS.NUM_ERROR, "Function DB parameter 4 value is "
 59+      + life + ". It should be less than or equal to value of Function DB parameter 3 with "+ period +".");
 60+  }
 61+  if (salvage >= cost) {
 62+    return 0;
 63+  }
 64+  var rate = (1 - Math.pow(salvage / cost, 1 / life));
 65+  var initial = cost * rate * month / 12;
 66+  var total = initial;
 67+  var current = 0;
 68+  var ceiling = (period === life) ? life - 1 : period;
 69+  for (var i = 2; i <= ceiling; i++) {
 70+    current = (cost - total) * rate;
 71+    total += current;
 72+  }
 73+  if (period === 1) {
 74+    return initial;
 75+  } else if (period === life) {
 76+    return (cost - total) * rate;
 77+  } else {
 78+    return current;
 79+  }
 80+};
 81+
 82+
 83 
 84 /**
 85  * Calculates the sum of the sums of the squares of values in two arrays.
 86diff --git a/tests/FormulasTest.ts b/tests/FormulasTest.ts
 87index be3532d..50e3d92 100644
 88--- a/tests/FormulasTest.ts
 89+++ b/tests/FormulasTest.ts
 90@@ -673,7 +673,20 @@ assertEquals(DAYS(DATEVALUE("1993-6-24"), DATEVALUE("1992-6-24")), 365);
 91 
 92 assertEquals(DAYS360(DATE(1969, 7, 16), DATE(1970, 7, 24), 1), 368);
 93 
 94-assertEquals(DB(100, 50, 10, 2, 12), 6.2511);
 95+
 96+// Test DB
 97+assertEquals(DB(100, 50, 10, 2, 12), 6.2482428240683285);
 98+assertEquals(DB("100", "50", "10", "2", "12"), 6.2482428240683285);
 99+assertEquals(DB(100, 50, 10, 2, 12.9999999), 6.2482428240683285);
100+catchAndAssertEquals(function() {
101+  DB(100, 50, 10, 2, 13);
102+}, ERRORS.NUM_ERROR);
103+catchAndAssertEquals(function() {
104+  DB(100, 50, 10, 12, 13);
105+}, ERRORS.NUM_ERROR);
106+catchAndAssertEquals(function() {
107+  DB(100, -50, 10, 2, 12);
108+}, ERRORS.NUM_ERROR);
109 
110 assertEquals(DDB(100, 50, 10, 2, 2.25), 17.4375);
111 
112diff --git a/tests/SheetFormulaTest.ts b/tests/SheetFormulaTest.ts
113index b14cf85..7449915 100644
114--- a/tests/SheetFormulaTest.ts
115+++ b/tests/SheetFormulaTest.ts
116@@ -185,7 +185,7 @@ testFormula('=DAYS(DATEVALUE("1993-6-24"), DATEVALUE("1992-6-24"))', 365);
117 testFormula('=DAYS360(DATE(1969, 7, 16), DATE(1970, 7, 24), 1)', 368);
118 
119 // Test DB
120-testFormula("=DB(100, 50, 10, 2, 12)", 6.2511);
121+testFormula("=DB(100, 50, 10, 2, 12)", 6.2482428240683285);
122 
123 // Test DDB
124 testFormula("=DDB(100, 50, 10, 2, 2.25)", 17.4375);