Skip to content

Commit

Permalink
Added changes in the logic of the formula shift/move when inserting t…
Browse files Browse the repository at this point in the history
…he table

Added tests
  • Loading branch information
DimitryOrlov committed Feb 13, 2025
1 parent 3469fa0 commit e7e03a4
Show file tree
Hide file tree
Showing 4 changed files with 225 additions and 24 deletions.
13 changes: 12 additions & 1 deletion cell/model/FormulaObjects/parserFormula.js
Original file line number Diff line number Diff line change
Expand Up @@ -9161,12 +9161,17 @@ function parserFormula( formula, parent, _ws ) {
_cellsBbox = elem.getBBox0();
}
}
let tableOffset = null;
if (_cellsRange || _cellsBbox) {
var isIntersect;
if (AscCommon.c_oNotifyType.Shift === notifyType) {
isIntersect = bbox.isIntersectForShift(_cellsBbox, offset);
} else if (AscCommon.c_oNotifyType.Move === notifyType) {
isIntersect = bbox.containsRange(_cellsBbox);
if (!isIntersect && bbox.isIntersect(_cellsBbox)) {
tableOffset = offset;
isIntersect = true;
}
} else if (AscCommon.c_oNotifyType.Delete === notifyType) {
isIntersect = bbox.isIntersect(_cellsBbox);
}
Expand All @@ -9175,7 +9180,13 @@ function parserFormula( formula, parent, _ws ) {
if (AscCommon.c_oNotifyType.Shift === notifyType) {
isNoDelete = _cellsBbox.forShift(bbox, offset, this.wb.bUndoChanges);
} else if (AscCommon.c_oNotifyType.Move === notifyType) {
_cellsBbox.setOffset(offset);
// If the first cell is inside the selective, then we move formula to -1 +1, if not then just +1 down
// It should work only when we insert the table
if (tableOffset && bbox.r1 !== _cellsBbox.r1) {
_cellsBbox.setOffsetLast(tableOffset);
} else {
_cellsBbox.setOffset(offset);
}
isNoDelete = true;
} else if (AscCommon.c_oNotifyType.Delete === notifyType) {
if (bbox.containsRange(_cellsBbox)) {
Expand Down
3 changes: 2 additions & 1 deletion cell/model/Workbook.js
Original file line number Diff line number Diff line change
Expand Up @@ -2184,7 +2184,8 @@
for (var areaIndex in sheetContainer.areaMap) {
var areaMapElem = sheetContainer.areaMap[areaIndex];
if (c_oNotifyType.Shift === notifyType) {
isIntersect = bboxShift.isIntersectWithOffset(areaMapElem.bbox, offset);
// isIntersect = bboxShift.isIntersect(areaMapElem.bbox);
isIntersect = bboxShift.containsRange(areaMapElem.bbox);
} else if (c_oNotifyType.Move === notifyType || c_oNotifyType.Delete === notifyType) {
isIntersect = bbox.isIntersect(areaMapElem.bbox);
}
Expand Down
17 changes: 2 additions & 15 deletions cell/utils/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -584,19 +584,6 @@
return bRes;
};

Range.prototype.isIntersectWithOffset = function (range, offset) {
let shiftRow = offset && offset.row && offset.row > 0 ? offset.row : 0,
shiftCol = offset && offset.col && offset.col > 0 ? offset.col : 0,
bRes = true;

if ((range.r2 + shiftRow) < this.r1 || this.r2 < range.r1) {
bRes = false;
} else if ((range.c2 + shiftCol) < this.c1 || this.c2 < range.c1) {
bRes = false;
}
return bRes;
};

Range.prototype.isIntersectForInsertColRow = function (range, isInsertCol) {
var bRes = true;
if (range.r2 < this.r1 || this.r2 < range.r1)
Expand Down Expand Up @@ -625,15 +612,15 @@
var isHor = offset && offset.col;
var isDelete = offset && (offset.col < 0 || offset.row < 0);
if (isHor) {
if (!isDelete && (this.r1 <= range.r1) && (range.r2 <= this.r2) && (this.c1 <= (range.c2 + offset.col))) {
if (this.r1 <= range.r1 && range.r2 <= this.r2 && this.c1 <= range.c2) {
return true;
} else if (isDelete && this.c1 <= range.c1 && range.c2 <= this.c2) {
var topIn = this.r1 <= range.r1 && range.r1 <= this.r2;
var bottomIn = this.r1 <= range.r2 && range.r2 <= this.r2;
return topIn || bottomIn;
}
} else {
if (!isDelete && (this.c1 <= range.c1) && (range.c2 <= this.c2) && (this.r1 <= (range.r2 + offset.row))) {
if (this.c1 <= range.c1 && range.c2 <= this.c2 && this.r1 <= range.r2) {
return true;
} else if (isDelete && this.r1 <= range.r1 && range.r2 <= this.r2) {
var leftIn = this.c1 <= range.c1 && range.c1 <= this.c2;
Expand Down
216 changes: 209 additions & 7 deletions tests/cell/spreadsheet-calculation/SheetStructureTests.js
Original file line number Diff line number Diff line change
Expand Up @@ -609,7 +609,7 @@ $(function () {
clearData(0, 0, AscCommon.gc_nMaxCol, AscCommon.gc_nMaxRow);
});

QUnit.test("Test: \"Shift cells when table created\"", function (assert) {
QUnit.test("Test: \"Shift/move cells after create a table\"", function (assert) {
// let testData = [
// ["1", "row1col2", "row1col3", "row1col4", "row1col5", "row1col6"],
// ["2", "row2col2", "row2col3", "row2col4", "row2col5", "row2col6"],
Expand Down Expand Up @@ -662,10 +662,11 @@ $(function () {
let tableOptions = new AscCommonExcel.AddFormatTableOptions();
tableOptions.range = "A100:A104";
// create table in A100:A104 range
tableOptions.isTitle = false;
api.asc_addAutoFilter("TableStyleMedium2", tableOptions);

let tables = wsView.model.autoFilters.getTablesIntersectionRange(new Asc.Range(0, 100, 0, 100));
assert.strictEqual(tables.length, 1, "compare tables length");
assert.strictEqual(tables.length, 1, "Table was created without selection of formula. Compare tables length");

let table = tables[0];
let tableName = table.DisplayName;
Expand Down Expand Up @@ -696,10 +697,11 @@ $(function () {
assert.strictEqual(resCell.getFormula(), "", "Formula in cell after table is created");

resCell = ws.getRange4(105, 0);
assert.strictEqual(resCell.getValueForEdit(), "=SUM(A100:A105)", "Value for edit in after table is created");
assert.strictEqual(resCell.getFormula(), "SUM(A100:A105)", "Formula in cell after table is created");
assert.strictEqual(resCell.getValueForEdit(), "=SUM(A101:A105)", "Value for edit in after table is created");
assert.strictEqual(resCell.getFormula(), "SUM(A101:A105)", "Formula in cell after table is created");

clearData(0, 0, AscCommon.gc_nMaxCol, AscCommon.gc_nMaxRow);
tables.length = 0;
clearData(0, 0, 200, 200);


/* create table with header/title and with the same data as the previous test*/
Expand Down Expand Up @@ -732,7 +734,7 @@ $(function () {
api.asc_addAutoFilter("TableStyleMedium2", tableOptions);

tables = wsView.model.autoFilters.getTablesIntersectionRange(new Asc.Range(0, 100, 0, 100));
assert.strictEqual(tables.length, 1, "compare tables length");
assert.strictEqual(tables.length, 1, "Table was created without selection of formula.compare tables length");

table = tables[0];
tableName = table.DisplayName;
Expand Down Expand Up @@ -766,7 +768,207 @@ $(function () {
assert.strictEqual(resCell.getValueForEdit(), "", "Value for edit in after table is created");
assert.strictEqual(resCell.getFormula(), "", "Formula in cell after table with title is created");

clearData(0, 0, AscCommon.gc_nMaxCol, AscCommon.gc_nMaxRow);
tables.length = 0;
clearData(0, 0, 200, 200);


ws.getRange2("A100").setValue("1");
ws.getRange2("A101").setValue("2");
ws.getRange2("A102").setValue("3");
ws.getRange2("A103").setValue("4");
ws.getRange2("A104").setValue("5");

resCell = ws.getRange4(104, 0);
resCell.setValue("=SUM(A100:A104)");

resCell = ws.getRange4(99, 0);
assert.strictEqual(resCell.getValueForEdit(), "1", "Value for edit in before table is created");
assert.strictEqual(resCell.getFormula(), "", "Formula in cell before table is created");

resCell = ws.getRange4(104, 0);
assert.strictEqual(resCell.getValueForEdit(), "=SUM(A100:A104)", "Value for edit in before table is created");
assert.strictEqual(resCell.getFormula(), "SUM(A100:A104)", "Formula in cell before table is created");

cellWithFormula = new AscCommonExcel.CCellWithFormula(ws, 104, 0);
oParser = new AscCommonExcel.parserFormula("SUM(A100:A104)", cellWithFormula, ws);
assert.ok(oParser.parse());
oParser.buildDependencies();
array = oParser.calculate();

tableOptions = new AscCommonExcel.AddFormatTableOptions();
tableOptions.range = "A100:A105";
tableOptions.isTitle = false;
api.asc_addAutoFilter("TableStyleMedium2", tableOptions);

tables = wsView.model.autoFilters.getTablesIntersectionRange(new Asc.Range(0, 100, 0, 100));
assert.strictEqual(tables.length, 1, "Table was created with selection of formula. Compare tables length");

table = tables[0];
tableName = table.DisplayName;

resCell = ws.getRange4(99, 0);
assert.strictEqual(resCell.getValueForEdit(), "Column1", "Value for edit in after table is created");
assert.strictEqual(resCell.getFormula(), "", "Formula in cell after table is created");

resCell = ws.getRange4(100, 0);
assert.strictEqual(resCell.getValueForEdit(), "1", "Value for edit in after table is created");
assert.strictEqual(resCell.getFormula(), "", "Formula in cell after table is created");

resCell = ws.getRange4(101, 0);
assert.strictEqual(resCell.getValueForEdit(), "2", "Value for edit in after table is created");
assert.strictEqual(resCell.getFormula(), "", "Formula in cell after table is created");

resCell = ws.getRange4(102, 0);
assert.strictEqual(resCell.getValueForEdit(), "3", "Value for edit in after table is created");
assert.strictEqual(resCell.getFormula(), "", "Formula in cell after table is created");

resCell = ws.getRange4(103, 0);
assert.strictEqual(resCell.getValueForEdit(), "4", "Value for edit in after table is created");
assert.strictEqual(resCell.getFormula(), "", "Formula in cell after table is created");

resCell = ws.getRange4(104, 0);
assert.strictEqual(resCell.getValueForEdit(), "5", "Value for edit in after table is created");
assert.strictEqual(resCell.getFormula(), "", "Formula in cell after table is created");

resCell = ws.getRange4(105, 0);
assert.strictEqual(resCell.getValueForEdit(), "=SUM(A101:A105)", "Value for edit in after table is created");
assert.strictEqual(resCell.getFormula(), "SUM(A101:A105)", "Formula in cell after table is created");

tables.length = 0;
clearData(0, 0, 200, 200);


ws.getRange2("A100").setValue("1");
ws.getRange2("A101").setValue("2");
ws.getRange2("A102").setValue("3");
ws.getRange2("A103").setValue("4");
ws.getRange2("A104").setValue("5");

resCell = ws.getRange4(104, 0);
resCell.setValue("=SUM(A100:A104)");

resCell = ws.getRange4(99, 0);
assert.strictEqual(resCell.getValueForEdit(), "1", "Value for edit in before table is created");
assert.strictEqual(resCell.getFormula(), "", "Formula in cell before table is created");

resCell = ws.getRange4(104, 0);
assert.strictEqual(resCell.getValueForEdit(), "=SUM(A100:A104)", "Value for edit in before table is created");
assert.strictEqual(resCell.getFormula(), "SUM(A100:A104)", "Formula in cell before table is created");

cellWithFormula = new AscCommonExcel.CCellWithFormula(ws, 104, 0);
oParser = new AscCommonExcel.parserFormula("SUM(A100:A104)", cellWithFormula, ws);
assert.ok(oParser.parse());
oParser.buildDependencies();
array = oParser.calculate();

tableOptions = new AscCommonExcel.AddFormatTableOptions();
tableOptions.range = "A100:A103";
tableOptions.isTitle = false;
api.asc_addAutoFilter("TableStyleMedium2", tableOptions);

tables = wsView.model.autoFilters.getTablesIntersectionRange(new Asc.Range(0, 100, 0, 100));
assert.strictEqual(tables.length, 1, "Table was created without selection of formula. Compare tables length");

table = tables[0];
tableName = table.DisplayName;

resCell = ws.getRange4(99, 0);
assert.strictEqual(resCell.getValueForEdit(), "Column1", "Value for edit in after table is created");
assert.strictEqual(resCell.getFormula(), "", "Formula in cell after table is created");

resCell = ws.getRange4(100, 0);
assert.strictEqual(resCell.getValueForEdit(), "1", "Value for edit in after table is created");
assert.strictEqual(resCell.getFormula(), "", "Formula in cell after table is created");

resCell = ws.getRange4(101, 0);
assert.strictEqual(resCell.getValueForEdit(), "2", "Value for edit in after table is created");
assert.strictEqual(resCell.getFormula(), "", "Formula in cell after table is created");

resCell = ws.getRange4(102, 0);
assert.strictEqual(resCell.getValueForEdit(), "3", "Value for edit in after table is created");
assert.strictEqual(resCell.getFormula(), "", "Formula in cell after table is created");

resCell = ws.getRange4(103, 0);
assert.strictEqual(resCell.getValueForEdit(), "4", "Value for edit in after table is created");
assert.strictEqual(resCell.getFormula(), "", "Formula in cell after table is created");

resCell = ws.getRange4(104, 0);
assert.strictEqual(resCell.getValueForEdit(), "5", "Value for edit in after table is created");
assert.strictEqual(resCell.getFormula(), "", "Formula in cell after table is created");

resCell = ws.getRange4(105, 0);
assert.strictEqual(resCell.getValueForEdit(), "=SUM(A101:A105)", "Value for edit in after table is created");
assert.strictEqual(resCell.getFormula(), "SUM(A101:A105)", "Formula in cell after table is created");

tables.length = 0;
clearData(0, 0, 200, 200);


ws.getRange2("A100").setValue("1");
ws.getRange2("A101").setValue("2");
ws.getRange2("A102").setValue("3");
ws.getRange2("A103").setValue("4");
ws.getRange2("A104").setValue("5");

resCell = ws.getRange4(104, 0);
resCell.setValue("=SUM(A100:A104)");

resCell = ws.getRange4(99, 0);
assert.strictEqual(resCell.getValueForEdit(), "1", "Value for edit in before table is created");
assert.strictEqual(resCell.getFormula(), "", "Formula in cell before table is created");

resCell = ws.getRange4(104, 0);
assert.strictEqual(resCell.getValueForEdit(), "=SUM(A100:A104)", "Value for edit in before table is created");
assert.strictEqual(resCell.getFormula(), "SUM(A100:A104)", "Formula in cell before table is created");

cellWithFormula = new AscCommonExcel.CCellWithFormula(ws, 104, 0);
oParser = new AscCommonExcel.parserFormula("SUM(A100:A104)", cellWithFormula, ws);
assert.ok(oParser.parse());
oParser.buildDependencies();
array = oParser.calculate();

tableOptions = new AscCommonExcel.AddFormatTableOptions();
tableOptions.range = "A102:A105";
tableOptions.isTitle = false;
api.asc_addAutoFilter("TableStyleMedium2", tableOptions);

tables = wsView.model.autoFilters.getTablesIntersectionRange(new Asc.Range(0, 103, 0, 103));
assert.strictEqual(tables.length, 1, "Table was created with selection of formula. Compare tables length");

table = tables[0];
tableName = table.DisplayName;

resCell = ws.getRange4(99, 0);
assert.strictEqual(resCell.getValueForEdit(), "1", "Value for edit in after table is created");
assert.strictEqual(resCell.getFormula(), "", "Formula in cell after table is created");

resCell = ws.getRange4(100, 0);
assert.strictEqual(resCell.getValueForEdit(), "2", "Value for edit in after table is created");
assert.strictEqual(resCell.getFormula(), "", "Formula in cell after table is created");

resCell = ws.getRange4(101, 0);
assert.strictEqual(resCell.getValueForEdit(), "Column1", "Value for edit in after table is created");
assert.strictEqual(resCell.getFormula(), "", "Formula in cell after table is created");

resCell = ws.getRange4(102, 0);
assert.strictEqual(resCell.getValueForEdit(), "3", "Value for edit in after table is created");
assert.strictEqual(resCell.getFormula(), "", "Formula in cell after table is created");

resCell = ws.getRange4(103, 0);
assert.strictEqual(resCell.getValueForEdit(), "4", "Value for edit in after table is created");
assert.strictEqual(resCell.getFormula(), "", "Formula in cell after table is created");

resCell = ws.getRange4(104, 0);
assert.strictEqual(resCell.getValueForEdit(), "5", "Value for edit in after table is created");
assert.strictEqual(resCell.getFormula(), "", "Formula in cell after table is created");

resCell = ws.getRange4(105, 0);
assert.strictEqual(resCell.getValueForEdit(), "=SUM(A100:A105)", "Value for edit in after table is created");
assert.strictEqual(resCell.getFormula(), "SUM(A100:A105)", "Formula in cell after table is created");

tables.length = 0;
clearData(0, 0, 200, 200);
ws.getRange2("A99:B110").cleanAll();

});

Expand Down

0 comments on commit e7e03a4

Please sign in to comment.