diff --git a/docs/guide/basic-operations.md b/docs/guide/basic-operations.md index fd2d31e9c..bd9400a06 100644 --- a/docs/guide/basic-operations.md +++ b/docs/guide/basic-operations.md @@ -49,8 +49,8 @@ const sheetsCount = hfInstance.countSheets(); A sheet can be removed by using the `removeSheet` method. To do that you need to pass a mandatory parameter: the ID of a sheet to be -removed. This method returns a list of cells whose values were affected -by this operation together with their absolute addresses and new values. +removed. +This method returns [an array of changed cells](#changes-array). ```javascript // track the changes triggered by removing the sheet 0 @@ -78,9 +78,8 @@ hfInstance.renameSheet(sheetID, 'AnotherNewName'); ### Clearing a sheet A sheet's content can be cleared with the `clearSheet` method. You need -to provide the ID of a sheet whose content you want to clear. This -method returns a list of cells whose values were affected by this -operation together with their absolute addresses and new values. +to provide the ID of a sheet whose content you want to clear. +This method returns [an array of changed cells](#changes-array). ```javascript // clear the content of sheet 0 @@ -91,9 +90,8 @@ const changes = hfInstance.clearSheet(0); Instead of removing and adding the content of a sheet you can replace it right away. To do so use `setSheetContent`, in which you can pass -the sheet ID and its new values. This method returns a list of cells -whose values were affected by this operation together with their -absolute addresses and new values. +the sheet ID and its new values. +This method returns [an array of changed cells](#changes-array). ```javascript // set new values for sheet 0 @@ -107,8 +105,7 @@ const changes = hfInstance.setSheetContent(0, [['50'], ['60']]); You can add one or more rows by using the `addRows` method. The first parameter you need to pass is a sheet ID, and the second parameter represents the position and the size of a block of rows to be added. -This method returns a list of cells whose values were affected by this -operation together with their absolute addresses and new values. +This method returns [an array of changed cells](#changes-array). ```javascript // track the changes triggered by adding @@ -121,9 +118,8 @@ const changes = hfInstance.addRows(0, [0, 2]); You can remove one or more rows by using the `removeRows` method. The first parameter you need to pass is a sheet ID, and the second parameter represents the position and the size of a block of rows to -be removed. This method returns a list of cells whose values were -affected by this operation together with their absolute addresses -and new values. +be removed. +This method returns [an array of changed cells](#changes-array). ```javascript // track the changes triggered by removing @@ -141,8 +137,7 @@ to pass the following parameters: * Number of rows to be moved * Target row -This method returns a list of cells whose values were affected by -this operation, together with their absolute addresses and new values. +This method returns [an array of changed cells](#changes-array). ```javascript // track the changes triggered by moving @@ -156,8 +151,7 @@ You can change the order of rows by using the `setRowOrder` method. You need to * Sheet ID * New row order -This method returns a list of cells whose values were affected by -this operation, together with their absolute addresses and new values. +This method returns [an array of changed cells](#changes-array). ```javascript // row 0 and row 2 swap places @@ -171,9 +165,8 @@ const changes = hfInstance.setRowOrder(0, [2, 1, 0]); You can add one or more columns by using the `addColumns` method. The first parameter you need to pass is a sheet ID, and the second parameter represents the position and the size of a block of columns -to be added. This method returns a list of cells whose values were -affected by this operation together with their absolute addresses -and new values. +to be added. +This method returns [an array of changed cells](#changes-array). ```javascript // track the changes triggered by adding @@ -186,9 +179,8 @@ const changes = hfInstance.addColumns(0, [0, 2]); You can remove one or more columns by using the `removeColumns` method. The first parameter you need to pass is a sheet ID, and the second parameter represents the position and the size of a block of columns -to be removed. This method returns a list of cells which values were -affected by this operation together with their absolute addresses -and new values. +to be removed. +This method returns [an array of changed cells](#changes-array). ```javascript // track the changes triggered by removing @@ -206,8 +198,7 @@ You need to pass the following parameters: * Number of columns to be moved * Target column -This method returns a list of cells whose values were affected by -this operation together with their absolute addresses and new values. +This method returns [an array of changed cells](#changes-array). ```javascript // track the changes triggered by moving @@ -221,8 +212,7 @@ You can change the order of columns by using the `setColumnOrder` method. You ne * Sheet ID * New column order -This method returns a list of cells whose values were affected by -this operation, together with their absolute addresses and new values. +This method returns [an array of changed cells](#changes-array). ```javascript // column 0 and column 2 swap places @@ -250,8 +240,7 @@ to pass the following parameters: * Source range ([SimpleCellRange](../api/interfaces/simplecellrange)) * Top left corner of the destination range ([SimpleCellAddress](../api/interfaces/simplecelladdress)) -This method returns a list of cells whose values were affected by -this operation together with their absolute addresses and new values. +This method returns [an array of changed cells](#changes-array). ```javascript // choose the source cells @@ -270,8 +259,7 @@ You can set the content of a block of cells by using the `setCellContents` method. You need to pass the top left corner address of a block as a simple cell address, along with the content to be set. It can be content for either a single cell or a set of cells in an array. -This method returns a list of cells whose values were affected by this -operation together with their absolute addresses and new values. +This method returns [an array of changed cells](#changes-array). ```javascript // track the changes triggered by setting @@ -365,23 +353,53 @@ if (!isRemovable) { } ``` -## What are the "changes"? +## Changes array -Several methods return the "changes". This is a list of cells -whose values were affected by an operation, together with their -absolute addresses and new values. +All data modification methods return an array of `ExportedChange`. +This is a collection of cells whose **values** were affected by an operation, +together with their absolute addresses and new values. ```javascript - [{ - address: { sheet: 0, col: 0, row: 0 }, - newValue: { error: [CellError], value: '#REF!' }, - }] +[{ + address: { sheet: 0, col: 0, row: 0 }, + newValue: { error: [CellError], value: '#REF!' }, +}] ``` This gives you information about where the change happened, what the new value of a cell is, and even what type it is - in this case, an -error. The change shows only those parts where calculations were made; -it will return an empty array if there were none. +error. + +The array of changes includes only cells that have different **values** after performing the operation. See the example: + +```js +const hf = HyperFormula.buildFromArray([ + [0], + [1], + ['=SUM(A1:A2)'], + ['=COUNTBLANK(A1:A3)'], +]); + +// Insert an empty row between the row 0 and the row 1 +const changes = hf.addRows(0, [1, 1]); + +console.log(hf.getSheetSerialized(0)); +// Sheet after adding the row: +// [ +// [0], +// [], +// [1], +// ['=SUM(A1:A3)'], +// ['=COUNTBLANK(A1:A4)'], +// ] + +console.log(changes); +// Changes include only the COUNTBLANK cell: +// [{ +// address: { sheet: 0, row: 4, col: 0 }, +// newValue: 1, +// }] +``` ## Demo diff --git a/docs/guide/named-expressions.md b/docs/guide/named-expressions.md index fe5a83ba8..59603650c 100644 --- a/docs/guide/named-expressions.md +++ b/docs/guide/named-expressions.md @@ -85,10 +85,8 @@ You can add a named expression by using the `addNamedExpression` method. It accepts name for the expression, the expression as a raw cell content, and optionally the scope. If you do not define the scope it will be set to global, meaning the expression name will be valid for the whole workbook. If you want to -add many of them, it is advised to do so in a [batch](batch-operations.md). This -method returns a list of cells whose values were affected by this operation, -their absolute addresses, and new values. See the "changes" section in -[basic operations](basic-operations) for more info. +add many of them, it is advised to do so in a [batch](batch-operations.md). +This method returns [an array of changed cells](basic-operations.md#changes-array). ```javascript // add 'prettyName' expression to the local scope of 'Sheet1' (sheetId = 0) @@ -106,10 +104,8 @@ Select the name of an expression to change and pass it as the first parameter, then define the new expression as raw cell content and optionally add the scope. If you do not define the scope it will be set to global, meaning the expression will be valid for the whole workbook. If you want to change many of them, it is -advised to do so in a [batch](batch-operations.md). This method returns a list -of cells whose values were affected by this operation, their absolute addresses, -and new values. See the "changes" section in -[basic operations](basic-operations) for more info. +advised to do so in a [batch](batch-operations.md). +This method returns [an array of changed cells](basic-operations.md#changes-array). ```javascript // change the named expression @@ -124,9 +120,8 @@ const changes = hfInstance.changeNamedExpression( You can remove a named expression by using the `removeNamedExpression` method. Select the name of an expression to remove and pass it as the first parameter and optionally define the scope. If you do not define the scope it will be -understood as global, meaning, the whole workbook. This method returns a list of -[cells whose values were affected by this operation](basic-operations.md#what-are-the-changes), -their absolute addresses, and new values. +understood as global, meaning, the whole workbook. +This method returns [an array of changed cells](basic-operations.md#changes-array). ```javascript // remove 'prettyName' expression from 'Sheet1' (sheetId=0) @@ -150,7 +145,7 @@ Operations on named expressions throw errors when something goes wrong. These errors can be [handled](basic-operations.md#handling-an-error) to provide a good user experience in the application. It is also possible to check the availability of operations using `isItPossibleTo*` methods, which are also -described in [that section](basic-operations#isitpossibleto-methods). +described in [that section](basic-operations.md#isitpossibleto-methods). ## Demo diff --git a/src/HyperFormula.ts b/src/HyperFormula.ts index 8d23d7c2f..f4a0a4a4b 100644 --- a/src/HyperFormula.ts +++ b/src/HyperFormula.ts @@ -1048,6 +1048,8 @@ export class HyperFormula implements TypedEmitter { /** * Undo the previous operation. * + * Returns [an array of cells whose values changed as a result of this operation](/guide/basic-operations.md#changes-array). + * * Note that this method may trigger dependency graph recalculation. * * @fires [[valuesUpdated]] if recalculation was triggered by this change @@ -1078,6 +1080,8 @@ export class HyperFormula implements TypedEmitter { /** * Re-do recently undone operation. * + * Returns [an array of cells whose values changed as a result of this operation](/guide/basic-operations.md#changes-array). + * * Note that this method may trigger dependency graph recalculation. * * @fires [[valuesUpdated]] if recalculation was triggered by this change @@ -1202,6 +1206,8 @@ export class HyperFormula implements TypedEmitter { /** * Sets the content for a block of cells of a given coordinates. * + * Returns [an array of cells whose values changed as a result of this operation](/guide/basic-operations.md#changes-array). + * * Note that this method may trigger dependency graph recalculation. * * @param {SimpleCellAddress} topLeftCornerAddress - top left corner of block of cells @@ -1238,6 +1244,8 @@ export class HyperFormula implements TypedEmitter { /** * Reorders rows of a sheet according to a source-target mapping. * + * Returns [an array of cells whose values changed as a result of this operation](/guide/basic-operations.md#changes-array). + * * Note that this method may trigger dependency graph recalculation. * * @param {number} sheetId - ID of a sheet to operate on @@ -1327,6 +1335,8 @@ export class HyperFormula implements TypedEmitter { * Parameter `newRowOrder` should have a form `[ newPositionForRow0, newPositionForRow1, newPositionForRow2, ... ]`. * This method might be used to [sort the rows of a sheet](../../guide/sorting-data.md). * + * Returns [an array of cells whose values changed as a result of this operation](/guide/basic-operations.md#changes-array). + * * Note: This method may trigger dependency graph recalculation. * * @param {number} sheetId - ID of a sheet to operate on @@ -1403,6 +1413,8 @@ export class HyperFormula implements TypedEmitter { /** * Reorders columns of a sheet according to a source-target mapping. * + * Returns [an array of cells whose values changed as a result of this operation](/guide/basic-operations.md#changes-array). + * * Note that this method may trigger dependency graph recalculation. * * @param {number} sheetId - ID of a sheet to operate on @@ -1488,6 +1500,8 @@ export class HyperFormula implements TypedEmitter { * Parameter `newColumnOrder` should have a form `[ newPositionForColumn0, newPositionForColumn1, newPositionForColumn2, ... ]`. * This method might be used to [sort the columns of a sheet](../../guide/sorting-data.md). * + * Returns [an array of cells whose values changed as a result of this operation](/guide/basic-operations.md#changes-array). + * * Note: This method may trigger dependency graph recalculation. * * @param {number} sheetId - ID of a sheet to operate on @@ -1596,6 +1610,8 @@ export class HyperFormula implements TypedEmitter { * Adds multiple rows into a specified position in a given sheet. * Does nothing if rows are outside effective sheet size. * + * Returns [an array of cells whose values changed as a result of this operation](/guide/basic-operations.md#changes-array). + * * Note that this method may trigger dependency graph recalculation. * * @param {number} sheetId - sheet ID in which rows will be added @@ -1667,6 +1683,8 @@ export class HyperFormula implements TypedEmitter { * Removes multiple rows from a specified position in a given sheet. * Does nothing if rows are outside the effective sheet size. * + * Returns [an array of cells whose values changed as a result of this operation](/guide/basic-operations.md#changes-array). + * * Note that this method may trigger dependency graph recalculation. * * @param {number} sheetId - sheet ID from which rows will be removed @@ -1736,6 +1754,8 @@ export class HyperFormula implements TypedEmitter { * Adds multiple columns into a specified position in a given sheet. * Does nothing if the columns are outside the effective sheet size. * + * Returns [an array of cells whose values changed as a result of this operation](/guide/basic-operations.md#changes-array). + * * Note that this method may trigger dependency graph recalculation. * * @param {number} sheetId - sheet ID in which columns will be added @@ -1810,6 +1830,8 @@ export class HyperFormula implements TypedEmitter { * Removes multiple columns from a specified position in a given sheet. * Does nothing if columns are outside the effective sheet size. * + * Returns [an array of cells whose values changed as a result of this operation](/guide/basic-operations.md#changes-array). + * * Note that this method may trigger dependency graph recalculation. * * @param {number} sheetId - sheet ID from which columns will be removed @@ -1893,6 +1915,8 @@ export class HyperFormula implements TypedEmitter { /** * Moves the content of a cell block from source to the target location. * + * Returns [an array of cells whose values changed as a result of this operation](/guide/basic-operations.md#changes-array). + * * Note that this method may trigger dependency graph recalculation. * * @param {SimpleCellRange} source - range for a moved block @@ -1984,6 +2008,8 @@ export class HyperFormula implements TypedEmitter { /** * Moves a particular number of rows to a specified position in a given sheet. * + * Returns [an array of cells whose values changed as a result of this operation](/guide/basic-operations.md#changes-array). + * * Note that this method may trigger dependency graph recalculation. * * @param {number} sheetId - a sheet number in which the operation will be performed @@ -2064,6 +2090,8 @@ export class HyperFormula implements TypedEmitter { /** * Moves a particular number of columns to a specified position in a given sheet. * + * Returns [an array of cells whose values changed as a result of this operation](/guide/basic-operations.md#changes-array). + * * Note that this method may trigger dependency graph recalculation. * * @param {number} sheetId - a sheet number in which the operation will be performed @@ -2187,6 +2215,8 @@ export class HyperFormula implements TypedEmitter { * When called after [[cut]] it performs [[moveCells]] operation into the cell block. * Does nothing if the clipboard is empty. * + * Returns [an array of cells whose values changed as a result of this operation](/guide/basic-operations.md#changes-array). + * * Note that this method may trigger dependency graph recalculation. * * @param {SimpleCellAddress} targetLeftCorner - upper left address of the target cell block @@ -2581,6 +2611,8 @@ export class HyperFormula implements TypedEmitter { /** * Removes a sheet * + * Returns [an array of cells whose values changed as a result of this operation](/guide/basic-operations.md#changes-array). + * * Note that this method may trigger dependency graph recalculation. * * @param {number} sheetId - sheet ID. @@ -2653,6 +2685,8 @@ export class HyperFormula implements TypedEmitter { /** * Clears the sheet content. Double-checks if the sheet exists. * + * Returns [an array of cells whose values changed as a result of this operation](/guide/basic-operations.md#changes-array). + * * Note that this method may trigger dependency graph recalculation. * * @param {number} sheetId - sheet ID. @@ -2724,6 +2758,8 @@ export class HyperFormula implements TypedEmitter { /** * Replaces the sheet content with new values. * + * Returns [an array of cells whose values changed as a result of this operation](/guide/basic-operations.md#changes-array). + * * @param {number} sheetId - sheet ID. * @param {RawCellContent[][]} values - array of new values * @@ -3393,6 +3429,8 @@ export class HyperFormula implements TypedEmitter { /** * Runs multiple operations and recomputes formulas at the end. * + * Returns [an array of cells whose values changed as a result of all batched operations](/guide/basic-operations.md#changes-array). + * * Note that this method may trigger dependency graph recalculation. * * @param {() => void} batchOperations - a function with operations to be performed @@ -3473,7 +3511,7 @@ export class HyperFormula implements TypedEmitter { /** * Resumes the dependency graph recalculation that was suspended with [[suspendEvaluation]]. - * It also triggers the recalculation and returns changes that are a result of all batched operations. + * It also triggers the recalculation and returns [an array of cells whose values changed as a result of all batched operations](/guide/basic-operations.md#changes-array). * * @fires [[valuesUpdated]] if recalculation was triggered by this change * @fires [[evaluationResumed]] after the recomputation of necessary values @@ -3573,6 +3611,8 @@ export class HyperFormula implements TypedEmitter { /** * Adds a specified named expression. * + * Returns [an array of cells whose values changed as a result of this operation](/guide/basic-operations.md#changes-array). + * * Note that this method may trigger dependency graph recalculation. * * @param {string} expressionName - a name of the expression to be added @@ -3791,6 +3831,8 @@ export class HyperFormula implements TypedEmitter { /** * Changes a given named expression to a specified formula. * + * Returns [an array of cells whose values changed as a result of this operation](/guide/basic-operations.md#changes-array). + * * Note that this method may trigger dependency graph recalculation. * * @param {string} expressionName - an expression name, case-insensitive. @@ -3873,6 +3915,8 @@ export class HyperFormula implements TypedEmitter { /** * Removes a named expression. * + * Returns [an array of cells whose values changed as a result of this operation](/guide/basic-operations.md#changes-array). + * * Note that this method may trigger dependency graph recalculation. * * @param {string} expressionName - expression name, case-insensitive. @@ -4380,6 +4424,8 @@ export class HyperFormula implements TypedEmitter { /** * Runs a recomputation starting from recently changed vertices. * + * Returns [an array of cells whose values changed as a result of this operation](/guide/basic-operations.md#changes-array). + * * Note that this method may trigger dependency graph recalculation. * * @fires [[valuesUpdated]] if recalculation was triggered by this change diff --git a/test/cruds/adding-row.spec.ts b/test/cruds/adding-row.spec.ts index f887baa5c..51b0f5f2c 100644 --- a/test/cruds/adding-row.spec.ts +++ b/test/cruds/adding-row.spec.ts @@ -194,16 +194,58 @@ describe('Adding row - reevaluation', () => { expect(c1setCellValueSpy).toHaveBeenCalled() }) - it('returns changed values', () => { - const engine = HyperFormula.buildFromArray([ - ['1'], - ['2', '=COUNTBLANK(A1:A2)'], - ]) + describe('returns array of changes', () => { + it('not including a value cell that was shifted due to adding a row before it', () => { + const engine = HyperFormula.buildFromArray([['1'],]) + + const changes = engine.addRows(0, [0, 1]) + expect(changes.length).toBe(0) + }) + + it('not including a formula cell that was shifted due to adding a row before it, but its value is the same', () => { + const engine = HyperFormula.buildFromArray([ + [1, 2], + ['=SUM(A1:B1)'], + ]) + + const changes = engine.addRows(0, [1, 1]) + expect(changes.length).toBe(0) + }) + + it('not including a formula cell in which the cell references changed (due to the row shift), but its value is the same', () => { + const engine = HyperFormula.buildFromArray([ + ['=SUM(A2:B2)'], + [1, 2], + ]) + + const changes = engine.addRows(0, [1, 1]) + expect(changes.length).toBe(0) + }) + + it('including a formula cell that was re-evaluated to different result', () => { + const engine = HyperFormula.buildFromArray([ + ['1'], + ['2', '=COUNTBLANK(A1:A2)'], + ]) + + const changes = engine.addRows(0, [1, 1]) + + expect(changes.length).toBe(1) + expect(changes).toContainEqual(new ExportedCellChange(adr('B3'), 1)) + }) + + it('not including a formula cell that was re-evaluated to same result', () => { + const engine = HyperFormula.buildFromArray([ + ['1'], + ['2', '=ROWS(A1:A2)-COUNTBLANK(A1:A2)'], + ]) - const changes = engine.addRows(0, [1, 1]) + expect(engine.getCellValue(adr('B2'))).toBe(2) - expect(changes.length).toBe(1) - expect(changes).toContainEqual(new ExportedCellChange(adr('B3'), 1)) + const changes = engine.addRows(0, [1, 1]) + + expect(changes.length).toBe(0) + }) }) })