This commit is contained in:
Vyacheslav Zgordan 2019-12-05 18:16:38 +03:00 committed by Gunnsteinn Hall
parent 8fadaaeecf
commit 50980fe02e
4 changed files with 51 additions and 3 deletions

View File

@ -129,7 +129,7 @@ func (f *Format) AddToken(t FmtType, l []byte) {
// string is empty, then General number formatting is used which attempts to mimic
// Excel's general formatting.
func Number(v float64, f string) string {
if f == "" || f == "General" {
if f == "" || f == "General" || f == "@" {
return NumberGeneric(v)
}
fmts := Parse(f)

View File

@ -15,6 +15,7 @@ import (
"unicode"
"github.com/unidoc/unioffice/internal/wildcard"
"github.com/unidoc/unioffice/spreadsheet/format"
)
func init() {
@ -40,6 +41,7 @@ func init() {
RegisterFunction("SEARCH", Search)
RegisterFunctionComplex("SEARCHB", Searchb)
RegisterFunction("T", T)
RegisterFunction("TEXT", Text)
RegisterFunction("TEXTJOIN", TextJoin)
RegisterFunction("_xlfn.TEXTJOIN", TextJoin)
RegisterFunction("TRIM", Trim)
@ -721,3 +723,31 @@ func appendSlices(s0, s1 []string) []string {
}
return s0
}
// Text is an implementation of the Excel TEXT function.
func Text(args []Result) Result {
if len(args) != 2 {
return MakeErrorResult("TEXT requires two arguments")
}
valueResult := args[0]
if valueResult.Type != ResultTypeNumber && valueResult.Type != ResultTypeString && valueResult.Type != ResultTypeEmpty {
return MakeErrorResult("TEXT requires first argument to be a number or string")
}
if args[1].Type != ResultTypeString {
return MakeErrorResult("TEXT requires second argument to be a string")
}
f := args[1].ValueString
switch valueResult.Type {
case ResultTypeNumber:
return MakeStringResult(format.Number(valueResult.ValueNumber, f))
case ResultTypeString:
return MakeStringResult(format.String(valueResult.ValueString, f))
case ResultTypeEmpty:
return MakeStringResult(format.Number(0, f))
case ResultTypeArray, ResultTypeList:
return MakeErrorResultType(ErrorTypeSpill, "TEXT doesn't work with arrays")
default:
return MakeErrorResult("Incorrect argument for TEXT")
}
}

View File

@ -1575,7 +1575,6 @@ func TestIndex(t *testing.T) {
sheet.Cell("A4").SetFormulaRaw(`=INDEX(A1:C3,1,1)`)
sheet.Cell("A5").SetFormulaArray(`=INDEX(A1:C3,2)`)
sheet.Cell("A6").SetFormulaArray(`=INDEX(A1:C3,,2)`)
sheet.Cell("A10").SetFormulaArray(`=INDEX(A1:C3)`)
sheet.RecalculateFormulas()
@ -1586,7 +1585,23 @@ func TestIndex(t *testing.T) {
{`=C5`, `6 ResultTypeNumber`},
{`=A7`, `5 ResultTypeNumber`},
{`=A8`, `8 ResultTypeNumber`},
{`=A10`, `#VALUE! ResultTypeError`},
}
ctx := sheet.FormulaContext()
runTests(t, ctx, td)
}
func TestText(t *testing.T) {
ss := spreadsheet.New()
sheet := ss.AddSheet()
td := []testStruct{
{`=TEXT(A1,"0#.00")`, `00.00 ResultTypeString`},
{`=TEXT(1,"0.00")`, `1.00 ResultTypeString`},
{`=TEXT(12345678,"0.00E+000")`, `1.23E+007 ResultTypeString`},
{`=TEXT(0.987654321,"0.000%")`, `98.765% ResultTypeString`},
{`=TEXT(0.05,"# ??/??")`, `1/20 ResultTypeString`},
}
ctx := sheet.FormulaContext()

View File

@ -158,6 +158,7 @@ const (
ErrorTypeRef
ErrorTypeName
ErrorTypeNum
ErrorTypeSpill
ErrorTypeNA
ErrorTypeDivideByZero
)
@ -176,6 +177,8 @@ func MakeErrorResultType(t ErrorType, msg string) Result {
return Result{Type: ResultTypeError, ValueString: "#NAME?", ErrorMessage: msg}
case ErrorTypeNum:
return Result{Type: ResultTypeError, ValueString: "#NUM!", ErrorMessage: msg}
case ErrorTypeSpill:
return Result{Type: ResultTypeError, ValueString: "#SPILL!", ErrorMessage: msg}
case ErrorTypeNA:
return Result{Type: ResultTypeError, ValueString: "#N/A", ErrorMessage: msg}
case ErrorTypeDivideByZero: