From e4497c494d0150c9e5c4c58e948743dadbf219fb Mon Sep 17 00:00:00 2001 From: Jerry Date: Thu, 25 Jan 2024 14:39:21 +0800 Subject: [PATCH] ref #65, new formula function: DBCS (#1791) Co-authored-by: wujierui --- calc.go | 33 +++++++++++++++++++++++++++++++++ calc_test.go | 15 +++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/calc.go b/calc.go index 2488eda..a6086a0 100644 --- a/calc.go +++ b/calc.go @@ -455,6 +455,7 @@ type formulaFuncs struct { // DAYS // DAYS360 // DB +// DBCS // DCOUNT // DCOUNTA // DDB @@ -13566,6 +13567,38 @@ func (fn *formulaFuncs) concat(name string, argsList *list.List) formulaArg { return newStringFormulaArg(buf.String()) } +// DBCS converts half-width (single-byte) letters within a character string to +// full-width (double-byte) characters. The syntax of the function is: +// +// DBCS(text) +func (fn *formulaFuncs) DBCS(argsList *list.List) formulaArg { + if argsList.Len() != 1 { + return newErrorFormulaArg(formulaErrorVALUE, "DBCS requires 1 argument") + } + arg := argsList.Front().Value.(formulaArg) + if arg.Type == ArgError { + return arg + } + if fn.f.options.CultureInfo == CultureNameZhCN { + var chars []string + for _, r := range arg.Value() { + code := r + if code == 32 { + code = 12288 + } else { + code += 65248 + } + if (code < 32 || code > 126) && r != 165 && code < 65381 { + chars = append(chars, string(code)) + } else { + chars = append(chars, string(r)) + } + } + return newStringFormulaArg(strings.Join(chars, "")) + } + return arg +} + // EXACT function tests if two supplied text strings or values are exactly // equal and if so, returns TRUE; Otherwise, the function returns FALSE. The // function is case-sensitive. The syntax of the function is: diff --git a/calc_test.go b/calc_test.go index 99b1eb2..83b578f 100644 --- a/calc_test.go +++ b/calc_test.go @@ -1723,6 +1723,10 @@ func TestCalcCellValue(t *testing.T) { "=CONCATENATE(TRUE(),1,FALSE(),\"0\",INT(2))": "TRUE1FALSE02", "=CONCATENATE(MUNIT(2))": "1001", "=CONCATENATE(A1:B2)": "1425", + // DBCS + "=DBCS(\"\")": "", + "=DBCS(123.456)": "123.456", + "=DBCS(\"123.456\")": "123.456", // EXACT "=EXACT(1,\"1\")": "TRUE", "=EXACT(1,1)": "TRUE", @@ -3836,6 +3840,9 @@ func TestCalcCellValue(t *testing.T) { // CONCATENATE "=CONCATENATE(NA())": {"#N/A", "#N/A"}, "=CONCATENATE(1,1/0)": {"#DIV/0!", "#DIV/0!"}, + // DBCS + "=DBCS(NA())": {"#N/A", "#N/A"}, + "=DBCS()": {"#VALUE!", "DBCS requires 1 argument"}, // EXACT "=EXACT()": {"#VALUE!", "EXACT requires 2 arguments"}, "=EXACT(1,2,3)": {"#VALUE!", "EXACT requires 2 arguments"}, @@ -5194,6 +5201,14 @@ func TestCalcDatabase(t *testing.T) { } } +func TestCalcDBCS(t *testing.T) { + f := NewFile(Options{CultureInfo: CultureNameZhCN}) + assert.NoError(t, f.SetCellFormula("Sheet1", "A1", "=DBCS(\"`~·!@#$¥%…^&*()_-+=[]{}\\|;:'\"\"<,>.?/01234567890 abc ABC \uff65\uff9e\uff9f \uff74\uff78\uff7e\uff99\")")) + result, err := f.CalcCellValue("Sheet1", "A1") + assert.NoError(t, err) + assert.Equal(t, "\uff40\uff5e\u00b7\uff01\uff20\uff03\uff04\u00a5\uff05\u2026\uff3e\uff06\uff0a\uff08\uff09\uff3f\uff0d\uff0b\uff1d\uff3b\uff3d\uff5b\uff5d\uff3c\uff5c\uff1b\uff1a\uff07\uff02\uff1c\uff0c\uff1e\uff0e\uff1f\uff0f\uff10\uff11\uff12\uff13\uff14\uff15\uff16\uff17\uff18\uff19\uff10\u3000\uff41\uff42\uff43\u3000\uff21\uff22\uff23\u3000\uff65\uff9e\uff9f\u3000\uff74\uff78\uff7e\uff99", result) +} + func TestCalcFORMULATEXT(t *testing.T) { f, formulaText := NewFile(), "=SUM(B1:C1)" assert.NoError(t, f.SetCellFormula("Sheet1", "A1", formulaText)) -- GitLab