如何解决OfficeJs - 使用流式调用时获取自定义函数的地址属性
目前,我正致力于在共享运行时加载项项目中从 CustomFunction.Invocation 更改为 StreamingInvocation,因为我将不得不使用 Web 套接字。 我有一个用例需要使用自定义函数的地址属性作为数据对象中的键以供进一步使用,我发现它不能与 StreamingInvocation 一起使用。我尝试使用 onChanged 和 oncalculated 事件实现一种解决方法,但效果不佳。因此,我不确定是否有一些解决方法可以用来在其自身内部获取自定义函数的地址属性。
export class TestExcelService {
private static instance: TestExcelService;
private dataEventEmtter?: EventEmitter;
// prevent direct construction call with new keyword.
// eslint-disable-next-line @typescript-eslint/no-empty-function
private constructor() {
this.registerOncalculated();
}
public static getInstance(): TestExcelService {
if (!TestExcelService.instance) {
TestExcelService.instance = new TestExcelService();
}
return TestExcelService.instance;
}
public setDataEventEmtter(eventEmitter: EventEmitter): void {
this.dataEventEmtter = eventEmitter;
}
public getDataEventEmtter(): EventEmitter | undefined {
return this.dataEventEmtter;
}
private async registerOncalculated(): Promise<void> {
await Excel.run(async (context: Excel.RequestContext) => {
context.workbook.worksheets.getActiveWorksheet().oncalculated.add(
async (arg: Excel.WorksheetCalculatedEventArgs): Promise<void> => {
const formulaAddresses: ICellAddress[] = await this.filterMyFormulaAddress(arg);
if (this.dataEventEmtter && formulaAddresses.length > 0) {
this.dataEventEmtter.emit('onExcelCalculated',formulaAddresses);
}
},);
});
}
private async filterMyFormulaAddress(arg: Excel.WorksheetCalculatedEventArgs): Promise<ICellAddress[]> {
// filter only some formulas
return [];
}
}
export class TestDataService {
private eventEmitter: EventEmitter = new EventEmitter();
private static instance: TestDataService;
private dataQueue = [];
// prevent direct construction call with new keyword.
// eslint-disable-next-line @typescript-eslint/no-empty-function
private constructor() {
this.eventEmitter.addListener('onExcelCalculated',this.excelCalculatedHandler.bind(this));
}
public static getInstance(): TestDataService {
if (!TestDataService.instance) {
TestDataService.instance = new TestDataService();
}
return TestDataService.instance;
}
public addDataToQueue(data): void {
const duplicatedindex: number = this.dataQueue.findindex(
(queueData) => data.formulaId === queueData.formulaId,);
if (duplicatedindex < 0) {
this.dataQueue.push(data);
}
}
public getEventEmitter(): EventEmitter {
return this.eventEmitter;
}
private async excelCalculatedHandler(formulaAddresses: ICellAddress[]): Promise<void> {
if (Array.isArray(this.dataQueue) && this.dataQueue.length > 0) {
// check that data queue is not empty and map formula addresses from oncalculated event to the data queue
}
}
}
总的想法是我将必须用它们各自的公式地址映射到数据服务中的数据队列的数据对象添加,并且在触发 oncalculated 事件后,我应该能够获得计算和过滤地址的列表。
根据我的测试,公式地址的顺序应该与数据队列的顺序匹配。起初,当我一次执行一个公式或同时重新计算少量公式时,此解决方法似乎工作正常,但是当公式数量开始增加并且我尝试重新计算所有公式时,公式的顺序地址和数据队列将不会如我预期的那样匹配。
解决方法
流媒体功能很特别。如果任何一组流函数使用相同的表达式,则它们共享相同的根(即上下文)。范围在工作簿中很好。在另一个工作簿中,上下文会有所不同。所以没有为流功能提供地址信息。如您所见, onCalculated 事件将记录所有计算出的地址。但是,对于地址的特殊请求,它需要额外的逻辑,例如保持公式地址的顺序以匹配您的案例中的数据队列。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。