Google spreadsheets, Delete sheets from multiple spreadsheets - google-apps-script

I'm trying to delete one specific sheet from multiple google spreadsheets.
I have a master spreadsheet that collects data from all the other spreadsheets.
From the master spreadsheet I'm able to do different kind of actions in the other spreadsheets, like adding sheets, renaming sheets, hide and lock sheets.
But not been able to delete sheets in the other spreadsheets.
Looked in other threads but can´t find anything to solve it.
This is what I´ve got so far.
It stops at this row:
"fname.deleteSheet(thisweek);}"
function DeleteSheet() {
var sss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = sss.getActiveSheet();
var range = sheet.getRange("Z1:Z").getValues();
var filtered_r = range.filter(String).length;
var range = SpreadsheetApp.getActiveSheet().getRange('Z2:Z'+filtered_r);
var numRows = range.getNumRows();
var numCols = range.getNumColumns();
for (var i = 1; i <= numRows; i++) {
for (var j = 1; j <= numCols; j++) {
//Get current file ID in column Z
var currentValue = range.getCell(i,j).getValue();
var currentweekneedstobedefined = SpreadsheetApp.getActiveSheet().getRange(1, 3);
var thisweek = currentweekneedstobedefined.getValue();
ss = SpreadsheetApp.openById(currentValue);
var dsheet = ss.getSheetByName(thisweek);
file = ss
var fname = file.getName();
var thisweeksSheet = file.getSheetByName(thisweek);
if (dsheet != null) {
fname.deleteSheet(thisweek);}
else {
}
}
}
}
I appreciate any help on this since I'm a newbie in coding.

var fname = file.getName(); does not return you an instance of the spreadsheet, but only its name
To delete a sheet, you need the spreadsheet instance itself: ss
Retrieving the spreadsheet name is redundant
Solution:
Modify
ss = SpreadsheetApp.openById(currentValue);
var dsheet = ss.getSheetByName(thisweek);
file = ss
var fname = file.getName();
var thisweeksSheet = file.getSheetByName(thisweek);
if (dsheet != null) {
fname.deleteSheet(thisweek);}
to
ss = SpreadsheetApp.openById(currentValue);
var dsheet = ss.getSheetByName(thisweek);
if (dsheet != null) {
ss.deleteSheet(dsheet);
}

Related

Copy Specific Sheet from Drive Folder and Paste Data into Active Sheet

