issue with console log for google apps scripts - google-apps-script

I'm trying to troubleshoot the below code (the main problem is that I can't get the range to display) and I've included a log command to show what is being printed out. When I run doGet() and go to View > Logs it says: "[16-10-07 17:31:19:145 EDT] number for you: Range"
sheet.getRange("H1:DE1") refers to part of a row that has dates. Shouldn't it list the contents of the row?
function doGet() {
// The code below opens a spreadsheet using its id and logs 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.openByUrl('https://docs.google.com/spreadsheets/d/1aCXXXXXXXXXXXXw61H6VuigRf6YykW8O6A0WWmG46VO7ijI/edit#gid=1673918325');
Logger.log(ss.getName());
var sheet = ss.getSheets()[1];
var range = sheet.getRange("H1:DE1");
Logger.log('number for you: %s', range);
// Calling this method with "true" sets the first line to be the title of the axes
var datatable = range.getDataTable(true);
// Note that this doesn't build an EmbeddedChart, so we can't just use
// Sheet#insertChart(). If we want to do that, we should use
// sheet.newChart().addRange() instead.
var chart = Charts.newBarChart()
.setDataTable(datatable)
.setOption("title", "Your Title Here")
.build();
var app = UiApp.createApplication();
app.add(chart);
ss.show(app);
}
Can anyone advise?

You can't to print the range object in this way. Instead you have to write range.getRow() or range.getColumn(). Please note you have various get functions of the range object.

The range object does not contain sheet values. In order to get them use either of the following:
values = range.getValues(); // gets internal values
values = range.getDisplayValues(); // gets displayed values
The best approach to fix errors in an apps script is to use the built in debugger (not the Logger object, not the execution transcript) and breakpoints, like this:
At the script editors top bar, find the dropdown menu and select a function you want to debug
Set a breakpoint: click the index of a line you would like to pause at (assume to be buggy)
Click the bug icon in the top bar to run the script in debug mode up to the specified breakpoint
Inspect your variables in the opened tab
Step through the lines of your script line by line by clicking the step in, step out, and step over buttons (at the right of the script editors top bar)

Related

Gapps Script in Google Sheet Is Not Scrolling No Matter What I Do

