如何使用脚本确定某个列是否隐藏在Google电子表格中?

时间:2013-05-29 16:32:08

标签: google-apps-script google-sheets

我正在尝试为Google电子表格编写一个函数,用于查找组的第一列和最后一列。然后隐藏该组,或者如果它已经被隐藏则显示该组。

但是,我无法找到确定列是否隐藏的方法。我无法在Google的“课程表”页面https://developers.google.com/apps-script/reference/spreadsheet/sheet上找到任何内容,而且我找不到与Excel相同的内容.hidden

getColumnWidth(column)返回未隐藏的列宽,即使它被隐藏。

这是我的代码:

function hideShowColumns(startCol, endCol) { 
  //endCol is one column past the last data set that should be hidden
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Transposed Data");
  //import the data from the Column Headers
  var colHeaderData = sheet.getRange(1, 1, 2, sheet.getMaxColumns()).getValues(); 
  var startColNum = 0;
  var endColNum = 0;

  // This section searches for the column names in the header rows and returns their column number
  for (var i =0; i < 2; ++i) {
    for (var j = 0; j < colHeaderData[0].length; ++j) {
      if (colHeaderData[i][j] == startCol) 
        startColNum = j;
      if (colHeaderData[i][j] == endCol) 
        endColNum = j;
    }
  }

  //This is the wrong command getColumnWidth doesn't change if column is hidden
  if (sheet.getColumnWidth(startColNum + 1) != 0) {
    sheet.hideColumns(startColNum + 2, endColNum - startColNum - 1);
    Logger.log(sheet.getColumnWidth(startColNum + 2));
    return;
  }

  //This is the wrong command getColumnWidth doesn't change if column is hidden
  if (sheet.getColumnWidth(startColNum + 1) == 0) { 
    for (var j = startColNum + 1; j < endColNum - 1; ++j) {
      sheet.unhideColumn(j);
      Logger.log(sheet.getColumnWidth(startColNum + 2));     
    }
    return;
  }
}

感谢您的帮助!

5 个答案:

答案 0 :(得分:6)

不幸的是,没有Google Apps脚本方法会返回是否隐藏列或行。作为一种方式,你可能想为它打开的问题加注星标。接收有关该问题的更新,以及b。 “签署请愿书”,可以这么说。

https://code.google.com/p/google-apps-script-issues/issues/detail?id=195&q=hidden%20column&colspec=Stars%20Opened%20ID%20Type%20Status%20Summary%20Component%20Owner

答案 1 :(得分:2)

解决方法。创建2行。第一个必须始终具有值,第二个具有一组公式。这两行看起来像这样:

  |           A             |           B             |            C            |
---------------------------------------------------------------------------------
1 |                       1 |                       1 |                       1 |
2 | =NOT(SUBTOTAL(103, A1)) | =NOT(SUBTOTAL(103, B1)) | =NOT(SUBTOTAL(103, C1)) |

SUBTOTAL使用指定的聚合函数返回小计。第一个参数103定义了用于聚合的函数类型。第二个参数是应用函数的范围。

  • 3表示COUNTA并计算范围
  • 中的值的数量
  • +100表示​​忽略范围内的隐藏单元格。

隐藏单元格时,范围为1单元格的SUBTOTAL的结果为0,显示单元格时为1。 NOT反转它。

现在,您可以使用脚本读取第二行,以了解列是否已隐藏。

以下是转置的问题和答案:https://stackoverflow.com/a/27846202/1385429

答案 2 :(得分:2)

抱歉,我也找不到方法,偶然发现这个堆栈溢出。 但我不妨在某个地方分享这个剧本。

