فهرست منبع

This closes #809, and add new fn: HARMEAN

xuri 4 سال پیش
والد
کامیت
e1abdb0e5a
4فایلهای تغییر یافته به همراه46 افزوده شده و 4 حذف شده
  1. 35 0
      calc.go
  2. 7 0
      calc_test.go
  3. 2 2
      styles.go
  4. 2 2
      xmlStyles.go

+ 35 - 0
calc.go

@@ -282,6 +282,7 @@ var tokenPriority = map[string]int{
 //    GAMMA
 //    GAMMALN
 //    GCD
+//    HARMEAN
 //    HEX2BIN
 //    HEX2DEC
 //    HEX2OCT
@@ -3927,6 +3928,40 @@ func (fn *formulaFuncs) GAMMALN(argsList *list.List) formulaArg {
 	return newErrorFormulaArg(formulaErrorVALUE, "GAMMALN requires 1 numeric argument")
 }
 
+// HARMEAN function calculates the harmonic mean of a supplied set of values.
+// The syntax of the function is:
+//
+//    HARMEAN(number1,[number2],...)
+//
+func (fn *formulaFuncs) HARMEAN(argsList *list.List) formulaArg {
+	if argsList.Len() < 1 {
+		return newErrorFormulaArg(formulaErrorVALUE, "HARMEAN requires at least 1 argument")
+	}
+	if min := fn.MIN(argsList); min.Number < 0 {
+		return newErrorFormulaArg(formulaErrorNA, formulaErrorNA)
+	}
+	number, val, cnt := 0.0, 0.0, 0.0
+	for token := argsList.Front(); token != nil; token = token.Next() {
+		arg := token.Value.(formulaArg)
+		switch arg.Type {
+		case ArgString:
+			num := arg.ToNumber()
+			if num.Type != ArgNumber {
+				continue
+			}
+			number = num.Number
+		case ArgNumber:
+			number = arg.Number
+		}
+		if number <= 0 {
+			return newErrorFormulaArg(formulaErrorNA, formulaErrorNA)
+		}
+		val += (1 / number)
+		cnt++
+	}
+	return newNumberFormulaArg(1 / (val / cnt))
+}
+
 // KURT function calculates the kurtosis of a supplied set of values. The
 // syntax of the function is:
 //

+ 7 - 0
calc_test.go

@@ -605,6 +605,9 @@ func TestCalcCellValue(t *testing.T) {
 		// GAMMALN
 		"=GAMMALN(4.5)":    "2.453736570842443",
 		"=GAMMALN(INT(1))": "0",
+		// HARMEAN
+		"=HARMEAN(2.5,3,0.5,1,3)":               "1.229508196721312",
+		"=HARMEAN(\"2.5\",3,0.5,1,INT(3),\"\")": "1.229508196721312",
 		// KURT
 		"=KURT(F1:F9)":           "-1.033503502551368",
 		"=KURT(F1,F2:F9)":        "-1.033503502551368",
@@ -1393,6 +1396,10 @@ func TestCalcCellValue(t *testing.T) {
 		"=GAMMALN(F1)":     "GAMMALN requires 1 numeric argument",
 		"=GAMMALN(0)":      "#N/A",
 		"=GAMMALN(INT(0))": "#N/A",
+		// HARMEAN
+		"=HARMEAN()":   "HARMEAN requires at least 1 argument",
+		"=HARMEAN(-1)": "#N/A",
+		"=HARMEAN(0)":  "#N/A",
 		// KURT
 		"=KURT()":          "KURT requires at least 1 argument",
 		"=KURT(F1,INT(1))": "#DIV/0!",

+ 2 - 2
styles.go

@@ -2472,8 +2472,8 @@ func newAlignment(style *Style) *xlsxAlignment {
 func newProtection(style *Style) *xlsxProtection {
 	var protection xlsxProtection
 	if style.Protection != nil {
-		protection.Hidden = style.Protection.Hidden
-		protection.Locked = style.Protection.Locked
+		protection.Hidden = &style.Protection.Hidden
+		protection.Locked = &style.Protection.Locked
 	}
 	return &protection
 }

+ 2 - 2
xmlStyles.go

@@ -49,8 +49,8 @@ type xlsxAlignment struct {
 // set. The cell protection properties do not take effect unless the sheet has
 // been protected.
 type xlsxProtection struct {
-	Hidden bool `xml:"hidden,attr"`
-	Locked bool `xml:"locked,attr"`
+	Hidden *bool `xml:"hidden,attr"`
+	Locked *bool `xml:"locked,attr"`
 }
 
 // xlsxLine expresses a single set of cell border.