Commit 08a5ed40 authored by Boris Kocherov's avatar Boris Kocherov

add CUBEMEMBER, CUBEVALUE

use lazy calculation
parent 6ee6d7fe
/* jshint -W040 */
/* /*
* (c) Copyright Ascensio System SIA 2010-2017 * (c) Copyright Ascensio System SIA 2010-2017
* *
...@@ -38,15 +39,298 @@ ...@@ -38,15 +39,298 @@
*/ */
function (window, undefined) { function (window, undefined) {
var cBaseFunction = AscCommonExcel.cBaseFunction; 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 = cFormulaFunctionGroup.Cube || [];
cFormulaFunctionGroup['Cube'].push(cCUBEKPIMEMBER, cCUBEMEMBER, cCUBEMEMBERPROPERTY, cCUBERANKEDMEMBER, cCUBESET, cFormulaFunctionGroup.Cube.push(cCUBEKPIMEMBER, cCUBEMEMBER, cCUBEMEMBERPROPERTY, cCUBERANKEDMEMBER, cCUBESET,
cCUBESETCOUNT, cCUBEVALUE); cCUBESETCOUNT, cCUBEVALUE);
cFormulaFunctionGroup['NotRealised'] = cFormulaFunctionGroup['NotRealised'] || []; cFormulaFunctionGroup.NotRealised = cFormulaFunctionGroup.NotRealised || [];
cFormulaFunctionGroup['NotRealised'].push(cCUBEKPIMEMBER, cCUBEMEMBER, cCUBEMEMBERPROPERTY, cCUBERANKEDMEMBER, cFormulaFunctionGroup.NotRealised.push(cCUBEKPIMEMBER, cCUBEMEMBERPROPERTY, cCUBERANKEDMEMBER,
cCUBESET, cCUBESETCOUNT, cCUBEVALUE); 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 * @constructor
...@@ -73,6 +357,78 @@ ...@@ -73,6 +357,78 @@
cCUBEMEMBER.prototype = Object.create(cBaseFunction.prototype); cCUBEMEMBER.prototype = Object.create(cBaseFunction.prototype);
cCUBEMEMBER.prototype.constructor = cCUBEMEMBER; 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 * @constructor
...@@ -138,4 +494,97 @@ ...@@ -138,4 +494,97 @@
cCUBEVALUE.prototype = Object.create(cBaseFunction.prototype); cCUBEVALUE.prototype = Object.create(cBaseFunction.prototype);
cCUBEVALUE.prototype.constructor = cCUBEVALUE; 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);
...@@ -670,6 +670,112 @@ parserHelp.setDigitSeparator(AscCommon.g_oDefaultCultureInfo.NumberDecimalSepara ...@@ -670,6 +670,112 @@ parserHelp.setDigitSeparator(AscCommon.g_oDefaultCultureInfo.NumberDecimalSepara
cBaseType.prototype.toLocaleString = function () { cBaseType.prototype.toLocaleString = function () {
return this.toString(); 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*/ /*Basic types of an elements used into formulas*/
/** /**
...@@ -2347,6 +2453,7 @@ parserHelp.setDigitSeparator(AscCommon.g_oDefaultCultureInfo.NumberDecimalSepara ...@@ -2347,6 +2453,7 @@ parserHelp.setDigitSeparator(AscCommon.g_oDefaultCultureInfo.NumberDecimalSepara
cBaseOperator.prototype.Calculate = function () { cBaseOperator.prototype.Calculate = function () {
return null; return null;
}; };
cBaseOperator.prototype.CalculatePromise = cBaseType.prototype.CalculatePromise;
cBaseOperator.prototype.Assemble = function (arg) { cBaseOperator.prototype.Assemble = function (arg) {
var str = ""; var str = "";
if (this.argumentsCurrent === 2) { if (this.argumentsCurrent === 2) {
...@@ -2394,6 +2501,7 @@ parserHelp.setDigitSeparator(AscCommon.g_oDefaultCultureInfo.NumberDecimalSepara ...@@ -2394,6 +2501,7 @@ parserHelp.setDigitSeparator(AscCommon.g_oDefaultCultureInfo.NumberDecimalSepara
this.value = new cError(cErrorType.wrong_name); this.value = new cError(cErrorType.wrong_name);
return this.value; return this.value;
}; };
cBaseFunction.prototype.CalculatePromise = cBaseOperator.prototype.CalculatePromise
cBaseFunction.prototype.DecrementArguments = function () { cBaseFunction.prototype.DecrementArguments = function () {
--this.argumentsCurrent; --this.argumentsCurrent;
}; };
...@@ -4225,7 +4333,7 @@ function parserFormula( formula, parent, _ws ) { ...@@ -4225,7 +4333,7 @@ function parserFormula( formula, parent, _ws ) {
this.parent.onFormulaEvent(AscCommon.c_oNotifyParentType.Change, eventData); 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) { if (this.parent && this.parent.onFormulaEvent) {
this.parent.onFormulaEvent(AscCommon.c_oNotifyParentType.Change, eventData); this.parent.onFormulaEvent(AscCommon.c_oNotifyParentType.Change, eventData);
} }
...@@ -5102,6 +5210,8 @@ parserFormula.prototype.parse = function(local, digitDelim) { ...@@ -5102,6 +5210,8 @@ parserFormula.prototype.parse = function(local, digitDelim) {
}; };
parserFormula.prototype.calculate = function (opt_defName, opt_bbox, opt_offset) { 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() : if (this.isCalculate && (!this.calculateDefName || this.calculateDefName[opt_bbox ? opt_bbox.getName() :
opt_bbox])) { opt_bbox])) {
//cycle //cycle
...@@ -5145,7 +5255,7 @@ parserFormula.prototype.parse = function(local, digitDelim) { ...@@ -5145,7 +5255,7 @@ parserFormula.prototype.parse = function(local, digitDelim) {
for (var ind = 0; ind < currentElement.getArguments(); ind++) { for (var ind = 0; ind < currentElement.getArguments(); ind++) {
arg.unshift(elemArr.pop()); arg.unshift(elemArr.pop());
} }
_tmp = currentElement.Calculate(arg, opt_bbox, opt_defName, this.ws); _tmp = currentElement.CalculatePromise(arg, opt_bbox, opt_defName, this.ws);
if (cNumFormatNull !== _tmp.numFormat) { if (cNumFormatNull !== _tmp.numFormat) {
numFormat = _tmp.numFormat; numFormat = _tmp.numFormat;
} else if (0 > numFormat || cNumFormatNone === currentElement.numFormat) { } else if (0 > numFormat || cNumFormatNone === currentElement.numFormat) {
...@@ -5163,8 +5273,28 @@ parserFormula.prototype.parse = function(local, digitDelim) { ...@@ -5163,8 +5273,28 @@ parserFormula.prototype.parse = function(local, digitDelim) {
elemArr.push(currentElement); elemArr.push(currentElement);
} }
} }
this.value = elemArr.pop(); value = elemArr.pop();
this.value.numFormat = numFormat; 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(); this._endCalculate();
return this.value; return this.value;
......
...@@ -908,6 +908,11 @@ ...@@ -908,6 +908,11 @@
this.buildDefName = {}; this.buildDefName = {};
}, },
calcTree: function() { calcTree: function() {
var dependency_graph = this,
formula,
i,
tasks = [],
lazy_value;
if (this.lockCounter > 0) { if (this.lockCounter > 0) {
return; return;
} }
...@@ -924,26 +929,44 @@ ...@@ -924,26 +929,44 @@
this._broadcastCells(notifyData, calcTrack); this._broadcastCells(notifyData, calcTrack);
} }
this._broadcastCellsEnd(); this._broadcastCellsEnd();
for (var i = 0; i < noCalcTrack.length; ++i) { for (i = 0; i < noCalcTrack.length; ++i) {
var formula = noCalcTrack[i]; formula = noCalcTrack[i];
//defName recalc when calc formula containing it. no need calc it //defName recalc when calc formula containing it. no need calc it
formula.setIsDirty(false); 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()) { if (formula.getIsDirty()) {
formula.calculate(); formula.calculate();
} }
} }
//copy cleanCellCache to prevent recursion in trigger("cleanCellCache") for (i = calcTrack.length-1; i >= 0; --i) {
var tmpCellCache = this.cleanCellCache; lazy_value = calcTrack[i].lazy_value;
this.cleanCellCache = {}; if (lazy_value) {
for (var i in tmpCellCache) { tasks.push(lazy_value());
this.wb.handlers.trigger("cleanCellCache", i, {0: tmpCellCache[i]}, }
AscCommonExcel.c_oAscCanChangeColWidth.none); }
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() { initOpen: function() {
this._foreachDefName(function(defName) { this._foreachDefName(function(defName) {
...@@ -5387,6 +5410,11 @@ ...@@ -5387,6 +5410,11 @@
this.nCol = -1; this.nCol = -1;
this.formulaParsed = null; this.formulaParsed = null;
} }
Cell.prototype.getId = function () {
return [this.ws.getId(), this.nRow, this.nCol].join(",");
};
Cell.prototype.getStyle=function(){ Cell.prototype.getStyle=function(){
return this.xfs; return this.xfs;
}; };
...@@ -5945,7 +5973,7 @@ ...@@ -5945,7 +5973,7 @@
this.setValue(""); this.setValue("");
}; };
Cell.prototype._checkDirty = function(){ Cell.prototype._checkDirty = function(){
if(this.formulaParsed && this.formulaParsed.getIsDirty()) { if(this.formulaParsed && this.formulaParsed.getIsDirty() && !this.formulaParsed.queue) {
this.formulaParsed.calculate(); this.formulaParsed.calculate();
} }
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment