'google is not defined' in custom spreadsheet function - google-apps-script

I am trying to write a very basic custom function for my google docs spreadsheet. I have a column in the spreadsheet that lists every day of the year. It's a simple function that should scroll to 'today' in the date column.
However, when I try to run the query, I get an error "google is not defined".
function gotoToday() {
var now = new Date();
var now = Utilities.formatDate(now, "EST", "M/d/yyyy");
var file = SpreadsheetApp.getActiveSpreadsheet();
var sheet = file.getActiveSheet();
var query = new google.visualization.Query(sheet);
query.setQuery('select A WHERE A= '&now);
query.send(handleQueryResponse);
function handleQueryResponse(response) {
Browser.msgBox(response);
var row = day+4;
file.setActiveCell(sheet.getRange(row,1));
}
};
It's dying at the new google.visualization.Query line, saying gooogle isn't defined.
Shouldn't I get those objects for free? Since it is being run in Google Docs, I can't load the jsapi via a script tag. I thought it should just be there. All the other code samples use this same method and the docs don't say anything about other scripts needing to be loaded.
Any ideas would be appreciated!
Thanks,
D

In addition to standard Javascript objects, APIs for many of google's offerings are provided as Services. You don't need to load other scripts to access the Script Services.
The visualization library is represented in Google Apps Script via the Charts Service. The GMail Stats tutorial is one of several that introduces use of the service.
All the other code samples use this same method...
Client-side Javascript samples can do that. No Google Apps Script example does.

Related

Unexpected value of Google PageSpeed insights API when used with Google Sheets

I'm using the PageSpeed API to pull data using Google Script into Google Sheets.
However, when I execute the script and fetch data from the PageSpeed URL, the time-to-first-byte numeric value is substantially higher than when I run it in my regular browser window.
For example, when I fetch the URL within Google Sheets with the code below, my average Time-to-first-byte is 500-510ms. While if I use the exact same URL in chrome on my desktop, it's generally 60-70ms.
This is the code I use to pull in the data:
function callPageSpeed(strategy) {
var pageSpeedUrl = 'https://www.googleapis.com/pagespeedonline/v5/runPagespeed?url=' + pageSpeedMonitorUrl + '&key=' + pageSpeedApiKey + '&strategy=' + strategy;
var response = UrlFetchApp.fetch(pageSpeedUrl);
var json = response.getContentText();
return JSON.parse(json);}
I then push it into my sheet using:
function monitor() {
var desktop = callPageSpeed('desktop');
var mobile = callPageSpeed('mobile');
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var sheet = spreadsheet.getSheetByName('results');
sheet.appendRow([
Utilities.formatDate(new Date(), 'GMT+1', 'yyyy-MM-dd'),
desktop['lighthouseResult']['audits']['time-to-first-byte']['numericValue'].toFixed(0) + " ms"
//some other metrics go here
]);
Does anybody know what might cause this, and how I can overcome it?
The difference in the time average between your direct Browser execution call and the one in your Apps Script execution is due to Apps Script code runs in Google's servers and not in your local machine as the Docs say:
There's nothing to install—we give you a code editor right in your
browser, and your scripts run on Google's servers.
Take that into consideration when calling external APIs because it can have other side effects, besides time average differences like having an IP address that you can't assign.

Interacting with activeSheet, activeCell in a stand-alone script

I created a google sheet that stores info row by row that I send out in different emails as templates. I'd like to give a copy of the file to my colleagues, but I'm figuring out it's probably better from a version-control standpoint to deploy the script as an add-on so they can install it individually, yet I retain centralized control of the code. However, my code uses a decent amount of ActiveSpreadsheet() and ActiveSheet() and activeCell() functions that apparently only container-bound scripts can use.
Anyone have any recommendations as to how to replace the following lines in a stand-alone script? Also any commentary on my idea to change my script to a stand-alone script to deploy as an add-on would be appreciated!
var sheet = SpreadsheetApp.getActiveSheet();
var scriptRow = sheet.getActiveCell().getRow();
var tst1 = SpreadsheetApp.getActiveSpreadsheet().toast('Draft create failed');
Try this instead of the above code:
var sheet = SpreadsheetApp.openById("your-spreadsheet-id").getSheetByName("your-table-name");
var scriptRow = sheet.getActiveCell().getRow();
var tst1 = sheet.toast('Draft create failed');
It's hard to say if an add-on would be good. Depends on the exact work the script is doing: You can either publish it as Add-on, Web app or API.

How do I convert this google script to work offline?

I am trying to automate data entry while roaming offline using my Chromebook.
I know that google drive is enabled offline and a standalone script in GAS should in theory do the trick but im not sure how to put the pieces together. So far I have the below code which works perfectly online (gets stuck in "running" offline) and I've got the GAS app installed. Any guidance would be greatly appreciated!
function onOpen() {
var ui = SpreadsheetApp.getUi();
// Or DocumentApp or FormApp.
ui.createMenu('Invoice/Receipt System')
// creates a menu item "Submit Order"
.addItem('Record Invoice', 'menuItem1')
.addToUi();
}
function menuItem1() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var is = ss.getSpreadsheetByName("Template_Invoice");
var lastID = is.getRange("j6");
var nextID = is.getRange("j7");
var lastIDValue = lastID.getValue();
var source = ss.getSpreadsheetByName("Key_Invoice");
// sets the 'Key_DailyInput' Sheet as source
var target = ss.geSpreadsheetByName("DataBase_Invoice");
// sets 'Key_DailyInput' sheet as the target for copying data to.
var sourceData = source.getSheetValues(5,1,source.getLastRow(),15);
// sets range to gather source 'Key_DailyInput' data by finding last row, and Line 5 to Column 15
target.getRange(target.getLastRow()+1, 1, sourceData.length,15).setValues(sourceData);
// finds last row of target 'Orders' and writes to +1 row past last row up to column 15 using setValues of sourceData
// Following simply clears DailyInput so new data can be entered
is.getRange('C5:c8').clearContent();
is.getRange('G7:G8').clearContent();
is.getRange('B12:h28').clearContent();
is.getRange('b31:b34').clearContent();
// increases value by +1 so next Sales Order ID is incremented by 1
var cell = is.getRange("j6");
var cellValue = cell.getValue();
cell.setValue(cellValue + 1);
nextID.setValue(lastIDValue + 1);
}
As stated in other responses, the answer appears to be 'No'. However, while researching I did find the Command Line Interface for Apps Script (clasp) to manage and edit your projects offline. I'll post it here hoping it will be helpful to Apps Script developers.
CLASP Features
Develop Locally. clasp lets you write code on your own computer and upload it to Apps Script via command line when you're done. You can also download existing Apps Script projects and then edit them locally. Once the code is local, you can use your favorite development tools like git to work on Apps Script projects.
* Manage Deployment Versions.
* Create, update, and view multiple deployments of your project.
* Structure Code. clasp automatically converts your flat project on script.google.com into folders.
You can find more information on clasp at https://developers.google.com/apps-script/guides/clasp. However, you'll also need to activate the Linux(beta) on your Chromebook utilizing these instructions.
Short answer
Google Apps Script can't be ran offline because they run on the server-side.
Explanation
From https://developers.google.com/apps-script/overview
Google Apps Script is a scripting language based on JavaScript that
lets you do new and cool things with Google Apps like Docs, Sheets,
and Forms. There's nothing to install — we give you a code editor
right in your browser, and your scripts run on Google's servers.

Using Google Scripts to upload without intervention

I have used the below to upload files from my local drive by choosing a file from the UI. I would like to upload a particular file with a static pathway every day. Is there a way to have a script upload a particular file? (Then I could just use triggers to make sure it happened routinely).
function doGet(e) {
var app = UiApp.createApplication().setTitle("Upload CSV to Sheet");
var formContent = app.createVerticalPanel();
formContent.add(app.createFileUpload().setName('thefile'));
formContent.add(app.createSubmitButton());
var form = app.createFormPanel();
form.add(formContent);
app.add(form);
return app;
}
function doPost(e) {
// data returned is a blob for FileUpload widget
var fileBlob = e.parameter.thefile;
var doc = DocsList.createFile(fileBlob);
}'
No, that is not possible (using Apps Script). Apps Script runs on Google servers and therefore do not have access to your local files.
I wrote an article for Steegle a while ago where I explain such Apps Script's aspects. You might want to give it a quick read.
You have to write such program using "traditional" development tools. That is, programs that run in your computer. For example, a Java program using Google Drive API library could do this easily. Then you could schedule it using your OS's scheduling feature (e.g. cron on linux/unix).

How to access data on different Google Spreadsheet through Google Apps Script?

I'm writing a Google Apps Script on my Google Site and am trying to use data that is provides on 2 different tabs in a Google Spreadsheet. From what I thought I understood from the documentation I could use all available methods in the SpreadsheetApp class on a Sites script by just using the openById() method.
Anyway here is what I tried to do
function doGet(e) {
var doc = SpreadsheetApp.openById(SPREADSHEET_ID_GOES_HERE).getActiveSheet();
SpreadsheetApp.setActiveSheet(doc.getSheetId()[1]);
//....
}
I get the error
Cannot find method setActiveSheet(. (line 4)
I'm pulling my work off this link: Storing Data in Google Spreadsheets and also the Ui Service section listed under Building User Interfaces.
Anybody seeing what I'm doing wrong in these two lines?
setActiveSheet should be used only with the spreadsheet displayed by the UI, a sheet in a spreadsheet you have opened in your browser.
With SpreadsheetApp.openById you are opening a spreadsheet to access its data, but it doesn't open in your browser. It hasn't an UI.
I found this comments in https://developers.google.com/apps-script/class_spreadsheetapp?hl=es-ES#openById :
// The code below opens a spreadsheet using it's ID and gets the name for it.
// Note that the spreadsheet is NOT physically opened on the client side.
// It is opened on the server only (for modification by the script).
var ss = SpreadsheetApp.openById("abc1234567");
Some examples assume your script is running into your spreadsheet. It's not your case, because you are running a script as a service, which should have its own User Interface.
I think #megabyte1024 addresses the syntax errors, but in answer to your comment to #YoArgentina:
Do you happen to know of a way to access data on different tabs then
through a service not running inside the Spreadsheet?
Does this sort of help?
var ss = SpreadsheetApp.openById(SPREADSHEET_ID_GOES_HERE);
var sheets = ss.getSheets();
// the variable sheets is an array of Sheet objects
var sheet1A1 = sheets[0].getRange('A1').getValue();
var sheet2A1 = sheets[1].getRange('A1').getValue();
You need to access each sheet separately.
var ss = SpreadsheetApp.openById(SPREADSHEET_ID_GOES_HERE);
var sheet = ss.getSheets()[0]; // "access data on different tabs"
ss.setActiveSheet(sheet);
There is at least one problem in these two lines. The 1st one is that the setActiveSheet method parameters is a Sheet class object and the getSheetId method returns an integer value. By the way this method (getSheetId) is not documented. The 2nd problem can happen if the SpreadsheetApp has no active spreadsheet. In this case there is the "Please select an active spreadsheet first." error. Use the SpreadsheetApp.setActiveSpreadsheet method to set an active spreadsheet.