Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"changes": [
{
"comment": "fix: cell formula cache error after delete row record\n\n",
"type": "none",
"packageName": "@visactor/vtable"
}
],
"packageName": "@visactor/vtable",
"email": "892739385@qq.com"
}
1 change: 1 addition & 0 deletions docs/assets/guide/en/custom_define/custom_icon.md
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,7 @@ The list of resettable internal icons is as follows:
| Fixed Columns | VTable. TYPES. IconFuncTypeEnum.frozen | "frozen" | Fixed Columns Function Icon, Fixed Status |
| Fixed Columns | VTable. TYPES. IconFuncTypeEnum.frozen | "frozenCurrent" | Fixed Columns Function Icon, Frozen When Columns |
| Image or video address invalid | VTable. TYPES. IconFuncTypeEnum.damagePic | "damage_pic" | Multimedia resource parsing failed |
| Loading | VTable. TYPES. IconFuncTypeEnum.loading_pic | "loading_pic" | Loading status |
| Image image type parsing failed | VTable. TYPES. IconFuncTypeEnum.imageDamagePic | "image_damage_pic" | Image resource parsing failed |
| Video video type parsing failed | VTable. TYPES. IconFuncTypeEnum.videoDamagePic | "video_damage_pic" | Video resource parsing failed |
| Tree Structure Folding | VTable. TYPES. IconFuncTypeEnum.collapse | "collapse" | Tree Structure Folded State |
Expand Down
1 change: 1 addition & 0 deletions docs/assets/guide/zh/custom_define/custom_icon.md
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,7 @@ VTable.register.icon('frozenCurrent', {
| 固定列 | VTable.TYPES.IconFuncTypeEnum.frozen | "frozen" | 固定列功能图标 已固定状态 |
| 固定列 | VTable.TYPES.IconFuncTypeEnum.frozen | "frozenCurrent" | 固定列功能图标 被冻结当列 |
| 图片 or 视频地址失效 | VTable.TYPES.IconFuncTypeEnum.damagePic | "damage_pic" | 多媒体资源解析失败 |
| 加载中 | VTable.TYPES.IconFuncTypeEnum.loading_pic | "loading_pic" | 加载中状态 |
|图片image类型解析失败 |VTable.TYPES.IconFuncTypeEnum.imageDamagePic | "image_damage_pic" | 图片资源解析失败 |
|视频video类型解析失败 |VTable.TYPES.IconFuncTypeEnum.videoDamagePic | "video_damage_pic" | 视频资源解析失败 |
| 树形结构折叠 | VTable.TYPES.IconFuncTypeEnum.collapse | "collapse" | 树形结构折叠状态 |
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
// @ts-nocheck
import { VTableSheet } from '../src/index';
import { createDiv, removeDom } from './dom';

// eslint-disable-next-line @typescript-eslint/no-explicit-any
(global as any).__VERSION__ = 'none';

describe('VTableSheet deleteRecords - 公式调整', () => {
let container: HTMLDivElement;
let sheetInstance: VTableSheet | null = null;

beforeEach(() => {
container = createDiv();
container.style.position = 'relative';
container.style.width = '1000px';
container.style.height = '800px';
});

afterEach(() => {
if (sheetInstance) {
sheetInstance.release();
sheetInstance = null;
}
removeDom(container);
});

test('删除第3行后,C7公式应移动并调整范围', () => {
sheetInstance = new VTableSheet(container, {
showSheetTab: true,
sheets: [
{
rowCount: 200,
columnCount: 10,
sheetKey: 'sheet1',
sheetTitle: 'sheet1',
filter: true,
columns: [
{
title: '名称',
sort: true,
width: 100
}
],
data: [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12], ['放到', '个', '哦'], [], [null, null, 30]],
formulas: {
C8: '=sum(C2:C5)'
},
active: true,
firstRowAsHeader: false
}
]
});

// 删除第3行数据(索引2)
sheetInstance.getActiveSheet().tableInstance?.deleteRecords([2]);

const formulaEngine = sheetInstance.formulaManager.formulaEngine;
const formula = sheetInstance.formulaManager.getCellFormula({ sheet: 'sheet1', row: 6, col: 2 });
expect(formula).toBe('=SUM(C2:C4)');
expect(sheetInstance.formulaManager.isCellFormula({ sheet: 'sheet1', row: 6, col: 2 })).toBe(true);
expect(formulaEngine.getCellFormula({ sheet: 'sheet1', row: 6, col: 2 })).toBe('=SUM(C2:C4)');
expect(formulaEngine.getCellFormula({ sheet: 'sheet1', row: 7, col: 2 })).toBeUndefined();

const exportedFormulas = formulaEngine.exportFormulas('sheet1');
expect(exportedFormulas.C7).toBe('=SUM(C2:C4)');
expect(exportedFormulas.C8).toBeUndefined();

const resultValue = sheetInstance.formulaManager.getCellValue({ sheet: 'sheet1', row: 6, col: 2 }).value;
expect(resultValue).toBe(21);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// @ts-nocheck
import { createFormulaDetectionOptions } from '../src/core/table-plugins';

describe('table-plugins formula detection', () => {
test('should use active worksheet key for formula lookup', () => {
const formulaManager = {
isCellFormula: jest.fn().mockReturnValue(true),
getCellFormula: jest.fn().mockReturnValue('=SUM(C2:C4)'),
setCellContent: jest.fn()
};

const vtableSheet = {
formulaManager,
getActiveSheet: () => ({
getKey: () => 'sheet1'
}),
sheetManager: {
_activeSheetKey: 'Sheet1',
getActiveSheet: () => ({ sheetKey: 'sheet1' })
}
};

const detection = createFormulaDetectionOptions(undefined, undefined, vtableSheet);

detection.isFormulaCell(2, 6, null, {} as any);
expect(formulaManager.isCellFormula).toHaveBeenCalledWith({ sheet: 'sheet1', row: 6, col: 2 });

detection.getCellFormula(2, 6, null, {} as any);
expect(formulaManager.getCellFormula).toHaveBeenCalledWith({ sheet: 'sheet1', row: 6, col: 2 });

detection.setCellFormula(2, 6, '=SUM(C2:C4)', {} as any);
expect(formulaManager.setCellContent).toHaveBeenCalledWith({ sheet: 'sheet1', row: 6, col: 2 }, '=SUM(C2:C4)');
});
});
4 changes: 4 additions & 0 deletions packages/vtable-sheet/examples/menu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,9 @@ export const menus = [
{
path: 'sheet',
name: 'sheet-update'
},
{
path: 'sheet',
name: 'sheet-deleteRecord'
}
];
60 changes: 60 additions & 0 deletions packages/vtable-sheet/examples/sheet/sheet-deleteRecord.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { VTableSheet, TYPES, VTable } from '../../src/index';
import * as VTablePlugins from '@visactor/vtable-plugins';
import { VTableSheetEventType } from '../../src/ts-types/spreadsheet-events';
const CONTAINER_ID = 'vTable';
export function createTable() {
// 清理之前的实例(如果存在)
if ((window as any).sheetInstance) {
(window as any).sheetInstance.release();
(window as any).sheetInstance = null;
}

const sheetInstance = new VTableSheet(document.getElementById(CONTAINER_ID)!, {
showSheetTab: true,
// defaultRowHeight: 25,
// defaultColWidth: 100,
sheets: [
{
rowCount: 200,
columnCount: 10,
sheetKey: 'sheet1',
sheetTitle: 'sheet1',
filter: true,
columns: [
{
title: '名称',
sort: true,
width: 100
}
],
data: [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12], ['放到', '个', '哦'], [], [null, null, 30]],
formulas: {
C8: '=sum(C2:C5)'
},
active: true
}
]
});
window.sheetInstance = sheetInstance;
//删除第3行数据
sheetInstance.getActiveSheet().tableInstance?.deleteRecords([2]);
// const tableInstance = sheetInstance.getActiveSheet().tableInstance;

// sheetInstance.formulaManager.setCellContent({ sheet: 'sheet1', row: 7, col: 3 }, '=SUM(C2:C5)');
// const result = sheetInstance.formulaManager.getCellValue({
// sheet: 'sheet1',
// row: 7,
// col: 3
// });
// sheetInstance
// .getActiveSheet()
// .tableInstance?.changeCellValue(3, 7, result.error ? '#ERROR!' : result.value, false, false);
//删除第3行数据
// sheetInstance.getActiveSheet().tableInstance?.deleteRecords([2]);
// debugger;
// sheetInstance.getActiveSheet().tableInstance?.startEditCell(3, 6);

// bindDebugTool(sheetInstance.activeWorkSheet.scenegraph.stage as any, {
// customGrapicKeys: ['role', '_updateTag']
// });
}
21 changes: 17 additions & 4 deletions packages/vtable-sheet/src/core/table-plugins.ts
Original file line number Diff line number Diff line change
Expand Up @@ -435,7 +435,20 @@ function handleDisableFirstRowAsHeader(table: VTable.ListTable): void {
/**
* 创建公式检测选项,使用vtable-sheet的公式引擎
*/
function createFormulaDetectionOptions(sheetDefine?: ISheetDefine, options?: IVTableSheetOptions, vtableSheet?: any) {
export function createFormulaDetectionOptions(
sheetDefine?: ISheetDefine,
options?: IVTableSheetOptions,
vtableSheet?: any
) {
const getActiveSheetKey = (): string => {
return (
vtableSheet?.getActiveSheet?.()?.getKey?.() ||
vtableSheet?.sheetManager?.getActiveSheet?.()?.sheetKey ||
sheetDefine?.sheetKey ||
'Sheet1'
);
};

return {
/**
* 自定义公式检测函数 - 使用vtable-sheet的公式引擎判断是否为公式
Expand All @@ -444,7 +457,7 @@ function createFormulaDetectionOptions(sheetDefine?: ISheetDefine, options?: IVT
// 首先尝试使用vtable-sheet的公式管理器
if (vtableSheet?.formulaManager) {
try {
const sheetName = (vtableSheet.sheetManager as any)?._activeSheetKey || 'Sheet1';
const sheetName = getActiveSheetKey();
return vtableSheet.formulaManager.isCellFormula({
sheet: sheetName,
row: row,
Expand Down Expand Up @@ -472,7 +485,7 @@ function createFormulaDetectionOptions(sheetDefine?: ISheetDefine, options?: IVT
// 首先尝试使用vtable-sheet的公式管理器
if (vtableSheet?.formulaManager) {
try {
const sheetName = (vtableSheet.sheetManager as any)?._activeSheetKey || 'Sheet1';
const sheetName = getActiveSheetKey();
return vtableSheet.formulaManager.getCellFormula({
sheet: sheetName,
row: row,
Expand All @@ -499,7 +512,7 @@ function createFormulaDetectionOptions(sheetDefine?: ISheetDefine, options?: IVT
// 首先尝试使用vtable-sheet的公式管理器
if (vtableSheet?.formulaManager) {
try {
const sheetName = (vtableSheet.sheetManager as any)?._activeSheetKey || 'Sheet1';
const sheetName = getActiveSheetKey();
vtableSheet.formulaManager.setCellContent(
{
sheet: sheetName,
Expand Down
12 changes: 6 additions & 6 deletions packages/vtable-sheet/src/managers/formula-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -784,7 +784,7 @@ export class FormulaManager implements IFormulaManager {
});
this.sheet
.getActiveSheet()
.tableInstance?.changeCellValue(cell.col, cell.row, result.error ? '#ERROR!' : result.value);
.tableInstance?.changeCellValue(cell.col, cell.row, result.error ? '#ERROR!' : result.value, false, false);
});
} catch (error) {
console.error('Failed to add rows:', error);
Expand Down Expand Up @@ -828,7 +828,7 @@ export class FormulaManager implements IFormulaManager {
});
this.sheet
.getActiveSheet()
.tableInstance?.changeCellValue(cell.col, cell.row, result.error ? '#ERROR!' : result.value);
.tableInstance?.changeCellValue(cell.col, cell.row, result.error ? '#ERROR!' : result.value, false, false);
});
} catch (error) {
console.error('Failed to remove rows:', error);
Expand Down Expand Up @@ -870,7 +870,7 @@ export class FormulaManager implements IFormulaManager {
});
this.sheet
.getActiveSheet()
.tableInstance?.changeCellValue(cell.col, cell.row, result.error ? '#ERROR!' : result.value);
.tableInstance?.changeCellValue(cell.col, cell.row, result.error ? '#ERROR!' : result.value, false, false);
});
} catch (error) {
console.error('Failed to add columns:', error);
Expand Down Expand Up @@ -913,7 +913,7 @@ export class FormulaManager implements IFormulaManager {
});
this.sheet
.getActiveSheet()
.tableInstance?.changeCellValue(cell.col, cell.row, result.error ? '#ERROR!' : result.value);
.tableInstance?.changeCellValue(cell.col, cell.row, result.error ? '#ERROR!' : result.value, false, false);
});
} catch (error) {
console.error('Failed to remove columns:', error);
Expand Down Expand Up @@ -955,7 +955,7 @@ export class FormulaManager implements IFormulaManager {
const result = this.getCellValue(cell);
this.sheet
.getActiveSheet()
.tableInstance?.changeCellValue(cell.col, cell.row, result.error ? '#ERROR!' : result.value);
.tableInstance?.changeCellValue(cell.col, cell.row, result.error ? '#ERROR!' : result.value, false, false);
}

// Log completion info
Expand Down Expand Up @@ -999,7 +999,7 @@ export class FormulaManager implements IFormulaManager {
const result = this.getCellValue(cell);
this.sheet
.getActiveSheet()
.tableInstance?.changeCellValue(cell.col, cell.row, result.error ? '#ERROR!' : result.value);
.tableInstance?.changeCellValue(cell.col, cell.row, result.error ? '#ERROR!' : result.value, false, false);
}

// Log completion info
Expand Down
Loading