找回密码
 立即注册

QQ登录

只需一步,快速开始

Coco_

注册会员

16

主题

41

帖子

149

积分

注册会员

积分
149
Coco_
注册会员   /  发表于:2023-8-8 19:35  /   查看:1758  /  回复:5
1金币
本帖最后由 Coco_ 于 2023-8-9 11:23 编辑

image.png337864989.png

如图,自定义了一个函数,功能为:在表头汇总所有 可见数据中 type不为a的数据。evaluate函数代码如下:
  1.                 let col = range.getColumn() , row = range.getRow() , rowCount = range.getRowCount() , colCount = range.getColumnCount();
  2.                 var sum = 0;
  3.                 for(let i = 0 ; i < rowCount ; i++){
复制代码
image.png818423461.png 修改值函数正常运行。
在筛选和排序事件回调中,都加上了计算公式的代码。
  1.   sheet.bind(GC.Spread.Sheets.Events.RangeSorted, function (e, info) {
  2.                         sheet.recalcAll();
  3.                 });

  4.                 sheet.bind(GC.Spread.Sheets.Events.RangeFiltered, function (e, info) {
  5.                         sheet.recalcAll();
  6.                 });
复制代码
筛选后值不会发生变化,好像是没调用函数
image.png232272643.png
重新排序之后函数又可以正常计算
image.png348348693.png
请问一下为什么在过滤事件回调中调用recalcAll方法无效?



image.png241578063.png

demo.zip

2.16 KB, 下载次数: 70

最佳答案

查看完整内容

你好,我猜在事件中直接调用计算会破坏已有的重算结构。把recalcAll放到setTimeout里面就好了

5 个回复

倒序浏览
最佳答案
最佳答案
WilliamChang
葡萄城公司职员   /  发表于:2023-8-8 19:35:17
来自 3#
你好,我猜在事件中直接调用计算会破坏已有的重算结构。把recalcAll放到setTimeout里面就好了
  1.                
  2.                 sheet.bind(GC.Spread.Sheets.Events.RangeSorted, function (e, info) {
  3.                         setTimeout(()=>{sheet.recalcAll();});
  4.                 });

  5.                 sheet.bind(GC.Spread.Sheets.Events.RangeFiltered, function (e, info) {
  6.                         setTimeout(()=>{sheet.recalcAll();});
  7.                 });
复制代码
回复 使用道具 举报
Coco_
注册会员   /  发表于:2023-8-8 19:37:08
2#
好像不能传附件,我把整个demo的js贴一下
  1. //自定义 可见区域的sumif 函数

  2. var sheet ;

  3. function SumIfVisibleFunction() {
  4.         this.name = "SUMIFVISIBLE";
  5.         this.maxArgs = 1;
  6.         this.minArgs = 1;
  7. }
  8. SumIfVisibleFunction.prototype = new GC.Spread.CalcEngine.Functions.Function();
  9. SumIfVisibleFunction.prototype.acceptsReference = function (index) {
  10.         return index === 0 ;
  11. }
  12. SumIfVisibleFunction.prototype.evaluate = function (range) {
  13.                 console.log("---计算函数")
  14.                 let col = range.getColumn() , row = range.getRow() , rowCount = range.getRowCount() , colCount = range.getColumnCount();
  15.                 var sum = 0;
  16.                 for(let i = 0 ; i < rowCount ; i++){
  17.                         if(sheet.getRowVisible( row + i)){
  18.                                 let value = sheet.getValue( row + i , col);
  19.                                 let type = sheet.getValue( row + i , 0);
  20.                                 if(!value || type === 'a'){
  21.                                         continue;
  22.                                 }
  23.                                 if(!isNaN(parseInt(value))) {
  24.                                         sum += parseInt(value);
  25.                                 }else{
  26.                                         return '#VALUE'
  27.                                 }
  28.                         }
  29.                 }
  30.                 return sum;
  31. }
  32. var sumifvisible = new SumIfVisibleFunction();
  33.    
  34.        
  35.        
  36.         window.onload = function () {
  37.         var spread = new GC.Spread.Sheets.Workbook(document.getElementById("ss"), { sheetCount: 2 });
  38.         initSpread(spread);

  39.     };
  40.        
  41.        
  42.        
  43.        
  44.        

  45.     function initSpread(spread) {
  46.         sheet = spread.getSheet(0);
  47.                
  48.                 let data = [
  49.                 { type : 'a' , value : 1 },
  50.                 { type : 'a' , value : 1 },
  51.                 { type : 'b' , value : 1 },
  52.                 { type : 'b' , value : 1 },
  53.                 { type : 'c' , value : 1 },
  54.                 { type : 'c' , value : 1 },
  55.                 { type : 'c' , value : 1 },
  56.                 ]
  57.                
  58.                 sheet.bindColumns([
  59.                 { name: 'type' } ,        { name: 'value' } ,
  60.                 ]);
  61.                
  62.                 sheet.setDataSource(data);
  63.                
  64.                                 sheet.addCustomFunction(sumifvisible);
  65.                 sheet.setFormula(0 , 1 , '=sumifvisible(Sheet1!B:B)' , GC.Spread.Sheets.SheetArea.colHeader);
  66.                
  67.                
  68.                 var basedFilterRange = new GC.Spread.Sheets.Range(-1,-1,-1,-1);
  69.                 var rowFilter = new GC.Spread.Sheets.Filter.HideRowFilter(basedFilterRange);
  70.                 sheet.rowFilter(rowFilter);
  71.                 rowFilter.filterButtonVisible(false);
  72.                 rowFilter.filterButtonVisible(0,true);
  73.                
  74.                
  75.                 sheet.bind(GC.Spread.Sheets.Events.RangeSorted, function (e, info) {
  76.                         sheet.recalcAll();
  77.                 });

  78.                 sheet.bind(GC.Spread.Sheets.Events.RangeFiltered, function (e, info) {
  79.                         sheet.recalcAll();
  80.                 });


  81.     };
  82.    
复制代码
  html就是咱们实例的代码
回复 使用道具 举报
Coco_
注册会员   /  发表于:2023-8-9 11:27:26
5#
WilliamChang 发表于 2023-8-9 10:33
你好,我猜在事件中直接调用计算会破坏已有的重算结构。把recalcAll放到setTimeout里面就好了

该方法可以解决
回复 使用道具 举报
Coco_
注册会员   /  发表于:2023-8-9 11:28:18
6#
Richard.Ma 发表于 2023-8-9 11:21
我这边验证一下,然后给你回复

已补充附件,根据楼上提供的方法已经解决问题,看是否还需要进一步分析
回复 使用道具 举报
Richard.Ma讲师达人认证 悬赏达人认证 SpreadJS 开发认证
超级版主   /  发表于:2023-8-9 11:39:21
7#
WilliamChang 发表于 2023-8-9 10:33
你好,我猜在事件中直接调用计算会破坏已有的重算结构。把recalcAll放到setTimeout里面就好了

加鸡腿
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 立即注册
返回顶部