I am having troubles make Gapps Script scroll the window.
Basically, I want to send the user to the first non blank row from the buttom. My sheet has around 24000 rows. The first non blank row from the bottom is on 23500 row.
I'm using this script but not matter how many time I flush, nothing happens.
I am correctly getting the address of the lastFilledRow... It's just the sheet which never scrolls.
My code is:
function go_to_last_row() {
var ss = SpreadsheetApp.openById('abc.....')
var sheet = ss.getSheetByName('All Leads')
var lastRow = sheet.getMaxRows()
Logger.log(lastRow)
sheet.getRange('A'+lastRow).activate()
SpreadsheetApp.flush()
var lastFilledRow = sheet.getActiveCell().getNextDataCell(SpreadsheetApp.Direction.UP).activate().getA1Notation()
SpreadsheetApp.flush()
Utilities.sleep(3000)
sheet.setActiveRange(sheet.getRange(lastFilledRow)).setValue('hello')
SpreadsheetApp.flush()
Logger.log(lastFilledRow)
Logger.log('done')
}
Any ideas how to force the window to actually scroll? I even set the value "hello" correctly, but still, the cursor never goes to that cell....
Use SpreadsheetApp.getActive(). For some reason, SpreadsheetApp.openById() doesn't provide the same privileged context that container-bound scripts afford. This is actually documented by Google, but in a relatively cryptic way
Functions that are run in the context of a spreadsheet can get a reference to the corresponding Spreadsheet object by calling this function.
As a result of your question, I now interpret that to mean that the other open methods (those that don't include "Active") will not give you that reference to the corresponding Spreadsheet.
This is an abridged version of your code. Works with getActive(), but not openById().
function go_to_last_row() {
var ss = SpreadsheetApp.getActive();
var sheet = ss.getSheetByName('All Leads');
var lastRow = sheet.getMaxRows();
sheet.getRange('A'+lastRow).activate();
}

Google Scripts " e.changeType=='INSERT_ROW' " functionality - Reading when a new row is inserted

I'm trying to get my Google sheet to perform certain functions only when a new row is added. After some research I found the .changeType function which seems to work, but I'm having trouble then getting more functions to run based on that condition.
As you can see in my code, I'm using the .changeType function within an if statement.
The if statement appears to work, and it works up until the ui alert - which also works. However, none of the code below it does.
The weird part is that the same code works if I take it outside of the if function.
I'm having a lot of trouble debugging this as the Google Scripts debug tool thinks if(e.changeType=='INSERT_ROW') is an incorrect line of code, but I don't feel it is as it does actually run correctly in the Google sheet. I think this is something to do with the on change trigger functionality.
Perhaps it's the rest of my code that's incorrect, but I can't understand why it works when it's not within that if statement.
What I'm trying to do is to get the row that's just been added, by getting the active range of cells. Then, find the range of cells from immediately below that cell right to the last populated cell in the whole sheet. Those cells should then move with the .moveTo function.
Can anyone explain what's going wrong here? it's been impossible to debug so far!
Code is below:
function moveUpRows(e)
{
var sheet = SpreadsheetApp.getActiveSheet();
var ui = SpreadsheetApp.getUi();
if(e.changeType=='INSERT_ROW')
{
ui.alert("new row added!");
var range = sheet.getActiveRange();
var belowActiveRange = range.offset(1, 0);
var rangeMovingUp = sheet.getRange("L"+belowActiveRange.getRow()+":S"+sheet.getLastRow())
rangeMovingUp.moveTo(rangeMovingUp.offset(-1, 0));
}
}
If you insert a new row - this will lead to an undefined active range notation
In fact, Logger.log(range.getA1Notation()); will log #REF!
You can work around this limitation by defining:
...
var range = sheet.getActiveRange();
var row = range.getLastRow();
var belowActiveRange = sheet.getRange(row+1, 1, 1, sheet.getLastColumn());
...

Google Script Function - Copy Paste

I was writing a script through Google Script about the function of a button when clicked. What I want to happen is SHEET 1 Values gets copied to SHEET 2 AS VALUES (Not copying the Google Sheets Formulas), then SHEET 1 VALUES will get cleared. However, it seems I'm having an issue with the values getting copied to SHEET 2.
I tried to search for something that could resolve this, but I'm not really that an expert when it comes to writing scripts since I'm a newbie to this.
// Display a dialog box with a message and "Yes" and "No" buttons.
var ui = SpreadsheetApp.getUi();
var response = ui.alert("Do you want to capture all data?", ui.ButtonSet.YES_NO);
// Process the user's response.
if (response == ui.Button.YES) {
}
function remove() {
var spreadsheet = SpreadsheetApp.getActive().getSheetByName("2019")
var destsheet = SpreadsheetApp.getActive().getSheetByName("Handled Tickets");
var getLastContentRow = spreadsheet.getRange("A8:I").getValues();
var destination = destsheet.getRange(destsheet.getLastRow()+1,1);
var source = spreadsheet.getRange("A8:I").getValues();
getLastContentRow.copyTo(destination.CopyPastType.PASTE_VALUES);
spreadsheet.getRange('C8:E').clearContent()
spreadsheet.getRange('F8:H').clearContent()
}
Expected Flow: 1) When the button has been clicked, whatever data in spreadsheet will be copied to destsheet. 2) Once copied, data in spreadsheet will be cleared.
Additional rules: 1) Once copied to destsheet, data will not be overwritten by other values when the button is clicked again. Instead, it will look for the last row (empty cell) and copy the data there. 2) If all cells have been used, automatically there will be additional 100 rows added.
Error:
Cannot find function copyTo in object
There are several issues with your code above (syntax, format, structure, missing semicolons to finish statements,...).
Assuming only the remove() function was being a problem, here is my version below with several comments.
You may also want to review the part with the UI above (e.g. embed it in a function that your button will call, make sure there is some code in your if statement,...).
function remove() {
var source_sheet = SpreadsheetApp.getActive().getSheetByName("2019"); // better not use "spreadsheet" as variable name here, this is confusing, your content is a sheet
var dest_sheet = SpreadsheetApp.getActive().getSheetByName("Handled Tickets");
var getLastContentRow = source_sheet.getRange("A8:I"); // The "copyTo" method applies to ranges, not to arrays, so remove the ".getValues()"
// --> the "getLastRow" variable name makes me believe you're only looking at copying the last row, but your current range will copy all rows starting at 8.
// --> as the same content is captured in "source" below, this might just be a misleading variable name, though, in which case you may want to simply rename it
var destination = dest_sheet.getRange(dest_sheet.getLastRow()+1,1);
// var source = spreadsheet.getRange("A8:I").getValues();
// --> this is duplicate with getLastContentRow, and not use in your function, so presumed useless. Can be removed.
getLastContentRow.copyTo(destination, SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);
// --> the example in the documentation is misleading, but this function requires a third argument for "transposed"
// spreadsheet.getRange('C8:E').clearContent()
// spreadsheet.getRange('F8:H').clearContent()
// --> why two different calls instead of 1 on C8:H directly?
// --> also, why not the same range as the one copied?
getLastContentRow.clearContent(); // This will remove all the copied content from the "source_sheet"
}

