Insert new sheet using sheet template is not working - google-apps-script

I have a sheet names in column A of the active sheet.
I am trying to get each new tab to be a duplicate of my Template tab, but they are just blank.
Here is the code:
/** #OnlyCurrentDoc */
function makeTabs(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var last = sheet.getLastRow();
for(var i = 1; i < last ; i++){
var tabName = sheet.getRange(i+1,1).getValue();
var templateSheet = ss.getSheetByName("Template");
var create = ss.insertSheet(tabName,{template: templateSheet});
}
}
Can anyone tell why created sheets are not based on template?

Solution:
Here is what you are looking for:
function copySheets() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheet = ss.getActiveSheet();
const last = sheet.getLastRow();
const template = ss.getSheetByName('Template');
const sh_names = sheet.getRange('A2:A'+last).getValues().flat([1]);
sh_names.forEach((name)=>{
const copy=template.copyTo(ss);
copy.setName(name);
})
}
Output:
Explanation:
I am using forEach() to iterate over the list of the names in column A of the active sheet. For each name, I am creating a copy of the template with this code:
const copy=template.copyTo(ss);
copy.setName(name);
Please keep in mind that you need to run this function when you have selected the active sheet (see my screenshot); the sheet that contains the name of the sheets you want to create. That is the reason I believe it is safer to get a sheet based on its name to be sure that you are getting the right input:
const sheet = ss.getSheetByName('Sheet1');
Obviously, you can't run this function more than once; it will output an error that sheets with these sheet names already exist.
Last but not least, all the duplicate sheets will have exactly the same content and format of Template sheet. I assume based on your question that this is your goal.

Related

Running App Script with output on a different Sheet

I have found a script that pulls data from a cell and adds a row to the bottom of the Google Sheet, but I want to be able to have the output on a separate sheet called "Data". Here is the script:
function recordValue() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Channels");
var date = new Date();
var value =sheet.getRange("B9").getValue();
sheet.appendRow([date,value])
}
I know I need to change the sheet.appendRow but I don't know what I need to get it to another sheet, say in cell A2.
You must declare the second sheet.
function recordValue() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Channels");
var dataSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Data");
var date = new Date();
var value = sheet.getRange("B9").getValue();
dataSheet.appendRow([date,value])
}
See:
The Modern JavaScript Tutorial
Outputting on a different sheet
function recordValue() {
const ss = SpreadsheetApp.getActive();
const sh = ss.getSheetByName("Channels");
const dsh = ss.getSheetByName("Data")
dsh.getRange(dsh.getLastRow() + 1, 1, 1,2),setValues([[new Date(),sh.getRange("B9").getValue()]]);
}
setValues

Set number of cells or rows/columns when generating Sheets in Google Sheets via script

I'm trying to generate sheets from a column in Google Sheets and it's working well. I am, however, running into an issue when too many tabs are generated. With this said, it would help if I can set up a Cell or Row/Colimn limit when genereting the new sheets.
I've tried creating a template sheet with just one cell, but it gets ignored.
The code I use now is:
function myFunction() {
const ss = SpreadsheetApp.getActive();
const sh1 = ss.getSheetByName('Sheet1');
const templateSheet = ss.getSheetByName('templateSheet');
const sh_names = sh1.getRange(1,1,sh1.getLastRow(),1).getValues().flat();
sh_names.forEach(n=>ss.insertSheet(n));
}
You can add this to your script to keep only 100 rows and 6 columns for instance
newSheet.deleteRows(100,900)
newSheet.deleteColumns(6,20)
so
function myFunction() {
const ss = SpreadsheetApp.getActive();
const sh1 = ss.getSheetByName('Sheet1');
const sh_names = sh1.getRange(1,1,sh1.getLastRow(),1).getValues().flat();
sh_names.forEach(function(n){
var newSheet = ss.insertSheet(n)
newSheet.setName(n)
newSheet.deleteRows(100,900)
newSheet.deleteColumns(6,20)
});
}

google sheets copy formatting from active sheet to every other sheet

I really need your help. After 2 days, I'm still on "ZERO".
I need a script that copies all the formats from an active sheet to every other sheet.
It would be nice to have the conditional formatting, alternating colors and data validation too.
I think it's not so hard, but I'm really new in script writing.
This is the sheet:
https://docs.google.com/spreadsheets/d/1mOkm_r4rngPXTkIerSQJKxRih31sM7XoZCZVnoHUc5M/edit?usp=sharing
The code so far:
enter function copyFormatting(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var copyTo = ss.getSheetByName('agent2');
var range = copyTo.getRange(1, 1, copyTo.getMaxColumns(), copyTo.getMaxRows());
sheet.getBandings()[0].copyTo(copyTo.getRange(1,1)),SpreadsheetApp.CopyPasteType.PASTE_FORMAT, false);
}
function allcopyFormatting() {
var spreadsheet = SpreadsheetApp.getActive();
var allSheets = spreadsheet.getSheets();
allSheets.forEach(function(sheet){
if(sheet.getSheetName() !== "detroit"){ // if you dont want to use the formatting on this sheet
sheet.activate();
copyFormatting(); // the function what yo like to run
}
})
}
I was able to figure out and write some functions: clear formatting on all sheets, format row headers on all sheets, show a list of sheets, but this one is too hard for me.
Even if I try to model it first with the macro recorder.
I would be very grateful, if you could help me with this issue.
I was able to figure it out:
function allcopyFormatting() {
var spreadsheet = SpreadsheetApp.getActive();
var allSheets = spreadsheet.getSheets();
var sampleSheet = spreadsheet.getActiveSheet(); // from the spreadsheet select the active sheet
var maxRow =sampleSheet.getMaxRows();
var maxCol =sampleSheet.getMaxColumns();
var sampleRange = sampleSheet.getRange(1,1,maxRow,maxCol);
allSheets.forEach(function(sheet){
if(sheet.getSheetName() !== "detroit"){ // if you dont want to use the formatting on this sheet
sheet.activate();
var targetSheet = spreadsheet.getActiveSheet(); // from the spreadsheet select the active sheet
var targetRange = targetSheet.getRange(1,1);
sampleRange.copyTo(targetRange, {formatOnly:true}) // it copies the formatting
}
})
}
Reference
Copy To
Try insertSheet(options) and if that doesn't work the try copyTo(destination, options)