I have 10 to 15 Files in the Drive Folder All files have more than 1 Google sheets in it with some sort of Conditional Formatting.
I want to copy the Specific Sheet Named "MasterSheet" from each File and Combine the data into the Active Sheet where from script is bieng run.
Copied data should keep conditional formatting cell color. I will appreciate the help. Thanks
function myFunction()
{
var myFolder = DriveApp.getFolderById("FolderID");
var spreadSheets = myFolder.getFilesByType("application/vnd.google-apps.spreadsheet");
var ActiveSpreadSheet = SpreadsheetApp.getActive().getSheetByName(Sheet1);
while(spreadSheets.hasNext())
{
var sheet = spreadSheets.next();
var spreadSheet = SpreadsheetApp.openById(sheet.getId());
for(var y in spreadSheet.getSheets())
{
spreadSheet.getSheets()[y].copyTo(ActiveSpreadSheet);
}
}
}
UPDATE to check if there's a sheet called that way:
function copywithLog()
{
var destinsheet = SpreadsheetApp.getActiveSpreadsheet()
var myFolder = DriveApp.getFolderById("16CxTO70ipcUt8U_beokid3vFOOLGTnPh");
var spreadSheets = myFolder.getFilesByType("application/vnd.google-apps.spreadsheet");
var activeSpreadSheet = SpreadsheetApp.getActive().getSheetByName("Sheet1");
var i = 1
while(spreadSheets.hasNext())
{
var sheet = spreadSheets.next();
var spreadSheet = SpreadsheetApp.openById(sheet.getId());
var sheets = spreadSheet.getSheets()
var filtered = sheets.filter(n => ["DATA"].lastIndexOf(n.getSheetName()) == 0)
if (filtered.length==1){
var newsheet = spreadSheet.getSheetByName('DATA').copyTo(destinsheet)
newsheet.getDataRange().copyTo(activeSpreadSheet.getRange(activeSpreadSheet.getLastRow()+2,1))
destinsheet.deleteSheet(newsheet)
Logger.log("Process successfully finished with the workbook named '"+spreadSheet.getName()+"'")}
else Logger.log("The worbook named '"+spreadSheet.getName()+ "' does not have a sheet called DATA")
}
}
It returns something like this:
UPDATE:
function copyinsamesheet()
{
var destinsheet = SpreadsheetApp.getActiveSpreadsheet()
var myFolder = DriveApp.getFolderById("FolderID");
var spreadSheets = myFolder.getFilesByType("application/vnd.google-apps.spreadsheet");
var activeSpreadSheet = SpreadsheetApp.getActive().getSheetByName("Sheet1");
var i = 1
while(spreadSheets.hasNext())
{
var sheet = spreadSheets.next();
var spreadSheet = SpreadsheetApp.openById(sheet.getId());
var newsheet = spreadSheet.getSheetByName('MasterSheet').copyTo(destinsheet)
newsheet.getDataRange().copyTo(activeSpreadSheet.getRange(activeSpreadSheet.getLastRow()+2,1))
destinsheet.deleteSheet(newsheet)
}
}
If it has always the same name, you can try with this:
function copyMasterSheets()
{
var destinsheet = SpreadsheetApp.getActiveSpreadsheet()
var myFolder = DriveApp.getFolderById("FolderID");
var spreadSheets = myFolder.getFilesByType("application/vnd.google-apps.spreadsheet");
var ActiveSpreadSheet = SpreadsheetApp.getActive().getSheetByName(Sheet1);
var i = 1
while(spreadSheets.hasNext())
{
var sheet = spreadSheets.next();
var spreadSheet = SpreadsheetApp.openById(sheet.getId());
spreadSheet.getSheetByName('MasterSheet').copyTo(destinsheet).setName('MasterSheet '+i)
i++
}
}
An addendum to the answer by #Martin.
This takes the data on the various "Master Sheets" and copies it to a single sheet.
The range of data on each sheet is established dynamically, and is stacked down the page.
function copyMasters(){
var ss = SpreadsheetApp.getActiveSpreadsheet()
var target = ss.getSheetByName('Sheet1')
// idetify the starting row
var activeStartRow = 1
// get an array of all the sheets with names like "MasterSheet"
var sheetList = new Array
var sheets = ss.getSheets()
//var sourcesheet = ss.getSheets().find(sheet => sheet.getName().includes("MasterSheet"))
var mastersheets = sheets.filter(sheet => sheet.getName().includes("MasterSheet"))
//loop through the Master sheets
for (var i=0;i<mastersheets.length;i++){
var mastername = mastersheets[i].getName()
var master = ss.getSheetByName(mastername)
var masterLC = master.getLastColumn()
var masterLR = master.getLastRow()
// calculate the start row for the target sheet
if (activeStartRow==1){
var startRow =1
}else{
var startRow=startRow+masterLR
}
activeStartRow = 0
var rangeToCopy = master.getRange(1, 1, masterLR,masterLC)
//Logger.log("DEBUG: range to copy:"+rangeToCopy.getA1Notation())
var targetRange = target.getRange(startRow, 1, masterLR,masterLC)
//Logger.log("DEBUG: target range:"+targetRange.getA1Notation())
rangeToCopy.copyTo(targetRange)
// Logger.log("DEBUG: copied the data for "+mastername)
}
}
SAMPLE

Add the time when one google sheets document is modified to another sheets document

