I have this script which I found here which mimicks the 'make a copy' function, but also renames the sheet all within a single action.
function onOpen() {
var menu = [{name: "Duplicate and name", functionName: "dupName"}];
SpreadsheetApp.getActiveSpreadsheet().addMenu("Custom", menu);
}
function dupName() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var name = Browser.inputBox('Enter new sheet name');
ss.insertSheet(name, {template: sheet});
}
I want to take this script a step farther and use it to increase the number in the name of the previous sheet, by 1.
For example, A sheet will be called 'Sheet 1' and when I duplicate the sheet using this script, I want the new one to be called 'Sheet 2'.
Is this possible?
If so, how can I modify this script to do that?
Or is there a better way to write it in the first place?
(considering the post I'm referencing to is 4 years old).
The following script can duplicate the sheets and also rename the same with your custom name and add protection to either selected range or complete sheet as defined in the protection line:
function script() {
var spreadsheet = SpreadsheetApp.getActive();
var myValue = SpreadsheetApp.getActiveSheet().getSheetName();
spreadsheet.duplicateActiveSheet();
var totalSheets = countSheets(); //script function
myValue = "CUSTOMTEXT" + totalSheets; //sample CUSTOMTEXT1
SpreadsheetApp.getActiveSpreadsheet().renameActiveSheet(myValue);
var protection = spreadsheet.getActiveSheet().protect();
protection.setUnprotectedRanges([spreadsheet.getRange('C2:E5')])
.removeEditors(['user1#gmail.com', 'user2#gmail.com']);
protection.addEditor('user0#gmail.com');
SpreadsheetApp.flush();
};
function countSheets() {
return SpreadsheetApp.getActiveSpreadsheet().getSheets().length;
}
If the same function is triggered using the doget(e) function you can be the owner of the sheet irrespective to the triggering user. Kindly follow the following for more details on it: Changing Owner of the Sheet irrespective of the duplicator
You can use this script:
function onOpen() {
var menu = [{name: "Duplicate and name", functionName: "dupName"}];
SpreadsheetApp.getActiveSpreadsheet().addMenu("Custom", menu);
}
function dupName() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var array = sheet.getName().split(" ");
var ssnum = Number(array[array.length-1]);
array[array.length-1] = ++ssnum;
ss.insertSheet(array.join(' '), {template: sheet});
}
Note that you need to have a space delimiter between the text part and the number part of the sheet name in order to use this script.
Sample Spreadsheet:
Related
I was wondering if there was any way I could shorten the script below? As you can see, I copied the eight lines (B13-I13) to make a new one with a different row (B4-I14). However, I must continue it until row 23.
var values = [[formS.getRange("C7").getValue(),
formS.getRange("C8").getValue(),
formS.getRange("D9").getValue(),
formS.getRange("B13").getValue(), <--- shorten this
formS.getRange("C13").getValue(),
formS.getRange("D13").getValue(),
formS.getRange("E13").getValue(),
formS.getRange("F13").getValue(),
formS.getRange("G13").getValue(),
formS.getRange("H13").getValue(),
formS.getRange("I13").getValue(), ----> to this
formS.getRange("B14").getValue(), <--- shorten this
formS.getRange("C14").getValue(),
formS.getRange("D14").getValue(),
formS.getRange("E14").getValue(),
formS.getRange("F14").getValue(),
formS.getRange("G14").getValue(),
formS.getRange("H14").getValue(),
formS.getRange("I14").getValue(), ----> to this
]];
This is the script that I'm using..
function SaveData() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var formS = ss.getSheetByName("Form");
var dataS = ss.getSheetByName("Data");
--> LOCATION OF THE SCRIPT ABOVE <---
dataS.getRange(dataS.getLastRow()+1,1,1,11).setValues(values);
ClearCell();
}
Please see the sample picture below where I encode the data.
This is the sample image of the sheet where the data were being saved.
SAMPLE SPREADSHEET
In your situation, how about the following modification?
Modified script:
function sample() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var formS = ss.getSheetByName("Form");
var dataS = ss.getSheetByName("Data");
var values = [
...formS.getRange("C7:C8").getValues().flat(),
formS.getRange("D9").getValue(),
...formS.getRange("B13:I23").getValues().flat()
];
dataS.appendRow(values);
}
From However, I must continue it until row 23., I used B13:I23.
In this modification, the values of "C7:C8" and "D9" and "B13:I23" of "Form" sheet are copied to the last row of "Data" sheet as one row.
I just want a "hello world" and after an embarrassing number of hours, its still not working. I'm new to Javascript and Google App script.
Here is the simple script that fails to enter the "Hello" and I would appreciate any tips you have on getting this to work.
As you can see in the commented lines, I've tried many ways to get my "Hello" out there, but none of them work yet. The menu does work. Thanks for your help
Really what I want to do is to be able to move from cell to cell in a spread sheet, get the values there, assign it to a variable. And then to write the var value to a cell after a condition is meet in the script.
function onOpen() {
var ss = SpreadsheetApp.getActive();
var menuItems = [
{name: 'Generate Coin Trades', functionName: 'GCTrades_'}
];
ss.addMenu('CoinTrade', menuItems)
function GCTrades_() {
var ss = SpreadsheetApp.getActive();
SpreadsheetApp.setActiveSheet(ss.getSheetByName('Prices'));
sheet.getRange("$H$1").setValue('Hello');
//settingsSheet.activate();
// One before the last row that has been entered in the spreadsheet
// var LastRow = sheet.spreadsheet.getLastRow() -1;
// var cell1 SpreadsheetApp.getActiveSheet().getRange(LastRow,16);
// var cell = spreadsheet.getRange("$H$1");
// cell.setvalue('Hello')
//var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
// var cell = sheet.getRange(1655,16);
// var cell = 'H1655'
// cell.setValue("Hello");
//var count = SpreadsheetApp.getActiveSheet().getRange(2, 3, 6, 4)
// Spreadsheet.getActiveSheet().getRange(LastRow,16).setvalue('Hello')
// SpreadsheetApp.getActiveRange().setValue('hello')
}
There are a couple of typos preventing your script from running. First, your onOpen script isn't closed.
function onOpen() {
var ss = SpreadsheetApp.getActive();
var menuItems = [
{name: 'Generate Coin Trades', functionName: 'GCTrades_'}
];
ss.addMenu('CoinTrade', menuItems)
} // missing closing curly brace.
You used sheet.getRange()... but didn't define sheet anywhere. You also do not need to use setActive to edit the sheet, as you can do that on a cell-by-cell basis. It is enough to define the sheet in the script.
Once your sheet is defined, you can get ranges and set the values. I kept your absolute range ($H$1) for the first cell. We then use a relative reference for the second cell by getting the position using the .getRow() and .getColumn() methods.
function GCTrades_() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('Sheet1')
var cell1 = sheet.getRange("$H$1").setValue('Hello');
var cell2 = sheet.getRange(cell1.getRow(), cell1.getColumn()+1).setValue('World');
}
Try this:
function onOpen()
{
SpreadsheetApp.getUi().createMenu('CoinTrade')
.addItem('Generate Coin Trades', 'GCTrades_')
.addToUi();
}
//This is a private function so it will not show up in script editors function list. If you want it to show up on the function list then remove the trailing underscore
function GCTrades_()
{
var ss=SpreadsheetApp.getActive();
var sh=ss.getSheetByName('Prices').activate();//The activate is not required but it will force this sheet to be on top
sh.getRange("A1").setValue('Hello');//Do not use $s in the range here
}
What I really want:
Really what I want to do is to be able to move from cell to cell in a
spread sheet, get the values there, assign it to a variable. And then
to write the var value to a cell after a condition is meet in the
script.
It's not clear to me what you "really want". Perhaps, you can begin that code yourself and refine the description of what you "really want".
I am trying to create a Google Sheet template where a user can enter a value (Project URN) in a cell and run a script to save the template as a sheet, renamed with the Project URN.
I have created a test Google Sheet here https://docs.google.com/spreadsheets/d/1IPpQyYHl_TtNa1lGpmu4dlzwTFjOotV2OcnxFT84iUk/edit?usp=sharing
This sheet has the following script, but I cant get the renaming function to correctly work.
function saveAsSpreadsheet(){
var sheet = SpreadsheetApp.getActiveSpreadsheet();
var destFolder = DriveApp.getFolderById("0B7RrbZuJGLlha3NvM3ZqcTY3MDA");
DriveApp.getFileById(sheet.getId())
.(makeCopy(values = SpreadsheetApp.getActiveSheet()
.getRange(2, 2).getValues()), destFolder);
} //END function saveAsSpreadsheet
I did also find the following article but wasn't able to turn it to my use. However, the secret must be here somewhere! Rename worksheet to cell value keeping format
Kitten
You almost have it. Please try this:
function myFunction() {
var ss = SpreadsheetApp.getActiveSpreadsheet(); // Get spreadsheet
var id = ss.getId(); // Get spreadsheet ID
var sstocopy = DriveApp.getFileById(id); //Get spreadsheet with DriveApp
var sheet = ss.getActiveSheet(); // Grab the sheet in order to find the name of the new spreadsheet to be created
var sheet_name = sheet.getRange("A1").getValue(); // Get the value, in this case: Project Urn
var folder = DriveApp.getFolderById("XXXX"); // Get the folder where the sheet needs to be placed.
sstocopy.makeCopy(sheet_name,folder); // Make the copy of the sheet in that folder.
}
Let me know if you have any questions.
I'm trying to use copyTo to duplicate an entire sheet from one Google Sheet to a brand new one. Everything works great however, the newly created Sheets all say "Copy" and then the Sheet name. Is there a way to remove the word Copy? Code is below.
function setupSheet()
{
var sources = SpreadsheetApp.openById('172teYmA4Bz61PscMQiTmpqWdvBUBDu_J2hR0m_8i_b8');
var allSheets = ['Display Case', 'Your Badges', 'Badge Directory', 'Activate Sheet'];
allSheets.forEach(function(each)
{
var thisSheet = SpreadsheetApp.getActive()
var sourcevalues = sources.getSheetByName(each).copyTo(thisSheet)
});
}
var sourcevalues =
sources.getSheetByName(each).copyTo(thisSheet).setName(each);
This should be simple but I'm stuck on this script...
It has a function (createnewsheet) that runs manually AND on a time trigger so I had to choose openById() to access the spreadsheet but when I'm looking at the sheet and run the function manually I want to set the newly created sheet active and that's what is causing me trouble.
When I run the function (createnewsheet) from the script editor everything is fine but when I call it from the spreadsheet menu I get this error message : Specified sheet must be part of the spreadsheet because of the last line of code. AFAIK I'm not addressing a sheet outside my spreadsheet... Any idea what I'm doing wrong in this context ?
Here is a simplified code that shows the problem, a shared copy is available here
var ss = SpreadsheetApp.openById('0AnqSFd3iikE3dGVtYk5hWUZVUFNZMzAteE9DOUZwaVE');
var sheet = SpreadsheetApp.getActiveSpreadsheet();
var sh = ss.getSheetByName('master')
var logsheet = ss.getSheetByName('logger')
var FUS1=new Date().toString().substr(25,6)+":00";
function onOpen() {
var menuEntries = [ {name: "Manual test", functionName: "createnewsheet"},
];
sheet.addMenu("Utilities",menuEntries);
SpreadsheetApp.setActiveSheet(logsheet);// this is working fine
}
function createnewsheet(){
var sheetName = "Control on "+ Utilities.formatDate(new Date(), FUS1, "MMM-dd-yy")
try{
var newsheet = ss.insertSheet(sheetName,2);// creates the new sheet in 3rd position
}catch(error){
FUS1=new Date().toString().substr(25,6)+":00";
var newsheet = ss.insertSheet(sheetName+' - '+Utilities.formatDate(new Date(), FUS1, "HH:mm:ss"),2);// creates the new sheet with a different name if already there
}
newsheet.getRange(1,1).setValue(sheetName);
SpreadsheetApp.setActiveSheet(ss.getSheets()[2]);// should make 3 rd sheet active but works only when run from script editor
// SpreadsheetApp.setActiveSheet(newsheet);// should have same result but works only when run from script editor
}
I found a practical workaround to solve my use case : I use a different function from the menu (in wich I setActive() the sheet I want) and call the main function from this one.
When called from the trigger there is no use to set any active sheet so I removed this part from the main function.
It goes like this :
function manualTest(){ // from the ss menu
createnewsheet();
var sheet = SpreadsheetApp.getActiveSpreadsheet();
SpreadsheetApp.setActiveSheet(sheet.getSheets()[2]);// this works from the menu when ss is open
}
function createnewsheet(){ // from the trigger and from function manualTest()
var sheetName = "Control on "+ Utilities.formatDate(new Date(), FUS1, "MMM-dd-yy");
try{
var newsheet = ss.insertSheet(sheetName,2);
}catch(error){
FUS1=new Date().toString().substr(25,6)+":00";
var newsheet = ss.insertSheet(sheetName+' - '+Utilities.formatDate(new Date(), FUS1, "HH:mm:ss"),2);
}
newsheet.getRange(1,1).setValue(sheetName);
}
There is a catch here
SpreadsheetApp.setActiveSheet(ss.getSheets()[2]);
When you run it from script editor, It automatically gets the container spreadsheet and makes the said sheet active, but it is not the case when you run it from Custom Menu or triggers.
Modify this statement to:
ss.setActiveSheet(ss.getSheets()[2]);
ss.setActiveSheet(newsheet);
The best solution i have found is to reseed sheet. getActiveSpreadsheet() recognises the Spreadsheet currently in use so no need to openById once more, but
// SpreadsheetApp.setActiveSheet(ss.getSheets()[2]);
// SpreadsheetApp.setActiveSheet(newsheet);
sheet = SpreadsheetApp.getActiveSpreadsheet(); // reloads the active sheet (including changes to the Sheets array)
sheet.setActiveSheet(sheet.getSheets()[2]); // works as expected from editor and custom menu
I think this suggests that the original ss and sheet have cached the Spreadsheet to memory and their pointer isn't refreshed to reflect structural changes. I tried .flush() as a shortcut, but that seems a one way refresh to the sheet from the script, not the other way around.