Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xuri
excelize
提交
dd6c3905
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,发现更多精彩内容 >>
已验证
提交
dd6c3905
编写于
7月 01, 2022
作者:
xurime
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
ref #65, new formula function: DAVERAGE
上级
eee6607e
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
73 addition
and
57 deletion
+73
-57
.gitignore
.gitignore
+1
-0
calc.go
calc.go
+48
-37
calc_test.go
calc_test.go
+24
-20
未找到文件。
.gitignore
浏览文件 @
dd6c3905
...
...
@@ -12,3 +12,4 @@ test/excelize-*
*.out
*.test
.idea
.DS_Store
calc.go
浏览文件 @
dd6c3905
...
...
@@ -418,6 +418,7 @@ type formulaFuncs struct {
// DATE
// DATEDIF
// DATEVALUE
// DAVERAGE
// DAY
// DAYS
// DAYS360
...
...
@@ -6008,7 +6009,7 @@ func (fn *formulaFuncs) AVERAGE(argsList *list.List) formulaArg {
}
count, sum := fn.countSum(false, args)
if count == 0 {
return newErrorFormulaArg(formulaErrorDIV,
"AVERAGE divide by zero"
)
return newErrorFormulaArg(formulaErrorDIV,
formulaErrorDIV
)
}
return newNumberFormulaArg(sum / count)
}
...
...
@@ -6025,7 +6026,7 @@ func (fn *formulaFuncs) AVERAGEA(argsList *list.List) formulaArg {
}
count, sum := fn.countSum(true, args)
if count == 0 {
return newErrorFormulaArg(formulaErrorDIV,
"AVERAGEA divide by zero"
)
return newErrorFormulaArg(formulaErrorDIV,
formulaErrorDIV
)
}
return newNumberFormulaArg(sum / count)
}
...
...
@@ -6075,7 +6076,7 @@ func (fn *formulaFuncs) AVERAGEIF(argsList *list.List) formulaArg {
}
count, sum := fn.countSum(false, args)
if count == 0 {
return newErrorFormulaArg(formulaErrorDIV,
"AVERAGEIF divide by zero"
)
return newErrorFormulaArg(formulaErrorDIV,
formulaErrorDIV
)
}
return newNumberFormulaArg(sum / count)
}
...
...
@@ -18068,6 +18069,42 @@ func (db *calcDatabase) next() bool {
return matched
}
// database is an implementation of the formula functions DAVERAGE, DMAX and DMIN.
func (fn *formulaFuncs) database(name string, argsList *list.List) formulaArg {
if argsList.Len() != 3 {
return newErrorFormulaArg(formulaErrorVALUE, fmt.Sprintf("%s requires 3 arguments", name))
}
database := argsList.Front().Value.(formulaArg)
field := argsList.Front().Next().Value.(formulaArg)
criteria := argsList.Back().Value.(formulaArg)
db := newCalcDatabase(database, field, criteria)
if db == nil {
return newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE)
}
args := list.New()
for db.next() {
args.PushBack(db.value())
}
switch name {
case "DMAX":
return fn.MAX(args)
case "DMIN":
return fn.MIN(args)
default:
return fn.AVERAGE(args)
}
}
// DAVERAGE function calculates the average (statistical mean) of values in a
// field (column) in a database for selected records, that satisfy
// user-specified criteria. The syntax of the Excel Daverage function is:
//
// DAVERAGE(database,field,criteria)
//
func (fn *formulaFuncs) DAVERAGE(argsList *list.List) formulaArg {
return fn.database("DAVERAGE", argsList)
}
// dcount is an implementation of the formula functions DCOUNT and DCOUNTA.
func (fn *formulaFuncs) dcount(name string, argsList *list.List) formulaArg {
if argsList.Len() < 2 {
...
...
@@ -18081,23 +18118,19 @@ func (fn *formulaFuncs) dcount(name string, argsList *list.List) formulaArg {
if argsList.Len() > 2 {
field = argsList.Front().Next().Value.(formulaArg)
}
var count float64
database := argsList.Front().Value.(formulaArg)
db := newCalcDatabase(database, field, criteria)
if db == nil {
return newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE)
}
args := list.New()
for db.next() {
cell := db.value()
if cell.Value() == "" {
continue
}
if num := cell.ToNumber(); name == "DCOUNT" && num.Type != ArgNumber {
continue
}
count++
args.PushBack(db.value())
}
return newNumberFormulaArg(count)
if name == "DCOUNT" {
return fn.COUNT(args)
}
return fn.COUNTA(args)
}
// DCOUNT function returns the number of cells containing numeric values, in a
...
...
@@ -18122,28 +18155,6 @@ func (fn *formulaFuncs) DCOUNTA(argsList *list.List) formulaArg {
return fn.dcount("DCOUNTA", argsList)
}
// dmaxmin is an implementation of the formula functions DMAX and DMIN.
func (fn *formulaFuncs) dmaxmin(name string, argsList *list.List) formulaArg {
if argsList.Len() != 3 {
return newErrorFormulaArg(formulaErrorVALUE, fmt.Sprintf("%s requires 3 arguments", name))
}
database := argsList.Front().Value.(formulaArg)
field := argsList.Front().Next().Value.(formulaArg)
criteria := argsList.Back().Value.(formulaArg)
db := newCalcDatabase(database, field, criteria)
if db == nil {
return newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE)
}
args := list.New()
for db.next() {
args.PushBack(db.value())
}
if name == "DMAX" {
return fn.MAX(args)
}
return fn.MIN(args)
}
// DMAX function finds the maximum value in a field (column) in a database for
// selected records only. The records to be included in the calculation are
// defined by a set of one or more user-specified criteria. The syntax of the
...
...
@@ -18152,7 +18163,7 @@ func (fn *formulaFuncs) dmaxmin(name string, argsList *list.List) formulaArg {
// DMAX(database,field,criteria)
//
func (fn *formulaFuncs) DMAX(argsList *list.List) formulaArg {
return fn.d
maxmin
("DMAX", argsList)
return fn.d
atabase
("DMAX", argsList)
}
// DMIN function finds the minimum value in a field (column) in a database for
...
...
@@ -18163,5 +18174,5 @@ func (fn *formulaFuncs) DMAX(argsList *list.List) formulaArg {
// DMIN(database,field,criteria)
//
func (fn *formulaFuncs) DMIN(argsList *list.List) formulaArg {
return fn.d
maxmin
("DMIN", argsList)
return fn.d
atabase
("DMIN", argsList)
}
calc_test.go
浏览文件 @
dd6c3905
...
...
@@ -2655,14 +2655,14 @@ func TestCalcCellValue(t *testing.T) {
"=AVEDEV(
\"\"
)"
:
"#VALUE!"
,
"=AVEDEV(1,
\"\"
)"
:
"#VALUE!"
,
// AVERAGE
"=AVERAGE(H1)"
:
"
AVERAGE divide by zero
"
,
"=AVERAGE(H1)"
:
"
#DIV/0!
"
,
// AVERAGEA
"=AVERAGEA(H1)"
:
"
AVERAGEA divide by zero
"
,
"=AVERAGEA(H1)"
:
"
#DIV/0!
"
,
// AVERAGEIF
"=AVERAGEIF()"
:
"AVERAGEIF requires at least 2 arguments"
,
"=AVERAGEIF(H1,
\"\"
)"
:
"
AVERAGEIF divide by zero
"
,
"=AVERAGEIF(D1:D3,
\"
Month
\"
,D1:D3)"
:
"
AVERAGEIF divide by zero
"
,
"=AVERAGEIF(C1:C3,
\"
Month
\"
,D1:D3)"
:
"
AVERAGEIF divide by zero
"
,
"=AVERAGEIF(H1,
\"\"
)"
:
"
#DIV/0!
"
,
"=AVERAGEIF(D1:D3,
\"
Month
\"
,D1:D3)"
:
"
#DIV/0!
"
,
"=AVERAGEIF(C1:C3,
\"
Month
\"
,D1:D3)"
:
"
#DIV/0!
"
,
// BETA.DIST
"=BETA.DIST()"
:
"BETA.DIST requires at least 4 arguments"
,
"=BETA.DIST(0.4,4,5,TRUE,0,1,0)"
:
"BETA.DIST requires at most 6 arguments"
,
...
...
@@ -4603,7 +4603,7 @@ func TestCalcCOVAR(t *testing.T) {
}
}
func
TestCalcD
COUNTandDCOUNTAandDMAXandDMIN
(
t
*
testing
.
T
)
{
func
TestCalcD
atabase
(
t
*
testing
.
T
)
{
cellData
:=
[][]
interface
{}{
{
"Tree"
,
"Height"
,
"Age"
,
"Yield"
,
"Profit"
,
"Height"
},
{
"=Apple"
,
">1000%"
,
nil
,
nil
,
nil
,
"<16"
},
...
...
@@ -4621,20 +4621,21 @@ func TestCalcDCOUNTandDCOUNTAandDMAXandDMIN(t *testing.T) {
assert
.
NoError
(
t
,
f
.
SetCellFormula
(
"Sheet1"
,
"A3"
,
"=
\"
=Pear
\"
"
))
assert
.
NoError
(
t
,
f
.
SetCellFormula
(
"Sheet1"
,
"C8"
,
"=NA()"
))
formulaList
:=
map
[
string
]
string
{
"=DCOUNT(A4:E10,
\"
Age
\"
,A1:F2)"
:
"1"
,
"=DCOUNT(A4:E10,,A1:F2)"
:
"2"
,
"=DCOUNT(A4:E10,
\"
Profit
\"
,A1:F2)"
:
"2"
,
"=DCOUNT(A4:E10,
\"
Tree
\"
,A1:F2)"
:
"0"
,
"=DCOUNT(A4:E10,
\"
Age
\"
,A2:F3)"
:
"0"
,
"=DCOUNTA(A4:E10,
\"
Age
\"
,A1:F2)"
:
"1"
,
"=DCOUNTA(A4:E10,,A1:F2)"
:
"2"
,
"=DCOUNTA(A4:E10,
\"
Profit
\"
,A1:F2)"
:
"2"
,
"=DCOUNTA(A4:E10,
\"
Tree
\"
,A1:F2)"
:
"2"
,
"=DCOUNTA(A4:E10,
\"
Age
\"
,A2:F3)"
:
"0"
,
"=DMAX(A4:E10,
\"
Tree
\"
,A1:F3)"
:
"0"
,
"=DMAX(A4:E10,
\"
Profit
\"
,A1:F3)"
:
"96"
,
"=DMIN(A4:E10,
\"
Tree
\"
,A1:F3)"
:
"0"
,
"=DMIN(A4:E10,
\"
Profit
\"
,A1:F3)"
:
"45"
,
"=DCOUNT(A4:E10,
\"
Age
\"
,A1:F2)"
:
"1"
,
"=DCOUNT(A4:E10,,A1:F2)"
:
"2"
,
"=DCOUNT(A4:E10,
\"
Profit
\"
,A1:F2)"
:
"2"
,
"=DCOUNT(A4:E10,
\"
Tree
\"
,A1:F2)"
:
"0"
,
"=DCOUNT(A4:E10,
\"
Age
\"
,A2:F3)"
:
"0"
,
"=DCOUNTA(A4:E10,
\"
Age
\"
,A1:F2)"
:
"1"
,
"=DCOUNTA(A4:E10,,A1:F2)"
:
"2"
,
"=DCOUNTA(A4:E10,
\"
Profit
\"
,A1:F2)"
:
"2"
,
"=DCOUNTA(A4:E10,
\"
Tree
\"
,A1:F2)"
:
"2"
,
"=DCOUNTA(A4:E10,
\"
Age
\"
,A2:F3)"
:
"0"
,
"=DMAX(A4:E10,
\"
Tree
\"
,A1:F3)"
:
"0"
,
"=DMAX(A4:E10,
\"
Profit
\"
,A1:F3)"
:
"96"
,
"=DMIN(A4:E10,
\"
Tree
\"
,A1:F3)"
:
"0"
,
"=DMIN(A4:E10,
\"
Profit
\"
,A1:F3)"
:
"45"
,
"=DAVERAGE(A4:E10,
\"
Profit
\"
,A1:F3)"
:
"73.25"
,
}
for
formula
,
expected
:=
range
formulaList
{
assert
.
NoError
(
t
,
f
.
SetCellFormula
(
"Sheet1"
,
"A11"
,
formula
))
...
...
@@ -4659,6 +4660,9 @@ func TestCalcDCOUNTandDCOUNTAandDMAXandDMIN(t *testing.T) {
"=DMAX(A4:E10,
\"
x
\"
,A1:F3)"
:
"#VALUE!"
,
"=DMIN()"
:
"DMIN requires 3 arguments"
,
"=DMIN(A4:E10,
\"
x
\"
,A1:F3)"
:
"#VALUE!"
,
"=DAVERAGE()"
:
"DAVERAGE requires 3 arguments"
,
"=DAVERAGE(A4:E10,
\"
x
\"
,A1:F3)"
:
"#VALUE!"
,
"=DAVERAGE(A4:E10,
\"
Tree
\"
,A1:F3)"
:
"#DIV/0!"
,
}
for
formula
,
expected
:=
range
calcError
{
assert
.
NoError
(
t
,
f
.
SetCellFormula
(
"Sheet1"
,
"A11"
,
formula
))
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录