I have one sheet for a group of people. I'm trying to make a script so that whenever they edit the sheet, the time that they last edited will show up in a sheet in another document.
A sample row from the group sheet looks like this:
col1|...|col10|person name|...|col17
and the sheet that the time should be going to looks like this:
person name|col2|...|col10|date last edited.
this is the code that I've been trying and it is not working so far:
function onEdit(e) {
var row = e.range.getRow();
var col = e.range.getColumn();
var time = new Date().toLocaleString("en-US", {timeZone: "America/Toronto"})
var ID = "sheet ID"; //The ID for the second sheet goes here
var sheet = SpreadsheetApp.OpenById(ID);
var target = sheet.getSheetByName("Sheet2");
var lastColumn = target.getLastColumn();
var lastRow = target.getLastRow();
var range = target.getRange(1,1,lastRow, lastColumn);
var data = range.getValues();
var userEmail = e.user.getEmail();
var array = userEmail.split(".");
var firstName = array[0];
var secondSheet = e.source.getActiveSheet();
var lastRowSecond = secondSheet.getLastRow();
var lastColumnSecond = secondSheet.getLastColumn();
var secondRange = secondSheet.getRange(1,1,lastRowSecond, lastColumnSecond);
var secondData = secondRange.getValues();
var nameRow = secondData[row-1];
var nameColumn = nameRow[10];
var secondPersonarray = nameColumn.split(" ");
var secondPersonFirstName = secondPersonarray[0];
for (var i=1; i<lastRow; i++) {
var sheetRow = data[i];
var name = sheetRow[0].split(" ");
var firstNameSheet = name[0];
if ((firstName == firstNameSheet) && (firstName == secondPersonFirstName)) {
target.getRange(sheetRow, 10).setValue(time);
}
}
}
I've done something similar, only with one document, so I know the problem isn't with the time.

How to make this script run faster?

Hello so I am trying to get values from the 'book' sheet then copy it to 'Completed' sheet. It takes the values form book stores it in the data array and copy them to the 'Completed' sheet. Its working fine but very slow which jeopardizes my work in time-wise. How can I make this run faster ?
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var clear_sheet = spreadsheet.getSheetByName('Completed_Orders'); // clear the destination sheet first
clear_sheet.getRange('A2:X').clear();
var sheet = spreadsheet.getSheetByName('book'); //source sheet
var Datarange = sheet.getRange('Q3:Q'); //range to check
var Datavalue = (Datarange.getValues());
var dest = spreadsheet.getSheetByName('Completed_Orders'); //destination sheet
var data = [];
for (i=0; i<Datavalue.length;i++) {
if ( Datavalue[i] == "Completed") {
data.push.apply(data,sheet.getRange(i+3,1,1,24).getValues());
}
}
dest.getRange(2,1,data.length,data[0].length).setValues(data);
var column = dest.getRange('A3:A');
var values = column.getValues(); // get all data in one call
var ct = 0;
while ( values[ct][0] != "" ) { // to find the last row correctly, getLastRow is not working perfectly
ct++;
}
var endRow = ct+2;
}
Try this:
Don't use this syntax var values=sheet.getRange('A3:A').getValues() because it get's the data all the way down to getMaxRows(). Instead use var values=sheet.getRange(3,1,sheet.getLastRow()-2,1).getValues().
Also Datavalue[i] is a whole row
function myfunction() {
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var clear_sheet = spreadsheet.getSheetByName('Completed_Orders');
clear_sheet.getRange(2,1,clear_sheet.getLastRow()-1,24).clear();
var sheet = spreadsheet.getSheetByName('book'); //source sheet
var Datarange = sheet.getRange(3,17,sheet.getLastRow()-2,1); //range to check
var Datavalue = Datarange.getValues();
var dest = spreadsheet.getSheetByName('Completed_Orders'); //destination sheet
var data = [];
for (var i=0;i<Datavalue.length;i++) {
if (Datavalue[i]["************You need another index here**************"] == "Completed") { //need another index Datavalue is 2d
data.push(sheet.getRange(i+3,1,1,24).getValues());
}
}
dest.getRange(2,1,data.length,data[0].length).setValues(data);
}
I think this version will be a lot faster.
function myfunction() {
var ss=SpreadsheetApp.getActiveSpreadsheet();
var ssh=ss.getSheetByName('book');
var dsh=ss.getSheetByName('Completed_Orders');
dsh.getRange(2,1,dsh.getLastRow()-1,24).clear();
var dv=ssh.getRange(3,1,ssh.getLastRow()-2,24).getValues();//this version just gets this data one time so it should a lot faster.
var data=[];
for (var i=0;i<dv.length;i++) {
if (dv[i][16]=="Completed") {
data.push(dv[i]);
}
}
dsh.getRange(2,1,data.length,data[0].length).setValues(data);
}

