Google Script to Create Tab Names Based on List - javascript

I am very new to Google Apps Scripts, but am working to create a spreadsheet function that will create new tabs based a list of names (in cells C6:C). Some of the cells may not have values in them, so would like to exclude these cells from creating new tabs.
The function works as planned, but after running the script, the new tabs are named with a (1), (2), (3),... etc. after the name that is in the list. For example if the first name in the list is "First Tab", the new tab gets named "First Tab (1)" after my current script is run.
I'm not sure as to what would be causing the numbers in the tab names, so any help would be greatly appreciated!
For reference, Cell B4 contains a count of the number of names in the List that the new Tabs should be created from
'''
function createProjectTabs() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheets()[0];
var range = ss.getRange("C6:C");
var values = range.getValues().filter(String);
var total = ss.getRange('B4').getValue();
for(var k=0; k < total; k++){
try{
var tabName = range[k][0];
ss.insertSheet(tabName);}
catch(err){
tabName = values [k][0]+ " " + k;
ss.insertSheet(tabName);}
}
}

function createNonDuplicateProjectTabs() {
var ss = SpreadsheetApp.getActive();
const shts = ss.getSheets().map(s => s.getName());
var sh = ss.getSheets()[0];
var vs = ss.getRange(6,3,sh.getLastRow()-5,1).getValues().flat();
vs.forEach(n => {
if(!~shts.indexOf(n)) {
ss.insertSheet(n)
}
});
}

Related

Push links generated to Google SpreadSheet in JS (Google AppScripts)

I am using a script to automate form generation.
It basically loops over a list of elements, since each of them should have a different forms link.
How can I store the links generated corresponding to each group in a google spreadsheet?
I would like to have a spreadsheet in this way:
Group Link
138 https://docs.google.com/forms/idForm138
139 https://docs.google.com/forms/idForm139
Here's my code:
var lista_url=[]
var group=[137, 138, 139]
function createForm(group) {
// create & name Form
var item = "Speaker Information Form";
var form = FormApp.create(item)
.setTitle(item);
// single line text field
item = group;
form.addTextItem()
.setTitle(item)
.setRequired(true);
// multi-line "text area"
item = "Short biography (4-6 sentences)";
form.addParagraphTextItem()
.setTitle(item)
.setRequired(true);
// radiobuttons
item = "Handout format";
var choices = ["1-Pager", "Stapled", "Soft copy (PDF)", "none"];
form.addMultipleChoiceItem()
.setTitle(item)
.setChoiceValues(choices)
.setRequired(true);
// (multiple choice) checkboxes
item = "Microphone preference (if any)";
choices = ["wireless/lapel", "handheld", "podium/stand"];
form.addCheckboxItem()
.setTitle(item)
.setChoiceValues(choices);
var url_form= Logger.log('Published URL: ' + form.getPublishedUrl());
Logger.log('Group: '+group)
lista_url.push(url_form)
}
function generate_Form_links(group){
group.forEach(function(item, index){
console.log(item, index)
createForm(item)
}
}
generate_Form_links(group)
EDIT:
Implementing this raises this error: TypeError: infoArray.join is not a function
function excelformat(lista_url) {
var result_table = lista_url
var lineArray = [];
result_table.forEach(function(infoArray, index) {
var line = infoArray.join(" \t");
lineArray.push(index == 0 ? line : line);
});
var csvContent = lineArray.join("\r\n");
var excel_file = document.createElement('a');
excel_file.setAttribute('href', 'data:application/vnd.ms-excel;charset=utf-8,' + encodeURIComponent(csvContent));
excel_file.setAttribute('download', 'Visitor_History.xls');
document.body.appendChild(excel_file);
excel_file.click();
document.body.removeChild(excel_file);
}
excelformat(lista_url)
Not sure if I understand your task correctly. So, if you have the two arrays: group and links you can add their content in spreadsheet this way:
var group = [138, 139];
var links = ['https://docs.google.com/forms/idForm138','https://docs.google.com/forms/idForm139'];
function save_arrays_to_spreadsheet(group, links) {
var ss = SpreadsheetApp.openById(ss_id); // <-- put the spreadsheet ID here
var sheet = ss.getSheets()[0]; // let it be a first sheet
for (var i in group) sheet.appendRow([group[i], links[i]]); // add a row
}
And I don't understand what this function in your code is doing:
function generate_Form_links(group){
for (var group=0; group<=group.length ; group=i++){
createForm(group) //call our function for each value in list
}
}
It gets group (an array?) and converts it into zero var group = 0, and then there appears the variable i, etc. It all looks like an error to me.
Probably, I don't know, there should be:
function generate_Form_links(group) {
for (var i=0; i<=group.length; i++) { createForm(group[i]) }
}

Mass apply copied range to multiple sheets

I currently have a script that I use to apply mass changes to multiple spreadsheets
function onOpen() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var menuEntries = [];
menuEntries.push({name: "Update Sheets", functionName: "updateSheets"});
ss.addMenu("Actions", menuEntries);
}
function ChangesAug1() {
var data = SpreadsheetApp.openById('XXX').getSheetByName('ListOfSheetsToBeUpadated').getDataRange().getValues();
for (var row = 2; row < data.length; row++ ) {
var spreadsheet = SpreadsheetApp.openById(data[row][0]).getSheetByName('Template');
And I have this other script I am using to copy and paste a range from one spreadsheet to another
var sss = SpreadsheetApp.openById('SourceID'); //replace with source ID
var ss = sss.getSheetByName('TemplateSheet'); //replace with source Sheet tab name
var range = ss.getRange('A1:EJ5'); //assign the range you want to copy
var data = range.getValues();
var tss = SpreadsheetApp.openById('DestID'); //replace with destination ID
var ts = tss.getSheetByName('DestSheet'); //replace with dest
ts.getRange(ts.getLastRow()+1, 1,5,140).setValues(data); //you will need to define the size of the copied data see getRange()ination Sheet tab name
Any Idea on how I can combine the 2 scripts to mass apply a copied range from one sheet to a list of sheets ?
Thank you for responses :)
You should just create a function that is used to copy the data wanted from one sheet to another and then call this function when accessing the sheets in the for loop you are using.
Therefore, you can use something similar to this:
function copyFromOneSheetToAnother(var sourceSheet,
var destinationSheet) {
var range = sourceSheet.getRange('A1:EJ5');
var data = range.getValues();
destinationSheet.getRange(ts.getLastRow() + 1, 1, 5, 140).setValues(data);
}
The above function is expecting two parameters: the sourceSheet and the destinationSheet. As for calling this function, you can just use this:
function ChangesAug1() {
var data = SpreadsheetApp.openById('XXX').getSheetByName('ListOfSheetsToBeUpadated').getDataRange().getValues();
for (var row = 2; row < data.length; row++) {
var spreadsheet = SpreadsheetApp.openById(data[row][0]).getSheetByName('Template');
//get THE_DESTINATION_SHEET as well
copyFromOneSheetToAnother(spreadsheet, THE_DESTINATION_SHEET);
}
}
Reference
Sheet Class Apps Script;
Range Class Apps Script.

Script to copy multiple ranges to another sheet (Google Sheets)

Pretty new to coding and I've been trying to solve this one, but I can't find out how and now I'm turing to you guys:
There is a spec sheet, containing a couple of information on an item:
Product Name (on A3)
Product Code (on A4)
Volume (on c3)
Und (on C4)
Cost (on A5), etc.
Then, underneath this "header", there is a table containing the ingredients that make up that item:
ItemNumber, Product, Manufacturer, Unt, Cost, Remarks
These are set on a range (A12:T50)
The need is to have this table moved to a sheet, which the below code does, but how I can I have the header moved as well, repeating each of the header ranges, forming a database-like table for further consulting?
Here is the working script:
function copyrange() {
var sourceSheet = 'New Item';
var destinationSheet = 'Consolidated';
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName(sourceSheet);
var LastRowSource = sheet.getLastRow();
var LastColumnSource = sheet.getLastColumn();
var values = sheet.getRange(11,1,LastRowSource,LastColumnSource).getValues();
var csh = ss.getSheetByName(destinationSheet);
var data = [];
var j =[];
for (var i = values.length-1; i != ""; i--) {
if ( values[i][0] != '') {
data.push(values[i]);
//sheet.deleteRow(i+1)
}
}
//Copy data array to destination sheet
csh.getRange(csh.getLastRow()+1,1,data.length,data[0].length).setValues(data);
}
Here is the link to the file in question:
https://docs.google.com/spreadsheets/d/1GlD_VIOFHj7PGfCCnfVZqdZbE22aVoUw91BSCZecsRc/edit#gid=371161645
Any help is appreciated.

Creating Nested For-Loop on Google Sheets Script Editor to Auto-Extract Data into Required Format

I am trying to come up with a function that could extract data from one workbook to another that has a separate format. I will refer to the workbooks as "Source" and "Destination". So, on the "Source", I have the data arranged in yearly tabs. However, on "Destination", I have tabs indicating the regions. I have attached snapshots of the two workbooks.
Since I have no basics in programming, I tried to come up with a code but it didn't quite work. The following is my attempt at a nested for-loop which first extracts the data from the "2015" tab of the first region ("Ampang"), and pastes it into the other workbook in the "Ampang" tab and the "2015" row. I ran the debugging function and it says that the "var data" is undefined.
function D() {
var ss = SpreadsheetApp.getActiveSpreadsheet();//open destination worksheet
var sss = ss.getSheets(); //get all destination sheets
//var sheetname = ss.getSheetName(); //get sheet names
var sheet1 = SpreadsheetApp.openByUrl("https://docs.google.com/spreadsheets/d/1jJ8QysQTmS5tG4wvNCxqdbWvAbdbmJm5uatdgIHe6tw/edit#gid=793399042"); //open where data is located
var sheet = sheet1.getSheets(); //get all the sheets required
for (j = 0; j<sss.length; j++) {
for (i = 0; i <sheet.length; i++) {
switch(sheet[i].getSheetName()) {
case "Main Menu" :
break;
default:
var data = sheet.getSheets()[i].getRange(i+1, i+2, 1, 2); //get the data for Specific Region and then Changing the Year
var destination = sss[j].getRange(j,j+1,1,2); //pasting the data to the specific year at the Specific Region Tab/
data.copyTo(destination);
}
}
}
}
[Update 1]
So, I realized that the copyTo() function doesn't work when the data are in separate workbooks so I have come up with a new code below:
function D() {
// define the source sheets
var ss = SpreadsheetApp.openByUrl("https://docs.google.com/spreadsheets/d/1jJ8QysQTmS5tG4wvNCxqdbWvAbdbmJm5uatdgIHe6tw/edit#gid=793399042");
// get all source sheets
var source = ss.getSheets();
// define the target sheets
var ts = SpreadsheetApp.getActiveSpreadsheet();
// get all target sheets
var target = ts.getSheets();
// set nested for-loop
for (j = 0; j < target.length; j++) {
for (i = 0; i < source.length; i++) {
if (source[i].getSheetName() !== "Main Menu") {
var rangeSource = source[i].getRange(i+1,i+1,1,2); // get the source range
var values = rangeSource[i].getValues(); // get the values from the set range
}
if (target[j].getSheetName() !== "Main Menu") {
var rangeTarget = target[j].getRange(j+1,j+1,1,2); //get the target range
rangeTarget.setValues(values[i]); // paste the values to the target range
}
}
}
}
However, the var rangeSource and values are currently undefined. I still am trying to find the source of the error.
Source Sheets Snapshot
Destination Sheets Snapshot
You've defined sheet as all the sheets
var sheet = sheet1.getSheets(); //get all the sheets required
So data needs to be
var data = sheet[i].getRange(i+1, i+2, 1, 2); //get the data for Specific Region and then Changing the Year
See is that helps.

Looking for one Google Script App for 4 sheet tabs to produce one json

Ok...not sure how to do this. Right now I 4 sheets and 4 scripts for each sheet producing 4 json feeds. What I am trying to experiment with is having one script that will produce 1 json that I can use in a web page and just call the type of class. They are all formatted the same with columns etc.
Here is the Google Script App code I have.
function doGet(e){
// Change Spread Sheet url
var ss = SpreadsheetApp.openByUrl("https://docs.google.com/spreadsheets/d/SpreadsheetID/edit#gid=0");
// Sheet Name, Change Sheet to whatever name you used to name your sheet
var sheet = ss.getSheetByName("Class Sheet 1");
return getClasses(sheet);
}
function getClasses(sheet){
var dataObj = {};
var dataArray = [];
// collecting data starting from 2nd Row , 1st column to last row and last column
var rows = sheet.getRange(2,1,sheet.getLastRow()-1, sheet.getLastColumn()).sort([{column: 1, ascending: true}, 1]).getValues();
for(var i = 0, l= rows.length; i<l ; i++){
var dataRow = rows[i];
var record = {};
record['Name'] = dataRow[0];
record['Note'] = dataRow[1];
record['Address'] = dataRow[2];
record['StreetAddress'] = dataRow[3];
record['City'] = dataRow[4];
record['State'] = dataRow[5];
record['ZipCode'] = dataRow[6];
record['ContactName'] = dataRow[7];
record['EMailAddress'] = dataRow[8];
record['CustomerServicePhone'] = dataRow[9];
dataArray.push(record);
}
dataObj = dataArray;
var result = JSON.stringify(dataObj);
return ContentService.createTextOutput(result).setMimeType(ContentService.MimeType.JSON);
}
Scratching my head on this a little bit....I'm sure its something simple and I am probably over thinking things, but any help would be appreciated.
Possible Solution:
The e object in your doGet(e) provides a way to send parameters to your script. You can access different sheets with different url parameters. You can then easily get the requested SheetName through e.parameter. Use
https://script.google.com/.../exec?sheet=ClassSheet1 //for ClassSheet1
https://script.google.com/.../exec?sheet=ClassSheet2 //for ClassSheet2
Code.gs:
function doGet(e){
var ss = SpreadsheetApp.openByUrl("https://docs.google.com/spreadsheets/d/SpreadsheetID/edit#gid=0");
var sheetName = e.parameter.sheet;
var sheet = ss.getSheetByName(sheetName);
return getClasses(sheet);
}
You can also provide UI in your web-app to select a sheet.

Categories

Resources