2

是否可以获得围绕特定单元格的范围,类似于电子表格中的 Ctrl+A?

4

2 回答 2

7

我有许多电子表格,其中表格是由QUERY()函数创建的,因此边界很灵活。过去,我曾求助于设置命名范围,其大小是我预期的 QUERY 结果所需的最大尺寸,并将这些命名范围用于其他操作。

不再!

这是一个实用函数,getContiguousRange()它接受 A1 表示法中的单元格位置,并返回Range包含它的连续单元格的位置。此代码在 gist中可用。

/**
 * Return the contiguous Range that contains the given cell.
 *
 * @param {String} cellA1 Location of a cell, in A1 notation.
 * @param {Sheet} sheet   (Optional) sheet to examine. Defaults
 *                          to "active" sheet.
 *
 * @return {Range} A Spreadsheet service Range object.
 */
function getContiguousRange(cellA1,sheet) {
  // Check for parameters, handle defaults, throw error if required is missing
  if (arguments.length < 2) 
    sheet = SpreadsheetApp.getActiveSheet();
  if (arguments.length < 1)
    throw new Error("getContiguousRange(): missing required parameter.");

  // A "contiguous" range is a rectangular group of cells whose "edge" contains
  // cells with information, with all "past-edge" cells empty.
  // The range will be no larger than that given by "getDataRange()", so we can
  // use that range to limit our edge search.
  var fullRange = sheet.getDataRange();
  var data = fullRange.getValues();

  // The data array is 0-based, but spreadsheet rows & columns are 1-based.
  // We will make logic decisions based on rows & columns, and convert to
  // 0-based values to reference the data.
  var topLimit = fullRange.getRowIndex(); // always 1
  var leftLimit = fullRange.getColumnIndex(); // always 1
  var rightLimit = fullRange.getLastColumn();
  var bottomLimit = fullRange.getLastRow();

  // is there data in the target cell? If no, we're done.
  var contiguousRange = SpreadsheetApp.getActiveSheet().getRange(cellA1);
  var cellValue = contiguousRange.getValue();
  if (cellValue = "") return contiguousRange;

  // Define the limits of our starting dance floor
  var minRow = contiguousRange.getRow();
  var maxRow = minRow;
  var minCol = contiguousRange.getColumn();
  var maxCol = minCol;
  var chkCol, chkRow;  // For checking if the edge is clear

  // Now, expand our range in one direction at a time until we either reach
  // the Limits, or our next expansion would have no filled cells. Repeat
  // until no direction need expand.
  var expanding;
  do {
    expanding = false;
    // Move it to the left
    if (minCol > leftLimit) {
      chkCol = minCol - 1;
      for (var row = minRow; row <= maxRow; row++)  {
        if (data[row-1][chkCol-1] != "") {
          expanding = true;
          minCol = chkCol; // expand left 1 column
          break;
        }
      }
    }

    // Move it on up
    if (minRow > topLimit) {
      chkRow = minRow - 1;
      for (var col = minCol; col <= maxCol; col++)  {
        if (data[chkRow-1][col-1] != "") {
          expanding = true;
          minRow = chkRow; // expand up 1 row
          break;
        }
      }
    }

    // Move it to the right
    if (maxCol < rightLimit) {
      chkCol = maxCol + 1;
      for (var row = minRow; row <= maxRow; row++)  {
        if (data[row-1][chkCol-1] != "") {
          expanding = true;
          maxCol = chkCol; // expand right 1 column
          break;
        }
      }
    }

    // Then get on down
    if (maxRow < bottomLimit) {
      chkRow = maxRow + 1;
      for (var col = minCol; col <= maxCol; col++)  {
        if (data[chkRow-1][col-1] != "") {
          expanding = true;
          maxRow = chkRow; // expand down 1 row
          break;
        }
      }
    }

  } while (expanding);  // Lather, rinse, repeat

  // We've found the extent of our contiguous range - return a Range object.
  return sheet.getRange(minRow, minCol, (maxRow - minRow + 1), (maxCol - minCol + 1))
}

作为一个测试,考虑这个电子表格。它有两个连续的范围,都有参差不齐的边缘。 电子表格屏幕截图

这是我们的测试功能:

function testRanges() {
  var range1 = getContiguousRange("C3").getA1Notation();
  var range2 = getContiguousRange("B8").getA1Notation();
  debugger; // Pause if running in debugger
}

这就是我们得到的:

调试器结果

我希望这会有所帮助!

于 2013-03-05T04:45:11.727 回答
2

我在一个包含多张工作表的工作表中尝试了上述方法,由于缺乏声誉,我无法对此发表评论,发现如果更改行会更好: var contiguousRange = SpreadsheetApp.getActiveSheet().getRange(cellA1) ; 使用 var contiguousRange = sheet.getRange(cellA1);

于 2016-11-09T18:12:19.253 回答