Google App Script - getCommenter

I'm brand new to Google Apps Script, and I'm trying to create a simple spreadsheet that will allow me to share files by user email through a single spreadsheet.
I have written the following script, which will allow me to add editors and viewers, but not commenters.
I keep getting an error that states that the function addCommenter cannot be found in object spreadsheet.
function shareSheet () {
var ss = SpreadsheetApp.getActiveSpreadsheet();
ss.toast('Updating access level...');
var sheet = ss.getSheets()[0];
var lastRow = sheet.getLastRow();
var range1 = sheet.getRange (3,1, lastRow,9);
var data = range1.getValues();
for (var i= 0; i < data.length; i++) {
var row = data [i];
var accessLevel = row [5];
var values = row [8];
var ss2 = SpreadsheetApp.openById(values);
var values2 = row [4];
// Add new editor
if (accessLevel == 'Edit') {
var addEditors = ss2.addEditor(values2);
}
// Add new viewer
if (accessLevel == 'View'){
var addViewers = ss2.addViewer(values2);
}
// Add new commenter
if (accessLevel == 'Comment') {
var addCommenters = ss2.addCommenter(values2);
}
}
}
The Spreadsheet object does not support the addCommentor() method. You should use DriveApp service instead.
DriveApp.getFileById(id).addCommenter(emailAddress)

Method is heavily used by the script

I am very new on using Google Apps Script and has a shallow knowledge on programming. What I am trying to do is copy the values of specific columns to a different Spreadsheet. Here's my code:
function myFunction() {
var ss = SpreadsheetApp.getActive();
var responses = ss.getSheetByName("Responses ID");//Where ID's of the spreadsheets are listed.
var consolidatedSheet = ss.getSheetByName("Consolidated");//Where the data should be pasted.
var responseColValues = responses.getRange(2,2, responses.getMaxRows() -1).getValues();
var responsesIds = [i for each (i in responseColValues)if (isNaN(i))];
var ssSelected = SpreadsheetApp.openById(responsesIds[0]);
var selectedSheets = ssSelected.getSheets();
for (i=0; i<3; i++){
var maxRows = selectedSheets[i].getLastRow()-1;
var x=2, y=2;
var lastRow = consolidatedSheet.getLastRow()+1;
for (j=0; j<maxRows; j++){
var eventID = selectedSheets[i].getRange(y,2).getValue();
var employeeName = selectedSheets[i].getRange(y,3).getValue();
var productionDate = selectedSheets[i].getRange(y,4).getValue();
var consolidatedSheetCell = consolidatedSheet.getRange(lastRow,1).setValue(eventID);
var consolidatedSheetCell = consolidatedSheet.getRange(lastRow,2).setValue(employeeName);
var consolidatedSheetCell = consolidatedSheet.getRange(lastRow,3).setValue(productionDate);
y++;
lastRow++;
}
}
}
However, I am experiencing this notification on the Execution hints (light bulb icon):
screenshot of the message. I am thinking that my code can be simplified. I am just not sure how to do it. Thank you in advance.
Every line with .getRange().getValue() and getRange.setValue() is a call to the file. Since you have these inside a for(){} loop, they are being called many times. Your goal is to limit these to as few as possible. Since you can read and write a range, you could do something similar to this:
function myFunction() {
var ss = SpreadsheetApp.getActive();
var responses = ss.getSheetByName("Responses ID");//Where ID's of the spreadsheets are listed.
var consolidatedSheet = ss.getSheetByName("Consolidated");//Where the data should be pasted.
var responseColValues = responses.getRange(2,2, responses.getMaxRows() -1).getValues();
var responsesIds = [i for each (i in responseColValues)if (isNaN(i))];
var ssSelected = SpreadsheetApp.openById(responsesIds[0]);
var selectedSheets = ssSelected.getSheets();
for (i=0; i<3; i++){
var maxRows = selectedSheets[i].getLastRow()-1;
var y=2;
var lastRow = consolidatedSheet.getLastRow()+1;
var copyValues = selectedSheets[i].getRange(y,2, maxRows, 4).getValues();
consolidatedSheet.getRange(lastRow,1, maxRows, 4).setValues(copyValues);
}
}