一、场景描述 1、目前有层级结构的数据可以通过将数据集转换为树数据集,然后结合下拉树或者视图树控件来展示,但是控件本身功能有限,无法在展示层级结构的同时满足填报计算+提交的效果
2、此类场景问题可以通过获取相邻单元格层级然后循环计算上下格数据,达到一个实时计算的效果。从基本的二层联动逻辑上出发,可以逐渐实现多层级自动计算效果,具体效果如下:
多级联动计算效果:
二、二级联动1、计算思路
(1)获取当前单元格值和对应层级的值,并用设置参数jj,公式值为len(value("测试表",1)),也就是获取到表的行数 - var location = this.options.location; //获取当前控件的位置
- var cr = FR.cellStr2ColumnRow(location);
- var col = cr.col; //列号
- var ro = cr.row; //行号
- //获取当前单元格的数据
- var score_obj = contentPane.getWidgetByCell(FR.columnRow2CellStr({
- col: col,
- row: ro
- }));
- var score=Number(score_obj.getValue());
- //获取当前层级
- var rank_obj = contentPane.getWidgetByCell(FR.columnRow2CellStr({
- col: col-1,
- row: ro
- }));
- var rank=Number(rank_obj.getValue());
复制代码
(2)关键计算逻辑:以当前单元格为起始,先向上检索层级,如果检索到层级为1,也就是当前的父层级就停止,将经过的子层级数据相加;然后向下检索层级,如果检索到层级为1,也将经过的子层级相加,最终两者之和会赋值给父层级。 - //循环检索计算
- var sum1=score;
- var ii=ro;
- //向下检索并求和
- for (var i = 1; i < jj-ii+1 ;i++) {
- var rank1=Number(contentPane.getWidgetByCell(FR.columnRow2CellStr({col:col-1,row: ro+i})).getValue());
- var score1=Number(contentPane.getWidgetByCell(FR.columnRow2CellStr({col:col,row: ro+i})).getValue());
- sum1=sum1+score1;
- if(rank1<rank){sum1=sum1-score1;break;}
- }
- //继续向上检索求和,然后赋值给上一层级
- for (var i = 1; i<jj; i++) {
- var rank2=Number(contentPane.getWidgetByCell(FR.columnRow2CellStr({col:col-1,row: ro-i})).getValue());
- var score2=Number(contentPane.getWidgetByCell(FR.columnRow2CellStr({col:col,row: ro-i})).getValue());
- sum1=sum1+score2;
- //alert(sum1)
- if(rank2<rank)
- {contentPane.setCellValue(col,ro-i,sum1-score2);break;}
- }
复制代码
2、注意事项
(1)由于有些字段格式是字符串,在获取值的时候用Number()进行转换,防止字符串类型数据与数字型相加,得到错误的计算结果
(2)层级那一列在列宽为0时,js获取会报错。可以设置列宽为1毫米,然后设置内边框有无作为替代方案
(3)层级为1的单元格可以通过条件属性设置为控件不可用,实际应用中也是由上层汇总下层数据,直接修改上层数据会导致数据计算错乱 三、三级联动1、内层计算
(1)计算层级3的数据,也就是只有两层时的计算逻辑
(2)获得外层遍历时的起始位置,避免重复运算
var mark1=0;//向下遍历时起始位置
var mark2=0;//向上遍历时起始位置
2、外层计算
(1)循环遍历所有层级2的值
(2)最终赋值给最近的一个层级1(也就是向上检索时碰到的第一个层级1),然后跳出结束; - var sum2=0;
- for(var i=mark1+1;i < jj-ii+1 ;i++){
- var rank3=Number(contentPane.getWidgetByCell(FR.columnRow2CellStr({col:col-1,row: ro+i})).getValue());
- var score3=Number(contentPane.getWidgetByCell(FR.columnRow2CellStr({col:col,row: ro+i})).getValue());
- if(rank3==2)
- {sum2=sum2+score3;}
- }
- for (var i = mark2-1; i<jj; i++) {
- var rank3=Number(contentPane.getWidgetByCell(FR.columnRow2CellStr({col:col-1,row: ro-i})).getValue());
- var score3=Number(contentPane.getWidgetByCell(FR.columnRow2CellStr({col:col,row: ro-i})).getValue());
- if(rank3==2)
- {sum2=sum2+score3};
- if(rank3==1){
- contentPane.setCellValue(col,ro-i,sum2);
- break;}
- }
复制代码
四、多级联动1、实际场景中,只需要编辑最底层的数据,然后往上层依次汇总的到上层数据,可以直接在原js基础上进行扩展,如层级为4时可以加在层级3汇总给层级2之前,因为js是依次计算,可以获取最新计算后的值 - var mark1=0;
- var mark2=0;
- var sum3=0;
- for(var i=mark1+1;i < jj-ii+1 ;i++){
- var rank4=Number(contentPane.getWidgetByCell(FR.columnRow2CellStr({col:col-1,row: ro+i})).getValue());
- var score4=Number(contentPane.getWidgetByCell(FR.columnRow2CellStr({col:col,row: ro+i})).getValue());
- //由于最低层是4,所以汇总层级为3的值
- if(rank4==3)
- {sum3=sum3+score4;}
- }
- for (var i = mark2-1; i<jj; i++) {
- var rank4=Number(contentPane.getWidgetByCell(FR.columnRow2CellStr({col:col-1,row: ro-i})).getValue());
- var score4=Number(contentPane.getWidgetByCell(FR.columnRow2CellStr({col:col,row: ro-i})).getValue());
-
- if(rank4==3)
- {sum3=sum3+score4};
- //向上检索找到最近的层级2,所以将汇总的层级为3的值给该层级2
- if(rank3==2){
- contentPane.setCellValue(col,ro-i,sum3);
- break;}
- }
复制代码
2、由于汇总计算都是用js实现,计算完的值需要提交到数据库后才能保存 部分js不支持移动端 五、附件提取码:8tlk 对你有帮助的话,可以点赞+关注+收藏,更多知识分享持续更新~ 编辑于 2021-6-15 10:44
|