Skip to content

Commit

Permalink
fix(formula): fix cut paste bug of formula (#4582)
Browse files Browse the repository at this point in the history
  • Loading branch information
wpxp123456 authored Feb 5, 2025
1 parent a54ab30 commit d9043ef
Showing 1 changed file with 127 additions and 55 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ function getValueMatrix(
return getSpecialPasteFormulaValueMatrix(unitId, subUnitId, range, matrix, lexerTreeBuilder, formulaDataModel, pasteFrom);
}

return getDefaultPasteValueMatrix(unitId, subUnitId, range, matrix, lexerTreeBuilder, formulaDataModel, pasteFrom);
return getDefaultPasteValueMatrix(unitId, subUnitId, range, matrix, copyInfo.copyType, lexerTreeBuilder, formulaDataModel, pasteFrom);
}

function getValueMatrixOfPasteFromIsNull(
Expand Down Expand Up @@ -386,83 +386,155 @@ function getSpecialPasteFormulaValueMatrix(
return valueMatrix;
}

// eslint-disable-next-line
function getDefaultPasteValueMatrix(
unitId: string,
subUnitId: string,
range: IDiscreteRange,
matrix: ObjectMatrix<ICellDataWithSpanInfo>,
copyType: COPY_TYPE,
lexerTreeBuilder: LexerTreeBuilder,
formulaDataModel: FormulaDataModel,
pasteFrom: ISheetDiscreteRangeLocation
): ObjectMatrix<ICellData> {
const valueMatrix = new ObjectMatrix<ICellData>();
const formulaIdMap = new Map<string, string>();
const formulaData = formulaDataModel.getSheetFormulaData(unitId, subUnitId);
const cutFormulaIds: string[] = [];

if (copyType === COPY_TYPE.CUT) {
// If cut, the formula range should not be moved.
matrix.forValue((row, col, value) => {
const toRow = range.rows[row];
const toCol = range.cols[col];
const valueObject: ICellDataWithSpanInfo = {};

if (isFormulaId(value.si)) {
if (isFormulaString(value.f)) {
cutFormulaIds.push(value.si as string);

valueObject.f = value.f;
valueObject.si = value.si;
} else if (cutFormulaIds.includes(value.si as string)) {
valueObject.f = null;
valueObject.si = value.si;
} else {
const formulaString = formulaDataModel.getFormulaStringByCell(
pasteFrom.range.rows[row % pasteFrom.range.rows.length],
pasteFrom.range.cols[col % pasteFrom.range.cols.length],
pasteFrom.subUnitId,
pasteFrom.unitId
);

valueObject.f = formulaString;
valueObject.si = null;
}

matrix.forValue((row, col, value) => {
const toRow = range.rows[row];
const toCol = range.cols[col];
const valueObject: ICellDataWithSpanInfo = {};

if (isFormulaId(value.si)) {
// If the copy value is a formula
if (pasteFrom.unitId !== unitId || pasteFrom.subUnitId !== subUnitId) {
const formulaString = formulaDataModel.getFormulaStringByCell(
pasteFrom.range.rows[row % pasteFrom.range.rows.length],
pasteFrom.range.cols[col % pasteFrom.range.cols.length],
pasteFrom.subUnitId,
pasteFrom.unitId
);
const offsetX = range.cols[col] - pasteFrom.range.cols[col % pasteFrom.range.cols.length];
const offsetY = range.rows[row] - pasteFrom.range.rows[row % pasteFrom.range.rows.length];
const shiftedFormula = lexerTreeBuilder.moveFormulaRefOffset(formulaString || '', offsetX, offsetY);
valueObject.v = null;
valueObject.p = null;

valueMatrix.setValue(toRow, toCol, valueObject);
} else if (isFormulaString(value.f)) {
valueObject.f = value.f;
valueObject.si = null;
valueObject.f = shiftedFormula;
} else {
valueObject.si = value.si;
valueObject.f = null;
}

valueObject.v = null;
valueObject.p = null;
valueObject.v = null;
valueObject.p = null;

valueMatrix.setValue(toRow, toCol, valueObject);
} else if (isFormulaString(value.f)) {
// If the copy value is a formula
const index = `${row % pasteFrom.range.rows.length}_${col % pasteFrom.range.cols.length}`;
let formulaId = formulaIdMap.get(index);
valueMatrix.setValue(toRow, toCol, valueObject);
}
});
} else {
// copy, the formula range should be moved.
matrix.forValue((row, col, value) => {
const toRow = range.rows[row];
const toCol = range.cols[col];
const valueObject: ICellDataWithSpanInfo = {};

if (isFormulaId(value.si)) {
// If the copy value is a formula
if (pasteFrom.unitId !== unitId || pasteFrom.subUnitId !== subUnitId) {
const formulaString = formulaDataModel.getFormulaStringByCell(
pasteFrom.range.rows[row % pasteFrom.range.rows.length],
pasteFrom.range.cols[col % pasteFrom.range.cols.length],
pasteFrom.subUnitId,
pasteFrom.unitId
);
const offsetX = range.cols[col] - pasteFrom.range.cols[col % pasteFrom.range.cols.length];
const offsetY = range.rows[row] - pasteFrom.range.rows[row % pasteFrom.range.rows.length];
const shiftedFormula = lexerTreeBuilder.moveFormulaRefOffset(formulaString || '', offsetX, offsetY);

valueObject.si = null;
valueObject.f = shiftedFormula;
} else {
valueObject.si = value.si;
valueObject.f = null;
}

if (!formulaId) {
formulaId = Tools.generateRandomId(6);
formulaIdMap.set(index, formulaId);
valueObject.v = null;
valueObject.p = null;

valueMatrix.setValue(toRow, toCol, valueObject);
} else if (isFormulaString(value.f)) {
// If the copy value is a formula
const index = `${row % pasteFrom.range.rows.length}_${col % pasteFrom.range.cols.length}`;
let formulaId = formulaIdMap.get(index);

if (!formulaId) {
formulaId = Tools.generateRandomId(6);
formulaIdMap.set(index, formulaId);

const offsetX = range.cols[col] - pasteFrom.range.cols[col % pasteFrom.range.cols.length];
const offsetY = range.rows[row] - pasteFrom.range.rows[row % pasteFrom.range.rows.length];
const shiftedFormula = lexerTreeBuilder.moveFormulaRefOffset(value.f || '', offsetX, offsetY);

valueObject.si = formulaId;
valueObject.f = shiftedFormula;
} else {
// At the beginning of the second formula, set formulaId only
valueObject.si = formulaId;
valueObject.f = null;
}

const offsetX = range.cols[col] - pasteFrom.range.cols[col % pasteFrom.range.cols.length];
const offsetY = range.rows[row] - pasteFrom.range.rows[row % pasteFrom.range.rows.length];
const shiftedFormula = lexerTreeBuilder.moveFormulaRefOffset(value.f || '', offsetX, offsetY);
valueObject.v = null;
valueObject.p = null;

valueObject.si = formulaId;
valueObject.f = shiftedFormula;
} else {
// At the beginning of the second formula, set formulaId only
valueObject.si = formulaId;
valueMatrix.setValue(toRow, toCol, valueObject);
} else if (formulaData?.[toRow]?.[toCol]) {
// If the paste location is a formula
valueObject.v = value.v;
valueObject.f = null;
}
valueObject.si = null;
valueObject.p = value.p;

valueObject.v = null;
valueObject.p = null;
valueMatrix.setValue(toRow, toCol, valueObject);
}
});
}

valueMatrix.setValue(toRow, toCol, valueObject);
} else if (formulaData?.[toRow]?.[toCol]) {
// If the paste location is a formula
valueObject.v = value.v;
valueObject.f = null;
valueObject.si = null;
valueObject.p = value.p;
// If cut range has the first formula id, remove the related formula ids and convert it to formula string.
if (cutFormulaIds.length > 0) {
new ObjectMatrix(formulaData!).forValue((row, col, value) => {
if (
!(pasteFrom.range.rows.includes(row) && pasteFrom.range.cols.includes(col)) &&
!(range.rows.includes(row) && range.cols.includes(col)) &&
cutFormulaIds.includes(value?.si as string)
) {
const formulaString = formulaDataModel.getFormulaStringByCell(
row,
col,
pasteFrom.subUnitId,
pasteFrom.unitId
);

valueMatrix.setValue(toRow, toCol, valueObject);
}
});
valueMatrix.setValue(row, col, {
f: formulaString,
si: null,
v: null,
p: null,
});
}
});
}

return valueMatrix;
}
Expand Down

0 comments on commit d9043ef

Please sign in to comment.