Get the row/col of a clicked drawing?

I assign to a cell in each row a png icon and a script with
sheet.insertImage(blob, 11, i).assignScript("ClickMe");
At the end of the process I have a few hundred rows with buttons at the end. What I'm struggling to do at the moment is work out which row gets clicked on. I've tried a few likely candidates like
var ss = SpreadsheetApp.getActiveSheet();
var sheetName = ss.getSheetName();
var activeRange = ss.getActiveRange();
var selection = ss.getSelection();
var ar = activeRange.getA1Notation();
var cc = ss.getCurrentCell().getA1Notation();
var scr = selection.getCurrentCell().getA1Notation();
var ac = ss.getActiveCell().getA1Notation();
Logger.log("scr=%s, ar=%s, cc=%s, ac=%s", scr, ar, cc, ac);
but having clicked on the 9th line, the Logger.log says
[19-06-20 22:39:01:123 HKT] scr=A1, ar=A1, cc=A1, ac=A1
So the question is this: if someone clicks on the button on the 21st line, can the script figure out what line the click occurred on?
The other answer is that you need to make 21 helper functions,
what I imagine you have now (> binding script)
Button1 > script
Button2 > script
Button3 > script
Button4 > script
function script(){
//Do something
}
Instead you need
Button1 > scriptOne
Button2 > scriptTwo
Button3 > scriptThree
Button4 > scriptFour
with carrier functions:
function scriptOne (){script(1);}
function scriptTwo (){script(2);}
function scriptThree (){script(3);}
function scriptFour(){script(4);}
and then you have that info in the script function
function script(input){
var row = input;
//Do something
}
This does get tedious, and isn't exactly easy to generate in bulk, but if you have a fixed sheet, that might work.
You can also consider making the button a checkbox, and then making your script be "onEdit" and checking for which row the change occurred in. But the way you are currently thinking won't work because there is no way to bind the scripts passing a variable from the button itself. The script will see all of your current buttons as the exact same thing.
It’s not possible to achieve exactly what you want in your code. This is because when you use the functions “getActiveRange” and “getSelection” [1], it returns the cell or cells that are being selected (have the focus on it). When you click in the inserted image, you’re not clicking the cell but only the image, so the focus is still in the first cell.
To obtain the cell where the image is anchored you can use the following snippet:
var image = sheet.insertImage(blob, 11, i).assignScript("ClickMe");
image.getAnchorCell().getA1Notation());
The problem is that you can’t pass any parameters in the assignScript function (like the cell position in this case), only the name of the function to run [2].
A possible workaround is to adjust the size of the cell to contain the complete image. Once this is done, request to your users that they must first click in the cell and then in the image:
var image = sheet.insertImage(blob, 11, i).setHeight(20).setWidth(20).assignScript("ClickMe");
[1] https://developers.google.com/apps-script/reference/spreadsheet/range
[2] https://developers.google.com/apps-script/reference/spreadsheet/over-grid-image

google app script map tutorial change

Trying to use: https://developers.google.com/apps-script/articles/maps_tutorial?hl=en I receive the map correctly. However, I would like for the map to remain on one tab. The bottom of the code reads:
SpreadsheetApp.getActiveSpreadsheet().show(ui);
And I think I should change it to
SpreadsheetApp.getActiveSpreadsheet().getSheetByName('restaurants').show(ui);
so that the map remains on one tab. But it gives me an error message. What can I do?
You are getting an error message because there is no .show() method for the Sheet Class. The ui is attached to a Spreadsheet, not a Sheet. (Comparing to Excel, Spreadsheet == Workbook, Sheet == Worksheet aka tab.)
If you want to ensure that the sheet (tab) containing the map is visible, use Sheet.activate().
var ss = SpreadsheetApp.getActiveSpreadsheet();
var mapSheet = ss.getSheetByName("Map"); // Assuming sheet is named Map
mapSheet.activate(); // Bring Map to front
ss.show(ui); // Open UI
You have to name the tab of the spreadsheet as 'restaurants', not the spreadsheet.