我使用第一列作为 - 或||的占位符告诉它是隐藏还是显示的价值。 (不是最好的,但我可以找到它的全部)

        <?php header("Content-type: application/javascript"); session_start(); include('../../db.connect.php');
        $js_time = strtotime('-30 minutes', time());
        $sqlonline = mysql_query("SELECT twitchid FROM users_hash WHERE timestamp >= '".strtotime('-30 min')."'") or die(mysql_error());

            if(mysql_num_rows($sqlonline) > '0'){
                while($rowonline = mysql_fetch_row($sqlonline)){

                $sqlonuser = mysql_query("SELECT id,avatar,username FROM users WHERE twitchid = '".$rowonline[0]."'") or die(mysql_error());
                $rowonuser = mysql_fetch_row($sqlonuser); ?>    

        (function ($) {     

        jQuery("body").append("<div id='_strike-<?php echo $rowonuser[2]; ?>'></div>");

        jQuery('#_strike-<?php echo $rowonuser[2]; ?>').hover(function() {
            isinsitememb = true;
        },function() {
            if(timerb) {
                clearTimeout(timerb);
                timerb = null;
            }
            isinsitememb = false;
            timerb = setTimeout(function() {
                if(isinsitememb == true)return false;
                jQuery("#_strike-<?php echo $rowonuser[2]; ?>").removeClass("active");
                jQuery("#_strike-<?php echo $rowonuser[2]; ?>").html("");
            }, 500);
        });

        jQuery('.<?php echo $rowonuser[2]; ?>-tooltip').hover(function() {
            if(timerb) {
                clearTimeout(timerb);
                timerb = null;
            }
            var offset = jQuery(this).offset();
            var position = jQuery(window).scrollTop();
            var karsejmeitene = offset.top-position;
            if(karsejmeitene <= 200){
                jQuery("#_strike-<?php echo $rowonuser[2]; ?>").addClass("upsidedown");
            }else{
                jQuery("#_strike-<?php echo $rowonuser[2]; ?>").removeClass("upsidedown");
            }
            jQuery("#_strike-<?php echo $rowonuser[2]; ?>").html('<a href="#" class="username" style="background:#232323;color:#fff;"><?php echo $rowonuser[2]; ?></a><a href="#" class="avatar online"><span class="wrapimg" style="display:inline-block;position:relative;border-radius:inherit;-moz-border-radius:inherit;overflow:hidden;"><img src="images/photos/avatar-11.jpg" alt="" /></span></a><div class="info"><div>"The one who digs a hole, has a shovel"</div><div><font>Group:</font><span class="admin-ribbon">main admin</span></div><div><font>Now:</font>Reading topic "<a href="#"><b>Do you wanna be a billionaire ?</b></a>"</div></div><div class="clear-float"></div><div class="bottom"><a href="#" class="com-control"><i class="fa fa-envelope"></i>Private message</a><a href="#" class="com-control"><i class="fa fa-file-text-o"></i>View profile</a></div>');
            jQuery("#_strike-<?php echo $rowonuser[2]; ?>").css("left", offset.left+"px").css("top", offset.top+"px");
            var wii = (parseInt(jQuery(this).css("width"))/2);
            var wiiii = ((parseInt(jQuery("#_strike-<?php echo $rowonuser[2]; ?>").css("width"))+parseInt(jQuery("#_strike-<?php echo $rowonuser[2]; ?>").css("padding-right"))+parseInt(jQuery("#_strike-<?php echo $rowonuser[2]; ?>").css("padding-left")))/2);
            timerb = setTimeout(function() {
                jQuery("#_strike-<?php echo $rowonuser[2]; ?>").css("margin-left", ((wiiii-wii)*(-1))+"px");
                jQuery("#_strike-<?php echo $rowonuser[2]; ?>").addClass("active");
            }, 500);
        },function() {
            if(timerb) {
                clearTimeout(timerb);
                timerb = null;
            }
            timerb = setTimeout(function() {
                if(isinsitememb == true)return false;
                jQuery("#_strike-<?php echo $rowonuser[2]; ?>").removeClass("active");
                jQuery("#_strike-<?php echo $rowonuser[2]; ?>").html("");
            }, 500);
        }); 
    });

<?php       }
        }
?>

请点击此处查看更新:https://gist.github.com/LiamKarlMitchell/81cef19a530261c4af93

答案 3 :(得分:1)

截至2018年,Google尚未向Sheets API添加行/列可见性方法。现在,2018年末,他们为此创建了一个API。

那很难过,但我发现了另一种方式:

当一行是最后一行可见时,您无法隐藏它(与列相同)。 Google Spreadsheet会抛出错误并向您显示一条消息。因此,当脚本函数隐藏除我们要检查的行之外的每一行时,如果它失败,则我们的行被隐藏。如果运行成功,则表示我们的行可见。

请注意,这种解决方法太难以在性能敏感的脚本中使用。

用法示例:

var sheet = SpreadsheetApp.getActive().getActiveSheet()
// Is the tenth row hidden?
isRowHidden(sheet.getRange('B10')) 

// Is column B hidden?
isColumnHidden(sheet.getRange('B10'))

// Is cell B10 visible? (not in a hidden row and/or column)
!(isCellHidden(sheet.getRange('B10')))

代码

/**
 * Takes the first row of a range and checks whether is hidden or not.
 * Second parameter is an optional sheet. Defaults to the active sheet.
 * @param {range} row
 * @param {sheet} [sheet]
 * @returns {boolean} True if row is hidden, false if it is visible.
 */
function isRowHidden (row, optionalSheet) {
  var ss = SpreadsheetApp.getActive()
  var sheet = optionalSheet || ss.getActiveSheet()
  SpreadsheetApp.setActiveSheet(sheet)
  var dup = ss.duplicateActiveSheet()
  SpreadsheetApp.setActiveSheet(sheet)
  var isHidden = false
  var rowIndex = row.getRow()
  var numRows = dup.getMaxRows()

  if (numRows === 1) {
    ss.deleteSheet(dup)
    return false
  }

  try {
    if (rowIndex === numRows ) {
      dup.hideRows(1, numRows - 1)
    } else if (rowIndex === 1) {
      dup.hideRows(rowIndex + 1, numRows - 1)
    } else {
      dup.hideRows(1, rowIndex - 1)
      dup.hideRows(rowIndex + 1, numRows - rowIndex)
    }
    isHidden = false
  } catch (e) {
    isHidden = true    
  } finally {
    ss.deleteSheet(dup)
  }

  return isHidden
}

/**
 * Takes the first column of a range and checks whether is hidden or not.
 * Second parameter is an optional sheet. Defaults to the active sheet.
 * @param {range} column
 * @param {sheet} [sheet]
 * @returns {boolean} True if column is hidden, false if it is visible.
 */
function isColumnHidden (col, optionalSheet) {
  var ss = SpreadsheetApp.getActive()
  var sheet = optionalSheet || ss.getActiveSheet()
  SpreadsheetApp.setActiveSheet(sheet)
  var dup = ss.duplicateActiveSheet()
  SpreadsheetApp.setActiveSheet(sheet)
  var isHidden = false
  var colIndex = col.getColumn()
  var numCols = dup.getMaxColumns()

  if (numCols === 1) {
    ss.deleteSheet(dup)
    return false
  }

  try {
    if (colIndex === numCols ) {
      dup.hideColumns(1, numCols - 1)
    } else if (colIndex === 1) {
      dup.hideColumns(colIndex + 1, numCols - 1)
    } else {
      dup.hideColumns(1, colIndex - 1)
      dup.hideColumns(colIndex + 1, numCols - colIndex)
    }
    isHidden = false
  } catch (e) {
    isHidden = true    
  } finally {
    ss.deleteSheet(dup)
  }

  return isHidden
}

/**
 * Takes the first cell of a range and checks whether is hidden or not.
 * Second parameter is an optional sheet. Defaults to the active sheet.
 * @param {range} cell
 * @param {sheet} [sheet]
 * @returns {boolean} True if cell is hidden, false if it is visible.
 */
function isCellHidden (cell, optionalSheet) {
  var isHidden = isColumnHidden(cell, optionalSheet) || isRowHidden(cell, optionalSheet)
  return isHidden
}

PS:代码遵循JS标准风格。

JavaScript Style Guide

答案 4 :(得分:1)

为此(自2018年起)新的api是:isColumnHiddenByUser(columnPosition)

返回给定的列是否被用户隐藏。

var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheets()[0];

// Columns start at 1
Logger.log(sheet.isColumnHiddenByUser(1));