Copy a range from last row to new sheet

I want to take the last response from a Google Form and copy it to the same range on another sheet.
The second sheet has some data in columns A & B (a login and password) that I want to assign as somebody completes the registration form.
I want the data from column B to H from the form response sheet to be copied to column C to I on the sheet that contains the login/password columns when a response is received.
I know I am missing the code to take the range from the last row, but I know NO coding at all and my current script is compiled from things I've found around the web and the reference material.
Any advice would be greatly appreciated.
function onEdit(e) {
var spreadsheet = SpreadsheetApp.openById("sheetid");
var sheet = spreadsheet.getSheets()[0];
var lastrow = sheet.getLastRow();
var range = sheet.getRange(2,2,1,7);
values = range.getValues();
var ss = SpreadsheetApp.getActiveSpreadsheet();
var SSsheet = ss.getSheets()[1];
var ssRange = SSsheet.getRange(2,3,1,7);
ssRange.setValues(values);
}
Try using copyTo(destination). It copies the data from a range of cells to another range of cells. Both the values and formatting are copied.
// The code below will copy the first 5 columns over to the 6th column.
var sheet = SpreadsheetApp.getActiveSheet();
var rangeToCopy = sheet.getRange(1, 1, sheet.getMaxRows(), 5);
rangeToCopy.copyTo(sheet.getRange(1, 6));
}
You can also try using copyValuesToRangecopyValuesToRange.
For additional code samples, you may also refer to this forum.
function onEdit(e) {
var spreadsheet = SpreadsheetApp.openById("ID");
var sheet = spreadsheet.getSheets()[0];
var lastRow = sheet.getLastRow();
var range = sheet.getRange("A"+(lastRow)+":G"+(lastRow));
var values = range.getValues();
var ss = SpreadsheetApp.getActiveSpreadsheet();
var SSsheet = ss.getSheets()[1];
var getRow = SSsheet.getLastRow() + 1;
var ssRange = SSsheet.getRange(getRow, 1, values.length, values[0].length);
ssRange.setValues(values);
Try with this,
this code copies the last value you want from a certain range and pastes it in the last available row of the other sheet.
The code it's the same only in the place where you are going to copy it, specify it to be the size of what I want to copy. I hope it helps you :D

How to get number of sheet from list

What script should do. First, get sheet names from range on sheet List_1. Then, using this array of names, put some data only on these sheets.
https://docs.google.com/spreadsheets/d/1Xdws6Vr6YVXuj19mvpOvkpJokOfY2T7Sh1aMpous_Xw/edit#gid=0
function VList() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheets = ss.getSheets();
var sheetNames = ss.getSheetByName("List_1");
var rangeNames = sheetNames.getRange("B3:B5").getValues();
for (var sheetId = 0; sheetId<sheets.length; sheetId++){
if(sheets[sheetId].getSheetName() == rangeNames) {
ss.getRange("C1").setValue("done");
}
}
}
Problem. When script starts - nothing happens. How to get number of sheet and vlookup only on them? Maybe, exist some function like "getSheetId" which can get number of sheet.
Solved, thanks to bruce.
function VList() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheets = ss.getSheets();
var sheetNames = ss.getSheetByName("List_1").getRange("B3:B5").getValues();
sheetNames.forEach(function(row) {
var sheet = ss.getSheetByName (row[0]);
if (!sheet) throw 'missing sheet ' + row[0];
sheet.getRange("c1").setValue ("done");
});
}
getValues() returns a two dimensional array, which you then compare with a string value - so that will never be true.
Once you fix that, you will still be updating the same cell, C1 with 'done' multiple times - ss points to the List_1 sheet - I assume you mean to update the sheet whose name is in the list.
Why not just use the list in b3:b5 to simply get each sheet by name and update it? There's no need to go through the sheets list since you already know their names.
something like
ss.getSheetByName("List_1").getRange("b3:b5").getValues()
.forEach(function(row) {
var sheet = ss.getSheetByName (row[0]);
if (!sheet) throw 'missing sheet ' + row[0];
sheet.getRange("c1").setValue ("done");
});