Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
S
sdkjs
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Boris Kocherov
sdkjs
Commits
08a5ed40
Commit
08a5ed40
authored
May 29, 2017
by
Boris Kocherov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
add CUBEMEMBER, CUBEVALUE
use lazy calculation
parent
6ee6d7fe
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
631 additions
and
24 deletions
+631
-24
cell/model/FormulaObjects/cubeFunctions.js
cell/model/FormulaObjects/cubeFunctions.js
+456
-7
cell/model/FormulaObjects/parserFormula.js
cell/model/FormulaObjects/parserFormula.js
+134
-4
cell/model/Workbook.js
cell/model/Workbook.js
+41
-13
No files found.
cell/model/FormulaObjects/cubeFunctions.js
View file @
08a5ed40
/* jshint -W040 */
/*
* (c) Copyright Ascensio System SIA 2010-2017
*
...
...
@@ -38,15 +39,298 @@
*/
function
(
window
,
undefined
)
{
var
cBaseFunction
=
AscCommonExcel
.
cBaseFunction
;
var
cFormulaFunctionGroup
=
AscCommonExcel
.
cFormulaFunctionGroup
;
var
cFormulaFunctionGroup
=
AscCommonExcel
.
cFormulaFunctionGroup
,
cElementType
=
AscCommonExcel
.
cElementType
,
cNumber
=
AscCommonExcel
.
cNumber
,
cString
=
AscCommonExcel
.
cString
,
cBool
=
AscCommonExcel
.
cBool
,
cError
=
AscCommonExcel
.
cError
,
cErrorType
=
AscCommonExcel
.
cErrorType
,
cArea
=
AscCommonExcel
.
cArea
,
cArea3D
=
AscCommonExcel
.
cArea3D
,
cRef
=
AscCommonExcel
.
cRef
,
cRef3D
=
AscCommonExcel
.
cRef3D
,
cEmpty
=
AscCommonExcel
.
cEmpty
,
cArray
=
AscCommonExcel
.
cArray
,
cubeScheme
=
{};
cFormulaFunctionGroup
[
'
Cube
'
]
=
cFormulaFunctionGroup
[
'
Cube
'
]
||
[];
cFormulaFunctionGroup
[
'
Cube
'
]
.
push
(
cCUBEKPIMEMBER
,
cCUBEMEMBER
,
cCUBEMEMBERPROPERTY
,
cCUBERANKEDMEMBER
,
cCUBESET
,
cFormulaFunctionGroup
.
Cube
=
cFormulaFunctionGroup
.
Cube
||
[];
cFormulaFunctionGroup
.
Cube
.
push
(
cCUBEKPIMEMBER
,
cCUBEMEMBER
,
cCUBEMEMBERPROPERTY
,
cCUBERANKEDMEMBER
,
cCUBESET
,
cCUBESETCOUNT
,
cCUBEVALUE
);
cFormulaFunctionGroup
[
'
NotRealised
'
]
=
cFormulaFunctionGroup
[
'
NotRealised
'
]
||
[];
cFormulaFunctionGroup
[
'
NotRealised
'
].
push
(
cCUBEKPIMEMBER
,
cCUBEMEMBER
,
cCUBEMEMBERPROPERTY
,
cCUBERANKEDMEMBER
,
cCUBESET
,
cCUBESETCOUNT
,
cCUBEVALUE
);
cFormulaFunctionGroup
.
NotRealised
=
cFormulaFunctionGroup
.
NotRealised
||
[];
cFormulaFunctionGroup
.
NotRealised
.
push
(
cCUBEKPIMEMBER
,
cCUBEMEMBERPROPERTY
,
cCUBERANKEDMEMBER
,
cCUBESET
,
cCUBESETCOUNT
);
var
xmla
=
new
Xmla
({
// listeners: {
// events: Xmla.EVENT_ERROR,
// handler: function (eventName, eventData, xmla) {
// console.log(eventData.exception);
// // alert(
// // "Snap, an error occurred: " + eventData.exception.message + " (" + eventData.exception.code + ")" +
// // (eventData.exception.code === Xmla.Exception.HTTP_ERROR_CDE
// // ? "\nstatus: " + eventData.exception.data.status + "; statusText: " + eventData.exception.data.statusText
// // : "")
// // );
// }
// },
async
:
true
});
function
xmla_request
(
func
,
prop
)
{
var
xmla
=
new
Xmla
({
async
:
true
});
// return function () {
return
new
RSVP
.
Queue
()
.
push
(
function
()
{
return
new
RSVP
.
Promise
(
function
(
resolve
,
reject
)
{
prop
.
success
=
function
(
xmla
,
options
,
response
)
{
resolve
(
response
);
};
prop
.
error
=
function
(
xmla
,
options
,
response
)
{
reject
(
response
);
};
xmla
[
func
](
prop
);
});
});
}
function
xmla_request_retry
(
func
,
prop
)
{
return
xmla_request
(
func
,
prop
)
.
push
(
undefined
,
function
(
response
)
{
// fix mondrian Internal and Sql errors
if
(
response
)
{
switch
(
response
.
code
)
{
case
"
SOAP-ENV:Server.00HSBE02
"
:
case
"
SOAP-ENV:00UE001.Internal Error
"
:
return
xmla_request
(
func
,
prop
);
}
}
throw
response
;
});
}
function
getProperties
(
connection
)
{
var
connections
=
{
xmla
:
{
prop
:
{
url
:
"
https://d1.erp5.ru/saiku/xmla
"
,
properties
:
{
DataSourceInfo
:
"
FoodMart
"
,
Catalog
:
"
FoodMart
"
}
},
cube
:
"
Sales
"
}
};
connection
=
connections
[
connection
];
connection
=
JSON
.
parse
(
JSON
.
stringify
(
connection
));
return
connection
;
}
function
getScheme
(
connection
)
{
var
scheme
=
cubeScheme
[
connection
];
if
(
scheme
)
{
return
scheme
;
}
else
{
scheme
=
{
members
:
{},
hierarchies
:
{}
};
cubeScheme
[
connection
]
=
scheme
;
return
scheme
;
}
}
function
getCell
(
arg0
)
{
if
(
arg0
instanceof
cArray
)
{
arg0
=
arg0
.
getElement
(
0
);
// } else if (arg0 instanceof cArea || arg0 instanceof cArea3D) {
// arg0 = arg0.cross(arguments[1].bbox);
}
else
if
(
arg0
instanceof
cRef
||
arg0
instanceof
cRef3D
)
{
arg0
=
arg0
.
getValue
();
}
return
arg0
;
}
function
parseArgs
(
mdx_array
)
{
return
function
()
{
var
members
=
[];
function
stringForge
(
value
)
{
var
array
;
if
(
value
.
cube_value
)
{
array
=
value
.
cube_value
;
}
else
{
array
=
value
.
value
.
split
(
'
,
'
);
}
if
(
array
.
length
>
0
)
{
// filter members already existed
members
=
members
.
filter
(
function
(
i
)
{
return
array
.
indexOf
(
i
)
===
-
1
;
});
members
=
members
.
concat
(
array
);
}
}
function
cellForge
(
cell
)
{
if
(
cell
)
{
if
(
cell
.
oValue
.
type
===
cElementType
.
error
)
{
// debugger;
throw
"
refenced cell contain error
"
;
}
if
(
cell
.
formulaParsed
&&
cell
.
formulaParsed
.
value
)
{
stringForge
(
cell
.
formulaParsed
.
value
);
}
else
{
stringForge
({
value
:
cell
.
getValue
()});
}
}
}
mdx_array
.
forEach
(
function
(
element
)
{
switch
(
element
.
type
)
{
case
cElementType
.
cellsRange
:
case
cElementType
.
cellsRange3D
:
case
cElementType
.
array
:
element
.
foreach
(
cellForge
);
break
;
default
:
if
(
element
instanceof
cRef
||
element
instanceof
cRef3D
)
{
element
.
getRange
().
getCells
().
forEach
(
cellForge
);
}
else
{
stringForge
(
element
);
}
}
});
return
members
;
};
}
var
AddCubeValueCalculate
=
(
function
()
{
var
deferred
=
RSVP
.
defer
(),
cells
=
[];
return
function
(
cell_id
)
{
if
(
cells
.
indexOf
(
cell_id
)
===
-
1
)
{
cells
.
push
(
cell_id
);
}
// console.log('+ ' + cells);
return
function
()
{
var
i
=
cells
.
indexOf
(
cell_id
);
if
(
i
!==
-
1
)
{
cells
.
splice
(
i
,
1
);
}
// console.log('-' + cells);
if
(
cells
.
length
===
0
)
{
deferred
.
resolve
();
deferred
=
RSVP
.
defer
();
return
{};
}
return
deferred
.
promise
;
};
};
})();
function
execute
(
connection
)
{
var
scheme
=
getScheme
(
connection
);
if
(
!
scheme
.
execute
)
{
scheme
.
execute
=
RSVP
.
defer
();
new
RSVP
.
Queue
()
.
push
(
function
()
{
var
settings
=
getProperties
(
connection
),
prop
=
settings
.
prop
,
hierarchies
=
scheme
.
hierarchies
,
hierarchy
,
mdx
=
[];
for
(
hierarchy
in
hierarchies
)
{
mdx
.
push
(
"
{
"
+
hierarchies
[
hierarchy
].
join
(
"
,
"
)
+
"
}
"
);
}
prop
.
statement
=
"
SELECT
"
+
mdx
.
join
(
"
*
"
)
+
"
ON 0 FROM [
"
+
settings
.
cube
+
"
]
"
;
return
xmla_request
(
"
execute
"
,
prop
);
})
.
push
(
function
(
dataset
)
{
var
cellset
=
dataset
.
getCellset
(),
axis_count
=
dataset
.
axisCount
(),
cell_id
=
0
,
axis_id
,
axis
,
cube
=
{
axes
:
{
length
:
axis_count
},
members
:
{},
hierarchies
:
{
length
:
0
},
cells
:
[]
};
function
collectAxes
(
axisIndex
,
parent_members
)
{
var
member
;
if
(
typeof
(
axisIndex
)
===
"
undefined
"
)
{
axisIndex
=
axis_count
-
1
;
parent_members
=
[];
}
axis
=
dataset
.
getAxis
(
axisIndex
);
axis
.
eachTuple
(
function
(
tuple
)
{
var
coordinate_tuple
=
[];
this
.
eachHierarchy
(
function
(
hierarchy
)
{
member
=
this
.
member
();
coordinate_tuple
.
push
(
member
.
UName
);
});
if
(
axisIndex
)
{
collectAxes
(
axisIndex
-
1
,
parent_members
.
concat
(
coordinate_tuple
));
}
else
{
console
.
log
(
parent_members
.
concat
(
coordinate_tuple
)
+
'
-
'
+
cube
.
cells
[
cell_id
]);
cell_id
++
;
}
});
axis
.
reset
();
}
for
(
axis_id
=
0
;
axis_id
<
axis_count
;
axis_id
++
)
{
axis
=
dataset
.
getAxis
(
axis_id
);
cube
.
axes
[
axis_id
]
=
{
tuples
:
{},
length
:
0
};
axis
.
eachTuple
(
function
(
tuple
)
{
var
coordinate_tuple
=
[];
axis
.
eachHierarchy
(
function
()
{
var
member
=
this
.
member
();
if
(
!
cube
.
members
.
hasOwnProperty
(
member
.
UName
))
{
cube
.
members
[
member
.
UName
]
=
member
;
}
coordinate_tuple
.
push
(
member
.
UName
);
});
cube
.
axes
[
axis_id
].
tuples
[
coordinate_tuple
.
join
(
'
,
'
)]
=
tuple
.
index
;
cube
.
axes
[
axis_id
].
length
++
;
});
axis
.
eachHierarchy
(
function
(
hierarchy
)
{
cube
.
hierarchies
[
hierarchy
.
name
]
=
{
axis_id
:
axis_id
,
tuple_id
:
hierarchy
.
index
,
name
:
hierarchy
.
name
};
cube
.
hierarchies
[
cube
.
hierarchies
.
length
]
=
cube
.
hierarchies
[
hierarchy
.
name
];
cube
.
hierarchies
[
''
+
axis_id
+
'
,
'
+
hierarchy
.
index
]
=
cube
.
hierarchies
[
hierarchy
.
name
];
cube
.
hierarchies
.
length
++
;
});
}
do
{
cube
.
cells
[
cellset
.
cellOrdinal
()]
=
cellset
.
cellValue
();
}
while
(
cellset
.
nextCell
()
>
0
);
collectAxes
();
scheme
.
cube
=
cube
;
scheme
.
execute
.
resolve
(
cube
);
scheme
.
execute
=
null
;
scheme
.
hierarchies
=
[];
})
.
push
(
undefined
,
function
()
{
scheme
.
execute
=
null
;
scheme
.
hierarchies
=
[];
});
}
return
scheme
.
execute
.
promise
;
}
/**
* @constructor
...
...
@@ -73,6 +357,78 @@
cCUBEMEMBER
.
prototype
=
Object
.
create
(
cBaseFunction
.
prototype
);
cCUBEMEMBER
.
prototype
.
constructor
=
cCUBEMEMBER
;
cCUBEMEMBER
.
prototype
.
argumentsMin
=
2
;
cCUBEMEMBER
.
prototype
.
argumentsMax
=
3
;
cCUBEMEMBER
.
prototype
.
CalculateLazy
=
function
(
queue
)
{
var
connection
,
caption
;
return
queue
.
push
(
function
(
arg
)
{
connection
=
getCell
(
arg
[
0
]);
caption
=
getCell
(
arg
[
2
]);
if
(
caption
)
{
caption
=
caption
.
getValue
();
}
return
parseArgs
([
arg
[
1
]])();
})
.
push
(
function
(
members
)
{
var
promises
=
[],
i
;
function
discoverMember
(
connection
,
member_name
)
{
var
settings
=
getProperties
(
connection
),
prop
=
settings
.
prop
;
prop
.
restrictions
=
{
// 'CATALOG_NAME': 'FoodMart',
'
MEMBER_UNIQUE_NAME
'
:
member_name
,
'
CUBE_NAME
'
:
settings
.
cube
};
return
xmla_request_retry
(
"
discoverMDMembers
"
,
prop
)
.
push
(
function
(
response
)
{
if
(
response
.
numRows
>
0
)
{
return
response
;
}
else
{
throw
"
member not found
"
;
}
});
}
for
(
i
=
0
;
i
<
members
.
length
;
i
++
)
{
if
(
members
[
i
])
{
promises
.
push
(
discoverMember
(
connection
,
members
[
i
]));
}
}
return
RSVP
.
all
(
promises
);
})
.
push
(
function
(
responses
)
{
var
last_id
=
responses
.
length
-
1
,
ret
,
scheme
=
getScheme
(
connection
);
if
(
!
caption
)
{
caption
=
responses
[
last_id
].
getMemberCaption
();
}
ret
=
new
cString
(
caption
);
ret
.
ca
=
true
;
ret
.
cube_value
=
responses
.
map
(
function
(
r
)
{
var
uname
=
r
.
getMemberUniqueName
(),
member
=
scheme
.
members
[
uname
];
if
(
!
member
)
{
scheme
.
members
[
uname
]
=
{
h
:
r
.
getHierarchyUniqueName
()};
}
return
uname
;
});
return
ret
;
})
.
push
(
undefined
,
function
()
{
return
new
cError
(
cErrorType
.
not_available
);
});
};
cCUBEMEMBER
.
prototype
.
getInfo
=
function
()
{
return
{
name
:
this
.
name
,
args
:
"
( x )
"
};
};
/**
* @constructor
...
...
@@ -138,4 +494,97 @@
cCUBEVALUE
.
prototype
=
Object
.
create
(
cBaseFunction
.
prototype
);
cCUBEVALUE
.
prototype
.
constructor
=
cCUBEVALUE
;
})(
window
);
cCUBEVALUE
.
prototype
.
argumentsMin
=
2
;
cCUBEVALUE
.
prototype
.
argumentsMax
=
5
;
cCUBEVALUE
.
prototype
.
CalculateLazy
=
function
(
queue
,
range
)
{
var
scheme
,
connection
,
members
,
current_cell_id
=
range
.
getCells
()[
0
].
getId
(),
waiter
=
AddCubeValueCalculate
(
current_cell_id
);
return
queue
.
push
(
function
(
arg
)
{
connection
=
getCell
(
arg
[
0
]);
scheme
=
getScheme
(
connection
);
return
parseArgs
(
arg
.
slice
(
1
))();
})
.
push
(
function
(
m
)
{
members
=
m
;
members
.
forEach
(
function
(
member
)
{
var
h
;
h
=
scheme
.
hierarchies
[
scheme
.
members
[
member
].
h
];
if
(
!
h
)
{
h
=
[];
scheme
.
hierarchies
[
scheme
.
members
[
member
].
h
]
=
h
;
}
if
(
h
.
indexOf
(
member
)
===
-
1
)
{
h
.
push
(
member
);
}
});
return
waiter
();
})
.
push
(
function
()
{
return
execute
(
connection
);
})
.
push
(
function
(
cube
)
{
var
cell_id
=
0
,
p_d
=
1
,
h
,
member_path
,
coordinate
=
[],
i
,
ret
;
for
(
i
=
0
;
i
<
cube
.
hierarchies
.
length
;
i
++
)
{
h
=
cube
.
hierarchies
[
i
];
coordinate
[
h
.
axis_id
]
=
[];
coordinate
[
h
.
axis_id
][
h
.
tuple_id
]
=
null
;
}
for
(
i
=
0
;
i
<
members
.
length
;
i
++
)
{
member_path
=
members
[
i
];
h
=
cube
.
members
[
member_path
];
if
(
h
===
undefined
)
{
throw
"
query result not contain data for member:
"
+
member_path
;
}
h
=
h
.
hierarchy
;
h
=
cube
.
hierarchies
[
h
];
coordinate
[
h
.
axis_id
][
h
.
tuple_id
]
=
member_path
;
}
coordinate
=
coordinate
.
map
(
function
(
axis
,
axis_id
)
{
axis
.
forEach
(
function
(
h
,
h_id
)
{
if
(
h
===
null
)
{
throw
"
Axis:
"
+
axis_id
+
"
hierarchy:
"
+
cube
.
hierarchies
[
axis_id
+
'
,
'
+
h_id
].
name
+
"
not determinated
"
;
}
});
return
axis
.
join
(
'
,
'
);
});
coordinate
.
forEach
(
function
(
tuple
,
axis_id
)
{
var
axis
=
cube
.
axes
[
axis_id
];
cell_id
=
p_d
*
axis
.
tuples
[
tuple
]
+
cell_id
;
p_d
=
p_d
*
axis
.
length
;
});
ret
=
new
cNumber
(
cube
.
cells
[
cell_id
]);
ret
.
ca
=
true
;
return
ret
;
})
.
push
(
undefined
,
function
(
error
)
{
console
.
log
(
error
,
current_cell_id
);
return
waiter
()
.
then
(
function
()
{
var
ret
=
new
cError
(
cErrorType
.
not_available
);
ret
.
ca
=
true
;
return
ret
;
});
});
};
// cCUBEVALUE.prototype.Calculate = cCUBEVALUE.prototype.CalculateLazy
cCUBEVALUE
.
prototype
.
getInfo
=
function
()
{
return
{
name
:
this
.
name
,
args
:
"
( connection, member1, member2, .. )
"
};
};
})
(
window
);
cell/model/FormulaObjects/parserFormula.js
View file @
08a5ed40
...
...
@@ -670,6 +670,112 @@ parserHelp.setDigitSeparator(AscCommon.g_oDefaultCultureInfo.NumberDecimalSepara
cBaseType
.
prototype
.
toLocaleString
=
function
()
{
return
this
.
toString
();
};
cBaseType
.
prototype
.
CalculatePromise
=
function
(
arg
,
opt_bbox
,
isDefName
,
ws
)
{
// depromise args
var
t
=
this
,
lazy_formulas
=
[],
lazy_found
;
function
check_args_promise
()
{
var
promise_flag
=
false
,
element
,
length
,
i
;
function
cellForge
(
cell
)
{
if
(
cell
&&
cell
.
formulaParsed
&&
(
cell
.
formulaParsed
.
lazy_value
||
cell
.
formulaParsed
.
queue
))
{
promise_flag
=
true
;
lazy_formulas
.
push
(
cell
.
formulaParsed
);
}
}
for
(
i
=
0
,
length
=
arg
.
length
;
i
<
length
;
++
i
)
{
element
=
arg
[
i
];
if
(
typeof
element
===
"
function
"
)
{
promise_flag
=
true
;
}
if
(
element
instanceof
cArea
||
element
instanceof
cArea3D
)
{
element
.
foreach
(
cellForge
);
}
if
(
element
instanceof
cRef
||
element
instanceof
cRef3D
)
{
element
.
getRange
().
getCells
().
forEach
(
cellForge
);
}
}
return
promise_flag
;
}
lazy_found
=
check_args_promise
();
if
(
t
.
CalculateLazy
)
{
return
function
()
{
var
queue
=
new
RSVP
.
Queue
();
if
(
lazy_formulas
.
length
>
0
)
{
lazy_formulas
.
forEach
(
function
(
formula
)
{
var
lazy
=
formula
.
lazy_value
;
if
(
lazy
)
{
// if value lazy run it
lazy
();
}
if
(
formula
.
queue
)
{
// add dependence from already
// running but not computed lazy
queue
.
push
(
function
()
{
return
formula
.
queue
;
});
}
});
}
queue
.
push
(
function
()
{
return
RSVP
.
all
(
arg
.
map
(
function
(
z
)
{
if
(
typeof
z
===
"
function
"
)
{
return
z
();
}
else
{
return
z
;
}
}));
});
return
t
.
CalculateLazy
(
queue
,
opt_bbox
,
isDefName
,
ws
);
};
}
else
{
if
(
lazy_found
)
{
return
function
()
{
var
queue
=
new
RSVP
.
Queue
();
if
(
lazy_formulas
.
length
>
0
)
{
lazy_formulas
.
forEach
(
function
(
formula
)
{
var
lazy
=
formula
.
lazy_value
;
if
(
lazy
)
{
// if value lazy add it dependence list
lazy
();
}
if
(
formula
.
queue
)
{
// add dependence from already
// running but not computed lazy
queue
.
push
(
function
()
{
return
formula
.
queue
;
});
}
});
}
return
queue
.
push
(
function
()
{
return
RSVP
.
all
(
arg
.
map
(
function
(
z
)
{
if
(
typeof
z
===
"
function
"
)
{
return
z
();
}
else
{
return
z
;
}
}));
})
.
push
(
function
(
arg
)
{
return
t
.
Calculate
(
arg
,
opt_bbox
,
isDefName
,
ws
);
});
};
}
else
{
return
t
.
Calculate
(
arg
,
opt_bbox
,
isDefName
,
ws
);
}
}
};
/*Basic types of an elements used into formulas*/
/**
...
...
@@ -2347,6 +2453,7 @@ parserHelp.setDigitSeparator(AscCommon.g_oDefaultCultureInfo.NumberDecimalSepara
cBaseOperator
.
prototype
.
Calculate
=
function
()
{
return
null
;
};
cBaseOperator
.
prototype
.
CalculatePromise
=
cBaseType
.
prototype
.
CalculatePromise
;
cBaseOperator
.
prototype
.
Assemble
=
function
(
arg
)
{
var
str
=
""
;
if
(
this
.
argumentsCurrent
===
2
)
{
...
...
@@ -2394,6 +2501,7 @@ parserHelp.setDigitSeparator(AscCommon.g_oDefaultCultureInfo.NumberDecimalSepara
this
.
value
=
new
cError
(
cErrorType
.
wrong_name
);
return
this
.
value
;
};
cBaseFunction
.
prototype
.
CalculatePromise
=
cBaseOperator
.
prototype
.
CalculatePromise
cBaseFunction
.
prototype
.
DecrementArguments
=
function
()
{
--
this
.
argumentsCurrent
;
};
...
...
@@ -4225,7 +4333,7 @@ function parserFormula( formula, parent, _ws ) {
this
.
parent
.
onFormulaEvent
(
AscCommon
.
c_oNotifyParentType
.
Change
,
eventData
);
}
}
}
else
if
(
AscCommon
.
c_oNotifyType
.
Changed
===
data
.
type
)
{
}
else
if
(
AscCommon
.
c_oNotifyType
.
Changed
===
data
.
type
)
{
if
(
this
.
parent
&&
this
.
parent
.
onFormulaEvent
)
{
this
.
parent
.
onFormulaEvent
(
AscCommon
.
c_oNotifyParentType
.
Change
,
eventData
);
}
...
...
@@ -5102,6 +5210,8 @@ parserFormula.prototype.parse = function(local, digitDelim) {
};
parserFormula
.
prototype
.
calculate
=
function
(
opt_defName
,
opt_bbox
,
opt_offset
)
{
var
value
,
formula
=
this
;
if
(
this
.
isCalculate
&&
(
!
this
.
calculateDefName
||
this
.
calculateDefName
[
opt_bbox
?
opt_bbox
.
getName
()
:
opt_bbox
]))
{
//cycle
...
...
@@ -5145,7 +5255,7 @@ parserFormula.prototype.parse = function(local, digitDelim) {
for
(
var
ind
=
0
;
ind
<
currentElement
.
getArguments
();
ind
++
)
{
arg
.
unshift
(
elemArr
.
pop
());
}
_tmp
=
currentElement
.
Calculate
(
arg
,
opt_bbox
,
opt_defName
,
this
.
ws
);
_tmp
=
currentElement
.
Calculate
Promise
(
arg
,
opt_bbox
,
opt_defName
,
this
.
ws
);
if
(
cNumFormatNull
!==
_tmp
.
numFormat
)
{
numFormat
=
_tmp
.
numFormat
;
}
else
if
(
0
>
numFormat
||
cNumFormatNone
===
currentElement
.
numFormat
)
{
...
...
@@ -5163,8 +5273,28 @@ parserFormula.prototype.parse = function(local, digitDelim) {
elemArr
.
push
(
currentElement
);
}
}
this
.
value
=
elemArr
.
pop
();
this
.
value
.
numFormat
=
numFormat
;
value
=
elemArr
.
pop
();
if
(
typeof
value
===
"
function
"
)
{
this
.
value
=
new
cError
(
cErrorType
.
getting_data
);
this
.
queue
=
true
;
this
.
lazy_value
=
function
()
{
formula
.
lazy_value
=
null
;
formula
.
queue
=
value
()
.
push
(
function
(
ret
)
{
formula
.
value
=
ret
;
formula
.
value
.
numFormat
=
numFormat
;
formula
.
_endCalculate
();
opt_bbox
.
updateOnScreen
();
formula
.
queue
=
false
;
// formula.lazy_value = null;
return
formula
.
value
;
});
return
formula
.
queue
}
}
else
{
this
.
value
=
value
;
this
.
value
.
numFormat
=
numFormat
;
}
this
.
_endCalculate
();
return
this
.
value
;
...
...
cell/model/Workbook.js
View file @
08a5ed40
...
...
@@ -908,6 +908,11 @@
this
.
buildDefName
=
{};
},
calcTree
:
function
()
{
var
dependency_graph
=
this
,
formula
,
i
,
tasks
=
[],
lazy_value
;
if
(
this
.
lockCounter
>
0
)
{
return
;
}
...
...
@@ -924,26 +929,44 @@
this
.
_broadcastCells
(
notifyData
,
calcTrack
);
}
this
.
_broadcastCellsEnd
();
for
(
var
i
=
0
;
i
<
noCalcTrack
.
length
;
++
i
)
{
var
formula
=
noCalcTrack
[
i
];
for
(
i
=
0
;
i
<
noCalcTrack
.
length
;
++
i
)
{
formula
=
noCalcTrack
[
i
];
//defName recalc when calc formula containing it. no need calc it
formula
.
setIsDirty
(
false
);
}
for
(
var
i
=
0
;
i
<
calcTrack
.
length
;
++
i
)
{
var
formula
=
calcTrack
[
i
];
for
(
i
=
0
;
i
<
calcTrack
.
length
;
++
i
)
{
formula
=
calcTrack
[
i
];
if
(
formula
.
getIsDirty
())
{
formula
.
calculate
();
}
}
//copy cleanCellCache to prevent recursion in trigger("cleanCellCache")
var
tmpCellCache
=
this
.
cleanCellCache
;
this
.
cleanCellCache
=
{};
for
(
var
i
in
tmpCellCache
)
{
this
.
wb
.
handlers
.
trigger
(
"
cleanCellCache
"
,
i
,
{
0
:
tmpCellCache
[
i
]},
AscCommonExcel
.
c_oAscCanChangeColWidth
.
none
);
for
(
i
=
calcTrack
.
length
-
1
;
i
>=
0
;
--
i
)
{
lazy_value
=
calcTrack
[
i
].
lazy_value
;
if
(
lazy_value
)
{
tasks
.
push
(
lazy_value
());
}
}
function
end
()
{
//copy cleanCellCache to prevent recursion in trigger("cleanCellCache")
var
tmpCellCache
=
dependency_graph
.
cleanCellCache
;
dependency_graph
.
cleanCellCache
=
{};
for
(
var
i
in
dependency_graph
.
cleanCellCache
)
{
dependency_graph
.
wb
.
handlers
.
trigger
(
"
cleanCellCache
"
,
i
,
{
0
:
tmpCellCache
[
i
]},
AscCommonExcel
.
c_oAscCanChangeColWidth
.
none
);
}
AscCommonExcel
.
g_oVLOOKUPCache
.
clean
();
AscCommonExcel
.
g_oHLOOKUPCache
.
clean
();
}
if
(
tasks
.
length
>
0
)
{
new
RSVP
.
Queue
()
.
push
(
function
()
{
return
RSVP
.
all
(
tasks
);
})
.
push
(
end
);
}
else
{
end
();
}
AscCommonExcel
.
g_oVLOOKUPCache
.
clean
();
AscCommonExcel
.
g_oHLOOKUPCache
.
clean
();
},
initOpen
:
function
()
{
this
.
_foreachDefName
(
function
(
defName
)
{
...
...
@@ -5387,6 +5410,11 @@
this
.
nCol
=
-
1
;
this
.
formulaParsed
=
null
;
}
Cell
.
prototype
.
getId
=
function
()
{
return
[
this
.
ws
.
getId
(),
this
.
nRow
,
this
.
nCol
].
join
(
"
,
"
);
};
Cell
.
prototype
.
getStyle
=
function
(){
return
this
.
xfs
;
};
...
...
@@ -5945,7 +5973,7 @@
this
.
setValue
(
""
);
};
Cell
.
prototype
.
_checkDirty
=
function
(){
if
(
this
.
formulaParsed
&&
this
.
formulaParsed
.
getIsDirty
())
{
if
(
this
.
formulaParsed
&&
this
.
formulaParsed
.
getIsDirty
()
&&
!
this
.
formulaParsed
.
queue
)
{
this
.
formulaParsed
.
calculate
();
}
};
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment