2016-04-26 11 views
0

Ich versuche, eine Google-Team's script zu demontieren, um einen Bericht aus AdWords zu erhalten und in die Google Tabellenkalkulation zu schreiben. Ich teste es im Apps-Editor und bekomme den Fehler "Kann nicht von undefinierten ... lesen".Google Sheets-Skript - "Eigenschaft von undefined nicht lesen" (wenn nicht)

Ich habe derzeit zwei .gs Dateien in meinem Projekt:

1. Funktionsdefinition ("class"), empty_row.gs Datei:

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. und eine main.gs Datei, wo ich instanziieren Sie das Objekt:

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); 
} 

Wenn ich laufe main{} Ich erhalte diese:

TypeError: Cannot call method "findEmptyRow" of undefined. (line 6, file "main")

Warum ist mein Objekt nicht definiert? Ich habe definiert:

  • die spreadsheetUrl
  • Sheetname
  • ich diese meine Funktionsaufruf bestanden haben
  • und schließlich die Funktion im selben Projekt definiert, separate Datei

Was gibt? Vielen Dank!

Antwort

1

Sie sollten nicht versuchen, Objekte, die Sie nicht besitzen, mit this zu ändern. Vor allem in Google Apps Script. AFAIK this bezieht sich tatsächlich auf das Objekt, das den gesamten Dienstcode für Apps Script selbst enthält.

Erstellen Sie Ihre eigenen Objekte und übergeben Sie diese, anstatt das Objekt mit globalem Bereich zu ändern, während es technisch funktioniert, alles in dieses Objekt zu stopfen und darauf Bezug zu nehmen, es wird abgeraten.

Ich war falsch in meiner Argumentation. Das Problem, das ich gepostet habe, steht trotzdem.

Das Problem:

object ist nicht definiert, weil Sie nicht einen Wert von SpreadsheetAccess() zurück. Nichts wurde definiert, da nichts zurückgegeben wurde.

Lösung 1

Hier ist der Code mit zwei Änderungen.Newing bis die SpreadsheetAccess Funktion und das Ändern spreadsheet.getSheetByName(sheetName); zu 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); 
    }; 
} 

Lösung 2 Hier ist meine modifizierten Code, dieser Code funktioniert, Getestet habe ich es schon mit meiner eigenen Tabelle:

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; 
} 
+0

Ich sehe Was hast du da gemacht? - Du hast die 'function SpreadsheetAccess()' -Definition (die "Klasse") so verändert, dass darin ein neues Objekt (line: 'var myObject = {};') erstellt wird, anstatt in ' function main() {}; 'wie ich es versucht habe. AFAIK, sollte nicht das gleiche Ergebnis mit 'var myObject = new SpreadsheetAccess()' in der 'function main() {};'? Das heißt, dass mein ursprünglicher Fehler die Zeile war: 'var object = SpreadsheetAccess (Tabellenblatt),' was sein sollte: 'var object = ** new ** SpreadsheetAccess (Tabellenblatt, Blattname)' –

+0

Ah! Ich sehe was du meinst, ich war in einigen meiner Argumentationen falsch, da ich Apps Script immer als ziemlich fragile Kreatur behandelt habe. Sie können Instanzen eines Objekts definitiv neu erstellen. Ich werde meinen Beitrag korrigieren, um das ebenfalls zu berücksichtigen. Sie haben auch einen Syntaxfehler, indem Sie Spreadsheet in Tabelle 3 Ihres ersten Code-Snippets aufrufen. –

+0

Verstehen Sie es jetzt vollständig! VIELEN Dank, dass du dir die Zeit genommen hast, "mir beizubringen, wie man fischt" anstatt mir den Fisch zu geben;). Noch eine Sache: in 'for() {}' innerhalb von 'function SpreadsheetAccess() {}' Warum geben sie -1 zurück? Warum nicht 0 oder 1? –

Verwandte Themen