如何覆盖电子表格的全部范围?

时间:2014-06-28 18:34:11

标签: google-apps-script google-sheets

我是Google Scripting电子表格(Google Apps脚本编辑)的新手,也是 Java Javascript的新手。 我对Excel VBA非常有信心,现在正试图进行转换

我在Google表格中有一张小桌子。

我正在尝试创建一个脚本来覆盖整个表格范围。

我有以下内容,但我似乎无法让Logger显示表格的范围。请注意我是Google Apps脚本的新用户,因此如果有人确实提供了答案,您可以进行注释。

我想通过制作x = my function,然后当我想要获得范围时,我可以声明x。 (我认为这不像VBA那么直接。)

function CountColb(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
 var sheet = ss.getSheets()[0];
function CountColA(){
 //var ss = SpreadsheetApp.getActiveSpreadsheet();//goes to active spreadsheet
 //SpreadsheetApp.setActiveSheet(ss.getSheets()[0]);//goes to sheet tab 0 = first sheet, 1 = sheet 2
  var data = ss.getDataRange().getValues();
  for(var i = data.length-1 ; i >=0 ; i--){
    if (data[i][0] != null && data[i][0] != ''){
      return i+1 ;
    }
  }
}

  var x = function CountColA(){

 var range = sheet.getRange(1, 1, x, 3);
 values = range.getValues();
 Logger.log(values);


}
  }

1 个答案:

答案 0 :(得分:1)

首先,请记住Google Apps脚本是Javascript的变体,而不是Java。如果您开始使用Google Apps脚本,Javascript教程应该是您的第一站。 (例如Codecademy。)这将使您熟悉变量,函数,对象,方法,声明,scope - 您遇到的所有问题。

Google Apps脚本编辑器会在您保存代码时检查代码的语法。如果您有语法错误,则保存将失败。但是,在这段代码中,没有语法错误。但是,这在语义上是不正确的 - 代码并不意味着你的想法。

让我们以reformatting代码开始公开逻辑结构。看一下缩进 - 它提供了关于scope函数的线索。我已经注释了它以突出关键方面。

/**
 * CountColb is a function at global scope. You'll see its name in the debug 
 * controls of the editor (see Fig 1 below).
 */
function CountColb() {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = ss.getSheets()[0];    //** Always uses "Sheet 1"

  /**
   * CountColA is in the local scope of CountColb. It does not appear in the
   * debug controls, because the debugger can only invoke functions at global
   * scope. It's available only to other code in the same local scope - this
   * is great for encapsulation, if that is what you're after.
   */
  function CountColA() {
    /**
     * Since CountColA is in CountColb local scope, it has access to other
     * local scope variables - in this case ss and sheet. In terms of scope,
     * this is called "closure". Within CountColb local scope, there can be
     * only one "ss". If we declare it a second time here, within CountColA,
     * it will in fact use the same storage location as the version first
     * declared in CountColb.
     */
    //var ss = SpreadsheetApp.getActiveSpreadsheet();//goes to active spreadsheet
    //SpreadsheetApp.setActiveSheet(ss.getSheets()[0]);//goes to sheet tab 0 = first sheet, 1 = sheet 2

    /**
     * This statement gets all the populated cell values from the sheet
     * into an array of arrays. While spreadsheet rows and column number
     * from 1 to n, javascript arrays index from 0 to n-1.
     */
    var data = ss.getDataRange().getValues();

    /**
     * This is a down-counting for loop, properly set up. It will start
     * at the highest-numbered row, and work back to the first.
     */
    for (var i = data.length - 1; i >= 0; i--) {
      if (data[i][0] != null && data[i][0] != '') {
        /**
         * The first time we find that the first element in a row is neither
         * null nor a blank string, we will return the spreadsheet row number.
         * If the content of the spreadsheet remains constant, this function
         * will ALWAYS return the same result. (Is that what you want?)
         */
        return i + 1;
      }
    }
  }

  /**
   * Here is another variable, x, in CountColB local scope. The value of x
   * is being set to a function (we can do that in Javascript). Since we are
   * supplying the function keyword, a name 'CountColA', and a function body
   * enclosed in braces, this is an entirely new function. While it has the
   * same name that was previously used in CountColB local scope, that is not
   * a problem for the javascript interpreter because the function name here
   * is x, NOT CountColA.
   *
   * This does not invoke CountColA and assign the return value to x.
   */
  var x = function CountColA() {

    /**
     * Because of closure, the x in here is the same as the x out at
     * CountColB local scope. The statement below will throw an exception
     * (crash) because it is passing a function (this function) as the
     * third parameter to getRange, which expects a number.
     */
    var range = sheet.getRange(1, 1, x, 3);
    values = range.getValues();
    Logger.log(values);


  }
}

/**
 * We've reached the end of CountColB without any statements that
 * invoke CountColA or x, the two functions within CountColB.
 * As a result, CountColB does nothing.
 */

图1:调试控件中的CountColb
screenshot

工作示例

不清楚什么"覆盖整个表格"意味着,但我们假设其目的是计算包含值的所有单元格。这个功能可以做到:

/**
 * Counts all non-blank cells in sheet 1 of the spreadsheet.
 *
 * @return {number}      count of non-blank cells
 */
function countCells() {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = ss.getSheets()[0];    //** Always uses "Sheet 1"
  var data = ss.getDataRange().getValues();
  var result = 0;

  // For every row
  for (var row = (data.length - 1) ; row >=0 ; row--) {
    // ... and every column in that row
    for (var col = (data[0].length - 1) ; col >=0 ; col--) {
      // ... check for existence and content of a cell's contents
      if ((data[row][col] !== null) && (data[row][col] !== '')) {
        // ... and count it
        result++;
      }
    }
  }
  // Return the count of non-blank cells
  return result;
}