Why does the addRange function not work in Google Apps Script? - google-apps-script

I want to import a graphical evaluation (diagram) into a new file using a macro. So the evaluation should not be inserted on a new sheet in the associated file, but a completely new file should be created, in which the graphical evaluation (in the form of a combination diagram) is then copied. The file should be either a Google Sheets or an Excel file. The combination diagram already exists and is located in a Google sheet, but it should be copied into a new file automatically with the help of a macro and the corresponding button. The code below unfortunately only inserts an empty sheet. Where is my error?
The chart will depend on the data in the new Spreadsheet, so I need to have the data in the new spreadsheet using importrange. How can I modify the data range with addRange function. The code below unfortunately does not work. Like this an empty chart is inserted.
Error Exception: Service error: Tables (line 7, file "Macros") (insertChart Line)
function Auswertung2() {
var sheet = SpreadsheetApp.getActive().getSheetByName("Evaluation");
var newSpreadsheet = SpreadsheetApp.create("new spreadsheet");
var newSheet = newSpreadsheet.getSheets()[0];
var chart = sheet.getCharts()[0];
chart = chart.modify().addRange(sheet.getRange("A1:AX80")).setPosition(7, 7, 0, 0).build();
newSheet.insertChart(chart);
};```

Related

sheet.getFormUrl() not found

When creating a copy of a spreadsheet that is linked to a form, a newSheets.getFormUrl() not found error occurs. The new spreadsheet is created since I'm able to add a new editor to it and it appears in the appropriate drive folder. Likewise, the expected new form is created and it is indeed linked to the the new spreadsheet. However, when trying to get a handle on the new form via getFormUrl(), the error occurs. I want to rename the new form and move it to a new folder but can't.
Also, although Spreadsheet.getFormURL() exists in the API, it doesn't appear in the typeahead when keying in the function. My Apps Script runtime is V8.
// generate the response sheet into the folder and add editor
var newSheet = DriveApp.getFileById(templateResponseSheetID).makeCopy('Contact Tracing RESPONSES - ' + name, childDocsFolder);
newSheet.addEditor(email);
var newform = newSheet.getFormUrl();
The problem is that newSheet is a File object but getFormUrl() is a method of Class Spreadsheet
instead of
var newform = newSheet.getFormUrl();
use
var spreadsheet = SpreadsheetApp.open(newSheet);
var url = spreadsheet.getFormUrl()

Copy paste data to bottom last row on different worksheet with google sheet scrips

I'm trying to a script to work in which value from a specific range are pasted onto another sheet in a specific range. Problem is that not always the entire range of the input sheet is used and next time the function is used the data is pasted below the previously empty cells, see picture. Anybody any ideas?
function submitData2() {
var ss = SpreadsheetApp.getActiveSpreadsheet()
var database = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Data Logboek");
var source = ss.getSheetByName('Logboek Melding');
var dataToCopy = source.getRange('B2:J11');
var lastRow = database.getLastRow();
database.getRange('\'Logboek melding\'!B2:J11')
.copyTo(SpreadsheetApp.getActiveSpreadsheet()
.getSheetByName("Data Logboek").getRange(lastRow + 1,1)
,SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);
}
Considerations
Your copying process seems confused:
You are selecting a range in your database Sheet using A1 notation, but you are referencing another Sheet.
You already have the Data Logboek Sheet saved in the database variable, there is no need to get it again from the SpreadsheetApp.
If the copying direction is source -> database you should call toCopy on a source range not the other way around.
Solution
Using your variable declaration you can translate your copying process to this:
var dataToCopy = source.getRange('A1Notation'); // Source data to copy on database
dataToCopy.copyTo(
database.getRange(lastRow + 1, 1), // Destination
SpreadsheetApp.CopyPasteType.PASTE_VALUES, // Copy Paste Type
false // Transpose
);
Reference
copyTo()

Google Scripts: Trigger not working or script only runs once

I am new to Google Scripts so I have been struggling with this issue for some days now. Gone through multiple sources and none have the same issue as me.
I have set a time-based trigger for my script to import a CSV from my Gmail into a sheet. The emails sent are reports pulled daily from DV360 which are then used to populate a Data Studio Dashboard.
My first issue is that either the trigger isn't working properly (which may be unlikely) or that there is something wrong with my code. One weird thing which I have noticed is that the trigger works for one of the reports but does not work for the remaining 6.
I have multiple scripts in this project which all import different CSV attachments from different emails and each populate their own tab in a Google Sheets file.
Once I have run the script once and it has populated its respective sheet, it won't run again even if there is an email with a more recent attachment in my inbox (for example if I ran the script the following day, it won't populate the sheet with that specific day's report).
Below is the code I have used.
function importCSVFromGmail() {
var threads = GmailApp.search("Label:Audience_List");
var message = threads[0].getMessages().pop();
var attachment = message.getAttachments()[0];
if (attachment != null) {
var attachName = attachment.getName();
// Is the attachment a CSV file
if (attachName.substring(attachName.length-4) === ".csv") {
var id = "1cl5nZiJ2Jh__pMig-BoGTKpE9kM8-5nYe178WdI6ChI";
var name = "Audience_List_Backend";
var sheet = SpreadsheetApp.openById(id);
var tab = sheet.getSheetByName(name);
var tabInfo = sheet.getSheetByName("Audience_List_Backend");
tabInfo.getRange("A1").setValue(new Date());
// Clear the content of the sheet
tab.clearContents().clearFormats();
var csvData = Utilities.parseCsv(attachment.getDataAsString(), ",");
tab.getRange(1, 1, csvData.length, csvData[0].length).setValues(csvData);
}
}
}
Thank you in advance for any assistance!
The solution was simple.
Split each Script File out into its own project and trigger them individually using a time-based trigger.
Therefore the 7 actions I required each had their own project with a time-based trigger.

Changing the active range to a newly generated sheet causing error

Receiving the error,
ReferenceError: "setActiveSelection" is not defined.
Using Google Apps Script on Google Sheets. With this function, I'm wanting to create a new sheet tab on the same workbook using a template from another workbook. Once the new sheet is created, I'd like to change the actively selected cell to cell 'B1'. The template is copying fine, but the error is coming from the line changing the active selection. I've also tried setActiveRange and even just setActiveSheet but they return the same error.
function newReception() {
var templateSpreadsheet = SpreadsheetApp.openById("ID Redacted");
var template = templateSpreadsheet.getSheets()[1];
var currentSpreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var newSheet = template.copyTo(currentSpreadsheet).setName("Untitled
Reception");
setActiveSelection(currentSpreadsheet.getSheetbyName("Untitled
Reception").getRange('B1'));
}
Please advise on a solution. Thanks!
You're getting this issue because you're running .setActiveSelection() on its own. This method is bound to sheets, so you must run it for such. See Class Sheet documentation for more details on this method.
Try defining your sheet as a variable and then running it for your new sheet variable.
var sheet = currentSpreadsheet.getSheetbyName("Untitled Reception");
sheet.setActiveSelection('B1');

Programmatically delete a script

I was wondering if someone could offer me some advice.
I have a master spreadsheet, acting as a template. I have written a script which can be run from the menu (using addToUi command), which makes a copy of template spreadsheet.
The problem is that the script gets copied into the new spreadsheet also which I don't want.
Could anyone suggest a possible way around this please?
I did think a possible way was to get the script to open the copied template and delete the script but not sure if this is possible.
Here is the function which does the copying....
function createCopy() {
var myValue = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getRange("B8").getValue();
var destinationFolder = DriveApp.getFolderById("xxxxxxxxxxxxxxxx");
DriveApp.getFileById(SpreadsheetApp.getActiveSpreadsheet().getId()).makeCopy(myValue,destinationFolder);
}
(Cell reference B8 holds the value of what I called the copied spreadsheet).
Rayden, I use a function like that to just copy one sheet to a new spreadsheet and it doesn't drag the script with it. gDrive is the id for the Spreadsheet, tabName the individual sheet you want copied, Filename the name of the copy and destination the destination directory.
//******************************************************************************
//- This function takes a tab and makes it its own file
function tabToSheet(gDrive,tabName,fileName,destination){
var sh = SpreadsheetApp.openById(gDrive);
var ss = sh.getSheetByName(tabName);
//create a new document in the location given
var newSheet = SpreadsheetApp.create("TEMPDELETEME");
//copy the tab from current document to new document
ss.copyTo(newSheet);
var id = newSheet.getId();
newSheet.deleteSheet(newSheet.getSheetByName("Sheet1"));
os = newSheet.getSheets()[0];
os.setName(tabName);
var file = DriveApp.getFileById(id);
var folder = DriveApp.getFolderById(destination);
var finalId = file.makeCopy(fileName, folder).getId();
file.setTrashed(true);
return finalId;
}//*****************************************************************************
The difference is that i'm making a new sheet, then copying the tab rather than copying the entire file. You could add another tab and remove the variables if you want to copy multiple tabs.
I was having trouble implementing J.G.'s approach of moving individual sheets, so the approach I took was to add a conditional in front of the script to only run if the spreadsheet id was equal to the id of the original spreadsheet. My use case was trying to suppress a custom menu on the original workbook from reappearing on the copy, so it worked for that.
var bookId = spreadsheet.getId();
if (bookId === 'original spreadsheet id') {
*Function*
}