首页 > 解决方案 > 您如何根据另一个单元格显示/隐藏行?(Google Apps 脚本/表格)

问题描述

目标:单击按钮/选择选项以隐藏/显示多行。例如,单击/选择隐藏行 A5-A8 的单元格 A4 和隐藏行 A46-A59 的另一个 A45。一个按钮将是首选,但我会采取任何措施。如果我可以使用自定义图像,则可以加分。

我有一个隐藏行的功能,但它有时只能工作,可能很慢(需要 5 秒或 20 秒以上,尽管我有 900 行)或者有时只隐藏一些列表而不管长度。我从其他地方复制了这个函数,我可能没有以最好的方式实现它,这可能解释了一些问题,但这就是它的工作原理。

在 B8 上有一个下拉列表(数据验证、项目列表)。有两个选项,一个是空白(技术上是一个不可见字符),另一个是“H”。在 C 列中,我将此代码复制到要隐藏的特定单元格中:

=IF(B8="H","Hide","Show")

这是脚本:

/** HideRow */
function onEdit()
{
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
  var lastRow = sheet.getLastRow();
  for( i=1 ; i<=lastRow ; i++) { // i <= lastRow

    var status = sheet.getRange("C"+i).getValue();  // C = the column that writes Show/Hide

    if (status == "Hide") {                                           // status == "Hide" 
         sheet.hideRows(i);
       } 
    if (status == "Show"){                                           // status == "Show" 
     sheet.showRows(i); 
    }
   }
}

我会随着时间的推移添加更多行,我不知道脚本是否会在单元格移动时跟踪它,这就是为什么我在单个单元格中编写了一行代码(也许一个数组会修复由于冗余而导致的减速?) . 尽管如果它在脚本中的效果比无论如何都要好。在这种情况下,命名范围有用吗?

我看过其他一些但没有运气,主要是因为除了变量之外我不确定我还需要改变什么。

标签: google-apps-scriptgoogle-sheetshideshow-hideshow

解决方案


onSelectionChange 触发器

您只需进行新的选择并选择 A4 或 A45,这将切换指定行的可见性。关键是,如果您已经在其中一个单元格上,并且再次选择它不起作用,则必须在所选范围内进行更改。

好消息是您不需要任何按钮或复选框。

function onSelectionChange(e) {
  //Logger.log(JSON.stringify(e));
  //e.source.toast('Entry');
  const C=['A4','A45'];//trigger ranges
  const R=[{row:5,count:4},{row:46,count:14}];//hide/show ranges with row and count for each
  const sh=e.range.getSheet();
  const idx=C.indexOf(e.range.getA1Notation());
  if(idx!=-1) {
    //e.source.toast('idx= ' + idx);
    if(sh.isRowHiddenByUser(R[idx].row)) {
      sh.showRows(R[idx].row,R[idx].count);
    }else{
      sh.hideRows(R[idx].row,R[idx].count);      
    }
  }
}

此版本使用触发字符串 ~1~ 和 ~2~ 并使用 1 行的相对偏移量,这是可配置的

function onSelectionChange(e) {
  //Logger.log(JSON.stringify(e));
  //e.source.toast('Entry');
  const T=['~1~','~2~'];
  const R=[{row:0,offset:1,count:4},{row:0,offset:1,count:14}];
  const sh=e.range.getSheet();
  const idx=T.indexOf(e.range.getValue());
  R[idx].row=e.range.getRow()+R[idx].offset
  if(idx!=-1) {
    //e.source.toast('idx= ' + idx);
    if(sh.isRowHiddenByUser(R[idx].row)) {
      sh.showRows(R[idx].row,R[idx].count);
    }else{
      sh.hideRows(R[idx].row,R[idx].count);      
    }
  }
}

另一个版本:

function onSelectionChange(e) {
  e.source.toast('Entry');
  const obj={T:[],R:[new shrows(1,5,'~1~'),new shrows(1,5,'~2~'),new shrows(1,5,'~3~'),new shrows(1,5,'~4~')]};
  obj.R.forEach(function(e,i){obj.T.push(e.tstring)});
  const sh=e.range.getSheet();
  const idx=obj.T.indexOf(e.range.getValue());
  obj.R[idx].row=e.range.getRow()+obj.R[idx].offset
  if(idx!=-1) {
    //e.source.toast('idx= ' + idx);
    if(sh.isRowHiddenByUser(obj.R[idx].row)) {
      sh.showRows(obj.R[idx].row,obj.R[idx].count);
    }else{
      sh.hideRows(obj.R[idx].row,obj.R[idx].count);      
    }
  }
}

function shrows(offset,count,tstring) {
  this.offset=offset;
  this.count=count;
  this.tstring=tstring;
  this.row=0;
}

关于此触发器的坏消息是似乎还没有可安装的版本,因此您无法执行需要权限的操作。

onSelectionChange()


推荐阅读