【问题标题】:google apps script - hide / unhide rows based on cell value谷歌应用脚​​本 - 根据单元格值隐藏/取消隐藏行
【发布时间】:2018-04-13 07:03:47
【问题描述】:

我有一个用于工作的电子表格,并且一直在努力根据特定的单元格值隐藏/显示行。

有问题的电子表格为我们的供应商创建了一份合同,并且特定的单元格值(在我的情况下为 F16)应该通过隐藏/显示带有数据的相关行来触发合同中间部分的更改。 幸运的是,所有行都可以分为三个组,因此公式/脚本的最终前提应该是:

cell F16 = "A", "B" or "C" (cell value changes by a vlookup formula in that 
cell that is connected to a specific reference number)

Block1 = rows 16 to 27
Block2 = rows 28 to 39
Block3 = rows 40 to 51

if F16 = "A" - show block1, hide block2, hide block3
if F16 = "B" - hide block1, show block2, hide block3
if F16 = "C" - hide block1, hide block2, show block3

一直在玩这个:

function HideSelectedRows2() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = ss.getSheetByName("Contract"); // Enter sheet name
var row = s.getRange('AM:AM')
    .getValues(); // Enter column letter that has the texts "Unhide" and 
"Hide until here" 

// hide all rows except first
s.hideRows(2, s.getMaxRows() - 1);
for (var i = 0; i < row.length; i++) {
    // then if the row says "unhide", start unhiding from that row and 
unhide 1 row
    if (row[i][0] == 'Unhide') {
        s.showRows(i + 1);
    }

    // then if the row says 'Hide' start from the next row and hide until 
the end 
    else if (row[i][0] == 'Hide') {
        s.hideRows(i + 1);
    }
}
}

但在每次编辑时都要不断地循环遍历行(通过 AM:AM 列,使用 If 公式创建“隐藏”和“取消隐藏”)。太烦人了,因为这些块有可编辑的区域。

希望电子表格读取起始触发器(参考编号)使用 vlookup 公式发挥它的魔力,一旦它更改单元格 F16 中的值,就会根据前提触发隐藏/取消隐藏行。然后就停在那里。

希望我说得通 帮助?想法?

【问题讨论】:

  • 也许您应该考虑在脚本中执行所有这些操作并完全消除单元格公式。然后您可以更好地控制所有各个部分

标签: google-apps-script google-sheets


【解决方案1】:

根据 F16 中的值隐藏行

Block1 = rows 16 to 27
Block2 = rows 28 to 39
Block3 = rows 40 to 51

if F16 = "A" - show block1, hide block2, hide block3
if F16 = "B" - hide block1, show block2, hide block3
if F16 = "C" - hide block1, hide block2, show block3

我使用了一个 switch 语句来简化逻辑并更容易看到正在发生的事情。我使用 getDataRange() 和 getValues() 来获取行数。获取额外数据并不会真正影响执行时间,因为这将由行的隐藏和显示决定。

function HideSelectedBlocks() 
{
  var ss=SpreadsheetApp.getActiveSpreadsheet();
  var sh=ss.getSheetByName("Contract");
  var rg=sh.getDataRange();
  var vA=rg.getValues();
  var F16=sh.getRange("F16").getValue();
  for(var i=0;i<vA.length;i++)
  {
    var row=i+1;
    switch(F16)
    {
      case 'A':
        if(row>=16 && row<=27){sh.showRows(row);}
        if(row>=28 && row<=39){sh.hideRows(row);}
        if(row>=40 && row<=51){sh.hideRows(row);}
        break;
      case 'B':
        if(row>=16 && row<=27){sh.hideRows(row);}
        if(row>=28 && row<=39){sh.showRows(row);}
        if(row>=40 && row<=51){sh.hideRows(row);}
        break;
      case 'C':
        if(row>=16 && row<=27){sh.hideRows(row);}
        if(row>=28 && row<=39){sh.hideRows(row);}
        if(row>=40 && row<=51){sh.showRows(row);}
        break;
      default:
    }
  }
}

执行大约需要 5 秒,在我的电子表格中获取值不到十分之一秒。

【讨论】:

  • 每次在可见块中进行更改/编辑时,它仍然会循环。有没有办法隔离脚本以仅在一个单元格中查找更改而忽略所有其他单元格中的任何更改?是“刷新”减慢了整个过程。否则,它会完全按照它的需要工作。
  • 你为什么不删除在列中隐藏和取消隐藏的 if 公式。
  • 您问“有没有办法隔离脚本以仅在一个单元格中查找更改而忽略所有其他单元格中的任何更改?”您的意思是在onEdit() 触发器中,还是您希望禁用单元格公式。在禁用该单元格公式的情况下,这是不可能的。
  • 有趣的是,谷歌文档说“UnhideRow”但它给出了一个错误...developers.google.com/apps-script/reference/spreadsheet/…... ShowRows 确实有效:) 谢谢你的回答
