google-apps-script - 在电子表格的 App 脚本中选择连续范围

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

最佳答案

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

不再!

这是一个实用函数 getContiguousRange(),它接受 A1 表示法中的单元格位置,并返回包含它的连续单元格的 Range。此代码可用 in a 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
}

这就是我们得到的:

希望对您有所帮助!

https://stackoverflow.com/questions/15187688/

相关文章:

solr - 从 DocsAndPositionsEnum 检索所有术语位置

sql - 如何将日期时间字段添加到 + 1 天

unix - 输出 shell 脚本到日志文件

bash - 如何从 Bash 中的域获取主 MX IP

performance - 如何减少此 Google Apps 脚本的执行时间?

sql - "column ambiguously defined"

vbscript - SystemUtil.Run 在 vb 脚本中不起作用

php - 通知 : unserialize() for symfony2 ( connection

java - 如何在其他计算机上运行java可执行文件

string - 一组字符串的 R 直方图和描述性统计数据