Google 表格脚本 - “无法读取未定义的属性”(如果不是)

Google Sheets script - "Cannot read property of undefined" (when it's not)

本文关键字:属性 如果不 未定义 读取 脚本 表格 Google      更新时间:2023-09-26

我正在尝试解构Google团队的脚本,用于从AdWords获取报告并将其写入Google Sheets电子表格。我正在应用程序编辑器中对其进行测试,并得到"无法读取未定义的..."错误。

我目前在我的项目中有两个 .gs 文件:

1. 函数定义("类"),empty_row.gs文件:

function SpreadsheetAccess(spreadsheetUrl, sheetName) {
this.spreadsheet = SpreadsheetApp.openByUrl(spreadsheetUrl);
this.sheet = spreadsheet.getSheetByName(sheetName);
this.findEmptyRow = function(minRow, column) {
    var values = this.sheet.getRange(minRow, column, this.sheet.getMaxRows(), 1).getValues();
    for (var i = 0; i < values.length; i++) {
        if(!values[i][0]) {
            return i + minRow;
        }
    }
    return -1;
    };
this.addRows = function(howMany){
    this.sheet.insertRowsAfter(this.sheet.getMaxRows(), howMany);
};
this.writeRows = function(){
    this.sheet.getRange(startRow, startColumn, rows.length, rows[0].length).setValue(rows);
};
}

2. 以及我实例化对象的main.gs文件:

var spreadsheetUrl = 'https://docs.google.com/spreadsheets/d/someurl/edit#gid=1540200210';
var sheetName = 'baba';
function main() {
  var object = SpreadsheetAccess(spreadsheetUrl, sheetName);
  var emptyRow = object.findEmptyRow(1, 1);
  Logger.log("The empty row is: %s", emptyRow);  
}

当我运行main{}时,我得到这个:

类型错误: 无法调用未定义的方法 "findEmptyRow"。(第 6 行,文件"主")

为什么我的对象未定义?我已经定义了:

  • 电子表格网址
  • 工作表名称
  • 我已将这些传递给我的函数调用
  • 最后在同一个项目中定义函数,单独的文件

什么给?谢谢!

您不应该尝试使用 this 来修改您不拥有的对象。AFAIK this实际上是指包含Apps Script本身的所有服务代码的对象。

创建自己的对象并传递这些对象,而不是使用全局范围更改对象,虽然从技术上讲,将所有内容填充到该对象中并引用它,但不鼓励这样做。

我的推理不正确。不过,我发布的问题仍然存在。

问题:

object未定义,因为您没有从 SpreadsheetAccess() 返回值。没有任何东西被定义,因为没有任何东西被返回。

解决方案 1

下面是包含两个更改的代码。更新电子表格访问功能,并将spreadsheet.getSheetByName(sheetName);更改为this.spreadsheet.getSheetByName(sheetName);

var spreadsheetUrl = 'https://docs.google.com/spreadsheets/d/someurl/edit#gid=1540200210';
var sheetName = 'baba';
function main() {
  var object = new SpreadsheetAccess(spreadsheetUrl, sheetName);
  var emptyRow = object.findEmptyRow(1, 1);
  Logger.log("The empty row is: %s", emptyRow);  
}
function SpreadsheetAccess(spreadsheetUrl, sheetName) {
  this.spreadsheet = SpreadsheetApp.openByUrl(spreadsheetUrl);
  this.sheet = this.spreadsheet.getSheetByName(sheetName);
  this.findEmptyRow = function(minRow, column) {
    var values = this.sheet.getRange(minRow, column, this.sheet.getMaxRows(), 1).getValues();
    for (var i = 0; i < values.length; i++) {
      if(!values[i][0]) {
        return i + minRow;
      }
    }
    return -1;
  };
  this.addRows = function(howMany){
    this.sheet.insertRowsAfter(this.sheet.getMaxRows(), howMany);
  };
  this.writeRows = function(){
    this.sheet.getRange(startRow, startColumn, rows.length, rows[0].length).setValue(rows);
  };
}

解决方案 2这是我修改后的代码,这段代码有效,我已经用我自己的电子表格测试过它:

var spreadsheetUrl = 'https://docs.google.com/spreadsheets/d/someurl/edit#gid=1540200210';
var sheetName = 'baba';
function main() {
  var myObject = SpreadsheetAccess(spreadsheetUrl, sheetName);
  var emptyRow = myObject.findEmptyRow(1, 1);
  Logger.log("The empty row is: %s", emptyRow);  
}
function SpreadsheetAccess(spreadsheetUrl, sheetName) {
  var myObject = {};
  myObject.spreadsheet = SpreadsheetApp.openByUrl(spreadsheetUrl);
  myObject.sheet = myObject.spreadsheet.getSheetByName(sheetName); 
  myObject.findEmptyRow = function(minRow, column) {
    var values = myObject.sheet.getRange(minRow, column, myObject.sheet.getMaxRows(), 1).getValues();
    for (var i = 0; i < values.length; i++) {
      if(!values[i][0]) {
        return i + minRow;
      }
    }
    return -1;
  };
  myObject.addRows = function(howMany){
    myObject.sheet.insertRowsAfter(myObject.sheet.getMaxRows(), howMany);
  };
  myObject.writeRows = function(startRow, startColumn, rows){
    myObject.sheet.getRange(startRow, startColumn, rows.length, rows[0].length).setValue(rows);
  };
  return myObject;
}