谷歌应用程序脚本 - 根据单元格值隐藏/取消隐藏行

时间:2017-11-01 01:08:26

标签: google-apps-script google-sheets

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

有问题的电子表格为我们的供应商创建合同,特定单元格值(在我的情况下为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中的值,则根据前提触发隐藏/取消隐藏行。然后就在那里停下来。

希望我有意义 救命?想法?

3 个答案:

答案 0 :(得分: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秒,不到十分之一秒才能获得电子表格中的值。

答案 1 :(得分:0)

我创建了一个脚本来隐藏过去有日期的所有行。 我在名为“常规信息”的工作表中设置了脚本的最后执行日期,以避免不必要的执行并避免隐藏已经隐藏的行。 出于性能原因,我首先收集要隐藏的一行行中的第一行,并在执行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())
}

答案 2 :(得分:0)

在过去要隐藏行的工作表中,我创建了三个列: 显示行是否被隐藏的1(是或否): = IF(SUBTOTAL(103; AD2);“否”;“是”)(列AD是带有数字的列) 2一列显示行号 = arrayformula(ROW(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);
          }
        };