【解决方案2】:

我创建了一个脚本来隐藏所有具有过去日期的行。 我在一个名为“常规信息”的工作表中设置了最后一次执行脚本的日期,以避免不必要的执行并避免隐藏已经隐藏的行。 出于性能原因,我首先收集一组要隐藏的行中的第一行,然后在执行setupSheet.hideRows(beginRow, nbrOfRows);之前计算要隐藏的行数@

希望对你有帮助

function hideRows() {
    var ss = SpreadsheetApp.getActive();
    var setupSheet = ss.getSheetByName("sheetName");
    var lastDateOpened = ss.getSheetByName("General     
    Info").getRange("B9").getValue().valueOf();
    // remove timestamps.
    lastDateOpened =  parseInt(lastDateOpened/100000000)
    var today = parseInt(new Date().valueOf()/100000000)
    // execute once a day in onOpen()
    if (today == lastDateOpened){
    return;
    }
    var lastrow = setupSheet.getRange("L4").getValue();
    var beginRow = 0
    var nbrOfRows = 0
    var rowNum = 0
    var dates =  
    setupSheet.getRange("A2:A"+lastrow).getValues().valueOf(); 

    for(var i = 0; i <lastrow-1; i++){
    rowNum = i+2
    var date =new Date(dates[i]).valueOf()
    date = parseInt(datum/100000000)  
    var nbrVolNeeded = ss.getSheetByName("sheetName")
    .getRange("E"+rowNum).getValue(); 

    if (date < today && date >= lastDateOpened){ 
    // date must be in the past and later than last execution date
    if (beginRow == 0){
    beginRow = rowNum 
    }
    nbrOfRows = nbrOfRows + 1
    }
    else {  
    if ( nbrOfRows > 0){
    setupSheet.hideRows(beginRij,nbrOfRows);
    var beginRow = 0
    var nbrOfRows = 0
            }
            }
        }
    ss.getSheetByName("General Info").getRange("B9").setValue(new 
    Date())
}

【讨论】:

    【解决方案3】:

    在过去我想隐藏行的工作表中,我创建了三个列: 1 显示一行是否隐藏是或否: =IF(SUBTOTAL(103; AD2);"No";"Yes") (AD 列是带数字的列) 2 显示行号的列 =数组公式(行(AJ2:AJ)) 3 根据工作表中的数据显示是否应隐藏该列的列: =ARRAYFORMULA(IF(FLOOR(Z2:Z) FLOOR(TODAY());IF(AN2:AN="否";"是";"否");IF(E2:E=0;"是";"没有”)))

    对于特定的工作表,我创建了一个函数:

     `
     ` function HideToevoegen(){
       var ss = SpreadsheetApp.getActive();
       var setupSheet = ss.getSheetByName("Toevoegen activiteiten");
       var lastrow= setupSheet.getRange("L4").getValue();
       var allData =  setupSheet.getRange("AI2:AJ"+lastrow).getValues().valueOf();
       hideRows(setupSheet,lastrow,allData)
       }
    
    
    
       function hideRows(setupSheet,lastrow,allData) {
         var ss = SpreadsheetApp.getActive();
         var beginRij = 0
         var nbrOfRows = 0
         var rowNum = 0
         var filteredData = allData.filter(function (dataRow) {
         return dataRow[0] === 'Ja'
         });
           for(var i in filteredData){
               if ( nbrOfRows == 0){   
               beginRij  = filteredData[i][1]
               nbrOfRows = nbrOfRows = +1
               var nextRow = beginRij + 1
               }
              else if ( filteredData[i][1] == nextRow ){ 
                nbrOfRows = nbrOfRows +1
                nextRow = nextRow + 1
               }
              else {    
                 setupSheet.hideRows(beginRij,nbrOfRows);
                 var beginRij = filteredData[i][1]
                 var nbrOfRows = 1
                 nextRow = beginRij+1
                 }
               }
              // process last row
               if ( nbrOfRows > 0){
               setupSheet.hideRows(beginRij,nbrOfRows);
              }
            };
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-12-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-02
      • 2022-08-07
      相关资源
      最近更新 更多