Google apps script 如何基于另一个单元格显示/隐藏行?(谷歌应用程序脚本/表单)

Google apps script 如何基于另一个单元格显示/隐藏行?(谷歌应用程序脚本/表单),google-apps-script,google-sheets,hide,show-hide,show,Google Apps Script,Google Sheets,Hide,Show Hide,Show,目标:单击按钮/选择选项以隐藏/显示多行。例如,在隐藏行A5-A8的单元格A4和另一个隐藏行A46-A59的单元格A45上单击/选择。一个按钮会更好,但我会采取任何。如果我可以使用自定义图像,则可获得额外积分 我有一个隐藏行的函数,但它只在某些时候起作用,在5s或20s+范围内的任何地方都可能很慢,尽管我有900行,或者有时只隐藏列表中的一些行,而不考虑长度。我从其他地方复制了这个函数,我可能没有以最好的方式实现它,这也许可以解释一些问题,但下面是它的工作原理 在B8上有一个下拉列表数据验证,项

目标:单击按钮/选择选项以隐藏/显示多行。例如,在隐藏行A5-A8的单元格A4和另一个隐藏行A46-A59的单元格A45上单击/选择。一个按钮会更好,但我会采取任何。如果我可以使用自定义图像,则可获得额外积分

我有一个隐藏行的函数,但它只在某些时候起作用,在5s或20s+范围内的任何地方都可能很慢,尽管我有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); 
    }
   }
}
随着时间的推移,我将添加更多的行,我不知道脚本在移动时是否跟踪单元格,这就是为什么我在单个单元格中编写了一行代码,也许数组可以修复由于冗余而导致的速度减慢?。尽管如果它在脚本中比在任何情况下都更有效,请执行它。在这种情况下,命名范围有用吗

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

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;
}
关于此触发器的坏消息是,似乎还没有可安装的版本,因此您无法执行需要权限的操作


所以它确实有效。。。但是最后一个问题。如果我在A4上方添加一个新行,这将把它向下推到A5。这意味着我必须将脚本中的值更新为A5才能工作。我有很多这样的下拉列表,根据我必须插入的信息,可能会在任何地方添加新行,而不仅仅是在底部。有没有办法让它保持原来的位置?这就是为什么我写这篇文章是为了寻找一个触发词。虽然这可能就是为什么它很慢,而你的是快速浏览整个列而不是特定的单元格。这意味着什么?我们可以检查每次选择更改的值,并触发唯一值。您正在考虑哪种类型的值?您希望隐藏的行是否总是与具有触发器字符串的单元格的固定偏移量?如果我理解正确,是的。每个下拉列表隐藏的数量相同,例如A4隐藏4行,而A45隐藏14行,以此类推。