Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xuri
excelize
提交
ad90cea7
excelize
项目概览
xuri
/
excelize
通知
13
Star
2
Fork
4
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
excelize
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
未验证
提交
ad90cea7
编写于
2月 15, 2023
作者:
J
jaby
提交者:
GitHub
2月 15, 2023
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
This closes #1469, fix cell resolver caused incorrect calculation result (#1470)
上级
363fa940
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
45 addition
and
18 deletion
+45
-18
calc.go
calc.go
+27
-17
calc_test.go
calc_test.go
+18
-1
未找到文件。
calc.go
浏览文件 @
ad90cea7
...
...
@@ -197,8 +197,10 @@ var (
// calcContext defines the formula execution context.
type calcContext struct {
sync.Mutex
entry string
iterations map[string]uint
entry string
maxCalcIterations uint
iterations map[string]uint
iterationsCache map[string]formulaArg
}
// cellRef defines the structure of a cell reference.
...
...
@@ -774,8 +776,10 @@ func (f *File) CalcCellValue(sheet, cell string, opts ...Options) (result string
token formulaArg
)
if token, err = f.calcCellValue(&calcContext{
entry: fmt.Sprintf("%s!%s", sheet, cell),
iterations: make(map[string]uint),
entry: fmt.Sprintf("%s!%s", sheet, cell),
maxCalcIterations: getOptions(opts...).MaxCalcIterations,
iterations: make(map[string]uint),
iterationsCache: make(map[string]formulaArg),
}, sheet, cell); err != nil {
return
}
...
...
@@ -1527,17 +1531,6 @@ func (f *File) cellResolver(ctx *calcContext, sheet, cell string) (formulaArg, e
value string
err error
)
ref := fmt.Sprintf("%s!%s", sheet, cell)
if formula, _ := f.GetCellFormula(sheet, cell); len(formula) != 0 {
ctx.Lock()
if ctx.entry != ref && ctx.iterations[ref] <= f.options.MaxCalcIterations {
ctx.iterations[ref]++
ctx.Unlock()
arg, _ = f.calcCellValue(ctx, sheet, cell)
return arg, nil
}
ctx.Unlock()
}
if value, err = f.GetCellValue(sheet, cell, Options{RawCellValue: true}); err != nil {
return arg, err
}
...
...
@@ -1551,8 +1544,25 @@ func (f *File) cellResolver(ctx *calcContext, sheet, cell string) (formulaArg, e
return newEmptyFormulaArg(), err
}
return arg.ToNumber(), err
default
:
case CellTypeInlineString, CellTypeSharedString
:
return arg, err
case CellTypeFormula:
ref := fmt.Sprintf("%s!%s", sheet, cell)
if ctx.entry != ref {
ctx.Lock()
if ctx.iterations[ref] <= ctx.maxCalcIterations {
ctx.iterations[ref]++
ctx.Unlock()
arg, _ = f.calcCellValue(ctx, sheet, cell)
ctx.iterationsCache[ref] = arg
return arg, nil
}
ctx.Unlock()
return ctx.iterationsCache[ref], nil
}
fallthrough
default:
return newEmptyFormulaArg(), err
}
}
...
...
@@ -7746,7 +7756,7 @@ func (fn *formulaFuncs) COUNTBLANK(argsList *list.List) formulaArg {
}
var count float64
for _, cell := range argsList.Front().Value.(formulaArg).ToList() {
if cell.
Value() == ""
{
if cell.
Type == ArgEmpty
{
count++
}
}
...
...
calc_test.go
浏览文件 @
ad90cea7
...
...
@@ -1023,7 +1023,7 @@ func TestCalcCellValue(t *testing.T) {
"=COUNTBLANK(MUNIT(1))"
:
"0"
,
"=COUNTBLANK(1)"
:
"0"
,
"=COUNTBLANK(B1:C1)"
:
"1"
,
"=COUNTBLANK(C1)"
:
"
1
"
,
"=COUNTBLANK(C1)"
:
"
0
"
,
// COUNTIF
"=COUNTIF(D1:D9,
\"
Jan
\"
)"
:
"4"
,
"=COUNTIF(D1:D9,
\"
<>Jan
\"
)"
:
"5"
,
...
...
@@ -5871,3 +5871,20 @@ func TestCalcColRowQRDecomposition(t *testing.T) {
assert
.
False
(
t
,
calcRowQRDecomposition
([][]
float64
{{
0
,
0
},
{
0
,
0
}},
[]
float64
{
0
,
0
},
1
,
0
))
assert
.
False
(
t
,
calcColQRDecomposition
([][]
float64
{{
0
,
0
},
{
0
,
0
}},
[]
float64
{
0
,
0
},
1
,
0
))
}
func
TestCalcCellResolver
(
t
*
testing
.
T
)
{
f
:=
NewFile
()
// Test reference a cell multiple times in a formula
assert
.
NoError
(
t
,
f
.
SetCellValue
(
"Sheet1"
,
"A1"
,
"VALUE1"
))
assert
.
NoError
(
t
,
f
.
SetCellFormula
(
"Sheet1"
,
"A2"
,
"=A1"
))
for
formula
,
expected
:=
range
map
[
string
]
string
{
"=CONCATENATE(A1,
\"
_
\"
,A1)"
:
"VALUE1_VALUE1"
,
"=CONCATENATE(A1,
\"
_
\"
,A2)"
:
"VALUE1_VALUE1"
,
"=CONCATENATE(A2,
\"
_
\"
,A2)"
:
"VALUE1_VALUE1"
,
}
{
assert
.
NoError
(
t
,
f
.
SetCellFormula
(
"Sheet1"
,
"A3"
,
formula
))
result
,
err
:=
f
.
CalcCellValue
(
"Sheet1"
,
"A3"
)
assert
.
NoError
(
t
,
err
,
formula
)
assert
.
Equal
(
t
,
expected
,
result
,
formula
)
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录