Commit 696fbed0 authored by Dmitry.Shahtanov's avatar Dmitry.Shahtanov Committed by Alexander.Trofimov

сделан разбор формул для локализованных названий функций, для локализованных чисел.

добавление и изменение именованных диапазонов через одну функцию.


git-svn-id: svn://192.168.3.15/activex/AVS/Sources/TeamlabOffice/trunk/OfficeWeb@62549 954022d7-b5bf-4e40-9824-e11837661b57
parent a42a2f2b
......@@ -2113,7 +2113,8 @@ var ASC_DOCS_API_USE_EMBEDDED_FONTS = "@@ASC_DOCS_API_USE_EMBEDDED_FONTS";
};
spreadsheet_api.prototype.asc_setDefinedNames = function (defName) {
return this.wb.setDefinedNames(defName);
// return this.wb.setDefinedNames(defName);
return this.wb.editDefinedNames(null, defName);
};
spreadsheet_api.prototype.asc_editDefinedNames = function (oldName, newName) {
......
......@@ -258,6 +258,9 @@ cBaseType.prototype = {
toString:function () {
return this.value.toString();
},
toLocaleString:function(){
return this.toString();
},
setNode:function ( node ) {
this.node = node;
}
......@@ -283,7 +286,7 @@ function cNumber( val ) {
cNumber.prototype = Object.create( cBaseType.prototype );
cNumber.prototype.tocString = function () {
return new cString( "" + this.value );
return new cString( ("" + this.value).replace(digitSeparatorDef,digitSeparator) );
};
cNumber.prototype.tocNumber = function () {
return this;
......@@ -291,6 +294,13 @@ cNumber.prototype.tocNumber = function () {
cNumber.prototype.tocBool = function () {
return new cBool( this.value !== 0 );
};
cNumber.prototype.toLocaleString = function (digitDelim) {
var res = this.value.toString();
if(digitDelim)
return res.replace(digitSeparatorDef,digitSeparator);
else
return res;
};
/** @constructor */
function cString( val ) {
......@@ -307,15 +317,28 @@ cString.prototype.tocNumber = function () {
/*if ( this.value[0] === '"' && this.value[this.value.length - 1] === '"' ) {
m = this.value.substring( 1, this.value.length - 1 );
}*/
if ( !parseNum( m ) ) {
res = new cError( cErrorType.wrong_value_type );
}
else {
var numberValue = parseFloat( m );
if ( !isNaN( numberValue ) ) {
res = new cNumber( numberValue );
if (g_oFormatParser.isLocaleNumber( this.value ))
{
if ("." != g_oDefaultCultureInfo.NumberDecimalSeparator) {
m = this.value.replace(".", "q");//заменяем на символ с которым не распознается, как в Excel
m = m.replace(g_oDefaultCultureInfo.NumberDecimalSeparator, ".");
}
if ( !parseNum( m ) ) {
res = new cError( cErrorType.wrong_value_type );
}
else {
var numberValue = g_oFormatParser.parseLocaleNumber( this.value );
if ( !isNaN( numberValue ) ) {
res = new cNumber( numberValue );
}
}
}
else{
res = new cError( cErrorType.wrong_value_type );
}
return res;
};
cString.prototype.tocBool = function () {
......@@ -1412,8 +1435,8 @@ cArray.prototype.tocBool = function () {
};
cArray.prototype.toString = function () {
var ret = "";
for ( var ir = 0; ir < this.rowCount; ir++, ret += ";" ) {
for ( var ic = 0; ic < this.countElementInRow[ir]; ic++, ret += "," ) {
for ( var ir = 0; ir < this.rowCount; ir++, ret += arrayRowSeparatorDef ) {
for ( var ic = 0; ic < this.countElementInRow[ir]; ic++, ret += arrayColSeparatorDef ) {
if ( this.array[ir][ic] instanceof cString ) {
ret += '"' + this.array[ir][ic].toString() + '"';
}
......@@ -1421,11 +1444,31 @@ cArray.prototype.toString = function () {
ret += this.array[ir][ic].toString() + "";
}
}
if ( ret[ret.length - 1] === "," ) {
if ( ret[ret.length - 1] === arrayColSeparatorDef ) {
ret = ret.substring( 0, ret.length - 1 );
}
}
if ( ret[ret.length - 1] === arrayRowSeparatorDef ) {
ret = ret.substring( 0, ret.length - 1 );
}
return "{" + ret + "}";
};
cArray.prototype.toLocaleString = function (digitDelim) {
var ret = "";
for ( var ir = 0; ir < this.rowCount; ir++, ret += digitDelim?arrayRowSeparator:arrayRowSeparatorDef ) {
for ( var ic = 0; ic < this.countElementInRow[ir]; ic++, ret += digitDelim?arrayColSeparator:arrayColSeparatorDef ) {
if ( this.array[ir][ic] instanceof cString ) {
ret += '"' + this.array[ir][ic].toLocaleString(digitDelim) + '"';
}
else {
ret += this.array[ir][ic].toLocaleString(digitDelim) + "";
}
}
if ( ret[ret.length - 1] === digitDelim?arrayColSeparator:arrayColSeparatorDef ) {
ret = ret.substring( 0, ret.length - 1 );
}
}
if ( ret[ret.length - 1] === ";" ) {
if ( ret[ret.length - 1] === digitDelim?arrayRowSeparator:arrayRowSeparatorDef ) {
ret = ret.substring( 0, ret.length - 1 );
}
return "{" + ret + "}";
......@@ -1545,6 +1588,16 @@ cBaseOperator.prototype = {
str += this.name + arg[start];
}
return new cString( str );
},
Assemble2Locale:function ( arg, start, count, locale, digitDelim ) {
var str = "";
if ( this.argumentsCurrent === 2 ){
str += arg[start + count - 2].toLocaleString(digitDelim) + this.name + arg[start + count - 1].toLocaleString(digitDelim);
}
else{
str += this.name + arg[start];
}
return new cString( str );
}
};
......@@ -1617,13 +1670,13 @@ cBaseFunction.prototype = {
}
return new cString( this.name + "(" + str + ")" );
},
Assemble2Locale:function ( arg, start, count, locale ) {
Assemble2Locale:function ( arg, start, count, locale, digitDelim ) {
var str = "", c = start + count - 1, localeName = locale ? locale[this.name] : this.name;
for ( var i = start; i <= c; i++ ) {
str += arg[i].toString();
str += arg[i].toLocaleString(digitDelim);
if ( i !== c ) {
str += ",";
str += functionArgumentSeparator;
}
}
return new cString( localeName + "(" + str + ")" );
......@@ -1717,6 +1770,9 @@ cUnarMinusOperator.prototype.Assemble = function ( arg ) {
cUnarMinusOperator.prototype.Assemble2 = function ( arg, start, count ) {
return new cString( "-" + arg[start + count - 1] );
};
cUnarMinusOperator.prototype.Assemble2Locale = function ( arg, start, count ) {
return new cString( "-" + arg[start + count - 1] );
};
/** @constructor */
function cUnarPlusOperator() {
......@@ -1742,6 +1798,9 @@ cUnarPlusOperator.prototype.Assemble = function ( arg ) {
cUnarPlusOperator.prototype.Assemble2 = function ( arg, start, count ) {
return new cString( "+" + arg[start + count - 1] );
};
cUnarPlusOperator.prototype.Assemble2Locale = function ( arg, start, count ) {
return new cString( "+" + arg[start + count - 1] );
};
/** @constructor */
function cAddOperator() {
......@@ -1814,6 +1873,9 @@ cPercentOperator.prototype.Assemble = function ( arg ) {
cPercentOperator.prototype.Assemble2 = function ( arg, start, count ) {
return new cString( arg[start + count - 1] + this.name );
};
cPercentOperator.prototype.Assemble2Locale = function ( arg, start, count ) {
return new cString( arg[start + count - 1] + this.name );
};
/** @constructor */
function cPowOperator() {
......@@ -3073,7 +3135,7 @@ parserFormula.prototype = {
this.cellAddress = g_oCellAddressUtils.getCellAddress( cellId );
},
parse:function ( local ) {
parse:function ( local, digitDelim ) {
if ( this.isParsed )
return this.isParsed;
......@@ -3271,14 +3333,14 @@ parserFormula.prototype = {
}
/* Array */
else if ( parserHelp.isArray.call( this, this.Formula, this.pCurrPos ) ) {
else if ( parserHelp.isArray.call( this, this.Formula, this.pCurrPos,digitDelim ) ) {
wasLeftParentheses = false; wasRigthParentheses = false;
var pH = new parserHelper(), tO = {pCurrPos:0, Formula:this.operand_str, operand_str:""};
var arr = new cArray(), operator = { isOperator:false, operatorName:""};
while ( tO.pCurrPos < tO.Formula.length ) {
if ( pH.isComma.call( tO, tO.Formula, tO.pCurrPos ) ) {
if ( tO.operand_str == ";" ) {
if ( pH.isArraySeparator.call( tO, tO.Formula, tO.pCurrPos, digitDelim ) ) {
if ( tO.operand_str == (digitDelim?arrayRowSeparator:arrayRowSeparatorDef) ) {
arr.addRow();
}
}
......@@ -3291,7 +3353,7 @@ parserFormula.prototype = {
else if ( pH.isError.call( tO, tO.Formula, tO.pCurrPos ) ) {
arr.addElement( new cError( tO.operand_str ) );
}
else if ( pH.isNumber.call( tO, tO.Formula, tO.pCurrPos ) ) {
else if ( pH.isNumber.call( tO, tO.Formula, tO.pCurrPos, digitDelim ) ) {
if ( operator.isOperator ) {
if ( operator.operatorName == "+" || operator.operatorName == "-" ) {
tO.operand_str = operator.operatorName + "" + tO.operand_str
......@@ -3409,7 +3471,7 @@ parserFormula.prototype = {
}
/* Numbers*/
else if ( parserHelp.isNumber.call( this, this.Formula, this.pCurrPos ) ) {
else if ( parserHelp.isNumber.call( this, this.Formula, this.pCurrPos, digitDelim ) ) {
if ( this.operand_str != "." ) {
found_operand = new cNumber( parseFloat( this.operand_str ) );
}
......@@ -3726,11 +3788,11 @@ parserFormula.prototype = {
var currentElement = null,
_count = this.outStack.length,
elemArr = new Array( _count ),
res = undefined;
res = undefined, _count_arg;
for ( var i = 0, j = 0; i < _count; i++,j++ ) {
currentElement = this.outStack[i];
if ( currentElement.type == cElementType.operator || currentElement.type == cElementType.func ) {
var _count_arg = currentElement.getArguments();
_count_arg = currentElement.getArguments();
res = currentElement.Assemble2( elemArr, j - _count_arg, _count_arg );
j -= _count_arg;
elemArr[j] = res;
......@@ -3752,7 +3814,7 @@ parserFormula.prototype = {
},
/* Сборка функции в инфиксную форму */
assembleLocale:function ( locale ) {
assembleLocale:function ( locale, digitDelim ) {
var currentElement = null,
_count = this.outStack.length,
elemArr = new Array( _count ),
......@@ -3761,25 +3823,20 @@ parserFormula.prototype = {
currentElement = this.outStack[i];
if ( currentElement.type == cElementType.operator || currentElement.type == cElementType.func ) {
_count_arg = currentElement.getArguments();
if( currentElement.type == cElementType.func ){
res = currentElement.Assemble2Locale( elemArr, j - _count_arg, _count_arg, locale);
}
else{
res = currentElement.Assemble2( elemArr, j - _count_arg, _count_arg );
}
res = currentElement.Assemble2Locale( elemArr, j - _count_arg, _count_arg, locale, digitDelim);
j -= _count_arg;
elemArr[j] = res;
}
else {
if ( currentElement instanceof cString ) {
currentElement = new cString( "\"" + currentElement.toString() + "\"" );
currentElement = new cString( "\"" + currentElement.toLocaleString(digitDelim) + "\"" );
}
res = currentElement;
elemArr[j] = res;
}
}
if ( res != undefined && res != null ){
return res.toString();
return res.toLocaleString(digitDelim);
}
else{
return this.Formula;
......@@ -4019,9 +4076,7 @@ parserFormula.prototype = {
},
parseDiagramRef:function () {
var res = [
[]
];
var res = [[]];
while ( this.pCurrPos < this.Formula.length ) {
if ( parserHelp.isComma.call( this, this.Formula, this.pCurrPos ) ) {
......
......@@ -2856,11 +2856,16 @@ UndoRedoWorkbook.prototype = {
}
else if(historyitem_Workbook_DefinedNamesAdd === Type ){
if(bUndo){
this.wb.delDefinesNames( Data );
this.wb.delDefinesNames( Data.newName );
}
else{
this.wb.setDefinesNames( Data );
this.wb.setDefinesNames( Data.newName );
}
/*TODO
* Ввели формулу в которой есть именованный диапазон, но ИД нет в списке ИД. Результат формулы #NAME!.
* Создаем ИД с таким же именем, что и в функции. Необходимо пересчитать функцию. Предварительно перестроив
* граф зависимостей.
* */
}
else if(historyitem_Workbook_DefinedNamesChange === Type ){
var oldName, newName;
......
......@@ -2176,63 +2176,94 @@ Workbook.prototype.delDefinesNames = function ( defName ) {
}
Workbook.prototype.editDefinesNames = function ( oldName, newName ) {
var oldN = oldName.Name.toLowerCase(),
newN = newName.Name.toLowerCase(),
retRes = null, _tmp;
var oldN, newN = newName.Name.toLowerCase(), retRes = null, _tmp,
dN = this.DefinedNames || {};
var rxTest = rx_defName.test( newN );
if ( !rxTest ) {
if ( !rx_defName.test( newN ) ) {
return retRes;
}
var dN = this.DefinedNames || {};
if ( null != oldName.Scope ) {
var ws = this.getWorksheetByName( oldName.Scope );
if ( ws ) {
if ( ws.DefinedNames ) {
if ( null == ws.DefinedNames[oldN] ) {
retRes = null;
}
else {
ws.DefinedNames[newN] = ws.DefinedNames[oldN];
ws.DefinedNames[newN].Name = newName.Name;
ws.DefinedNames[newN].Ref = newName.Ref;
// ws.DefinedNames[newN].LocalSheetId = ws.getId();
if(oldName){
oldN = oldName.Name.toLowerCase();
if ( oldN != newN ) {
ws.DefinedNames[oldN] = null;
delete ws.DefinedNames[oldN];
if ( null != oldName.Scope ) {
var ws = this.getWorksheetByName( oldName.Scope );
if ( ws ) {
if ( ws.DefinedNames ) {
if ( null == ws.DefinedNames[oldN] ) {
retRes = null;
}
else {
ws.DefinedNames[newN] = ws.DefinedNames[oldN];
ws.DefinedNames[newN].Name = newName.Name;
ws.DefinedNames[newN].Ref = newName.Ref;
// ws.DefinedNames[newN].LocalSheetId = ws.getId();
_tmp = [ws.DefinedNames[newN].LocalSheetId,oldN,newN];
if ( oldN != newN ) {
ws.DefinedNames[oldN] = null;
delete ws.DefinedNames[oldN];
}
retRes = new Asc.asc_CDefName( ws.DefinedNames[newN].Name, ws.DefinedNames[newN].Ref, newName.Scope );
_tmp = [ws.DefinedNames[newN].LocalSheetId,oldN,newN];
retRes = new Asc.asc_CDefName( ws.DefinedNames[newN].Name, ws.DefinedNames[newN].Ref, newName.Scope );
}
}
}
}
}
else {
if ( null != dN[oldN] ) {
dN[newN] = dN[oldN];
dN[newN].Name = newName.Name;
dN[newN].Ref = newName.Ref;
dN[newN].LocalSheetId = null;
if ( oldN != newN ) {
dN[oldN] = null;
delete dN[oldN];
else {
if ( null != dN[oldN] ) {
dN[newN] = dN[oldN];
dN[newN].Name = newName.Name;
dN[newN].Ref = newName.Ref;
dN[newN].LocalSheetId = null;
if ( oldN != newN ) {
dN[oldN] = null;
delete dN[oldN];
}
_tmp = [null,oldN,newN];
retRes = new Asc.asc_CDefName( dN[newN].Name, dN[newN].Ref, null );
}
}
_tmp = [null,oldN,newN];
}
else{
if ( null != newName.Scope ) {
var ws = this.getWorksheetById( newName.Scope );
if ( ws ) {
if ( ws.DefinedNames ) {
if ( ws.DefinedNames[newN] ) {
retRes = new Asc.asc_CDefName( ws.DefinedNames[newN].Name, ws.DefinedNames[newN].Ref, ws.getIndex() );
}
else {
if ( dN[newN] ) {
return new Asc.asc_CDefName( dN[newN].Name, dN[newN].Ref, null );
}
ws.DefinedNames[newN] = { LocalSheetId:newName.Scope, Name:newName.Name, Ref:newName.Ref, bTable:false };
retRes = new Asc.asc_CDefName( ws.DefinedNames[newN].Name, ws.DefinedNames[newN].Ref, ws.getIndex() );
}
}
}
return null;
}
if ( dN[newN] ) {
return new Asc.asc_CDefName( dN[newN].Name, dN[newN].Ref, null );
}
else {
dN[newN] = { LocalSheetId:null, Name:newName.Name, Ref:newName.Ref, bTable:false };
retRes = new Asc.asc_CDefName( dN[newN].Name, dN[newN].Ref, null );
}
}
if( retRes ){
History.Create_NewPoint();
History.Add(g_oUndoRedoWorkbook, historyitem_Workbook_DefinedNamesAdd, null, null, new g_oUndoRedoData_DefinedNamesChangeProperties(oldName, newName));
History.Add(g_oUndoRedoWorkbook, historyitem_Workbook_DefinedNamesAdd, null, null, new UndoRedoData_DefinedNamesChange(oldName, newName));
/*
* #1. поменяли название - перестроили формулу. нужно вызвать пересборку формул в ячейках, в которыйх есть эта именованная ссылка.
......@@ -2240,28 +2271,31 @@ Workbook.prototype.editDefinesNames = function ( oldName, newName ) {
* #2. поменяли диапазон. нужно перестроить граф зависимосте и пересчитать формулу. находим диапазон; меняем в нем ссылку; разбираем ссылку;
* удаляем старые master и добавляем новые, которые получились в результате разбора новой ссылки; пересчитываем формулу.
* */
var defNameID = getDefNameVertexId(_tmp[0], _tmp[1]);
var n = this.dependencyFormulas.getDefNameNode( defNameID );
var nSE = n.getSlaveEdges(), se;
n.deleteAllMasterEdges();
if(_tmp){
var defNameID = getDefNameVertexId(_tmp[0], _tmp[1]);
var n = this.dependencyFormulas.getDefNameNode( defNameID );
var nSE = n.getSlaveEdges(), se;
n.deleteAllMasterEdges();
for( var id in nSE ){
se = nSE[id];
se.deleteMasterEdge(n);
for( var id in nSE ){
se = nSE[id];
se.deleteMasterEdge(n);
this.needRecalc.nodes[se.nodeId] = [se.sheetId, se.cellId ];
this.needRecalc.length++;
this.needRecalc.nodes[se.nodeId] = [se.sheetId, se.cellId ];
this.needRecalc.length++;
se = se.returnCell();
se ? function(){
se.setFormula(se.formulaParsed.assemble());
se.formulaParsed.buildDependencies(true);
}() : null;
se = se.returnCell();
se ? function(){
se.setFormula(se.formulaParsed.assemble());
se.formulaParsed.buildDependencies(true);
}() : null;
}
sortDependency(this);
}
sortDependency(this);
}
return retRes;
......@@ -4739,7 +4773,7 @@ Cell.prototype.setValue=function(val,callback, isCopyPaste){
oldFP = this.formulaParsed;
var cellId = g_oCellAddressUtils.getCellId(this.nRow, this.nCol);
this.formulaParsed = new parserFormula(val.substring(1),cellId,this.ws);
if( !this.formulaParsed.parse(true) ){
if( !this.formulaParsed.parse(true,true) ){
switch( this.formulaParsed.error[this.formulaParsed.error.length-1] ){
case c_oAscError.ID.FrmlWrongFunctionName:
break;
......
......@@ -3018,7 +3018,7 @@ CCellValue.prototype =
var oValueArray = null;
var xfs = cell.getCompiledStyle();
if(cell.sFormula)
oValueText = "="+cell.formulaParsed.assembleLocale(cFormulaFunctionToLocale); // ToDo если будет притормаживать, то завести переменную и не рассчитывать каждый раз!
oValueText = "="+cell.formulaParsed.assembleLocale(cFormulaFunctionToLocale,true); // ToDo если будет притормаживать, то завести переменную и не рассчитывать каждый раз!
else
{
if(null != this.text || null != this.number)
......
......@@ -1951,8 +1951,13 @@
WorkbookView.prototype.editDefinedNames = function (oldName, newName) {
//ToDo проверка defName.ref на знак "=" в начале ссылки. знака нет тогда это либо число либо строка, так делает Excel.
this.handlers.trigger("asc_onEditDefName", this.model.editDefinesNames(oldName, newName));
var res = this.model.editDefinesNames(oldName, newName);
if( oldName ){
this.handlers.trigger("asc_onEditDefName", res);
}
else{
this.handlers.trigger("asc_onDefName", res);
}
};
......
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