I've set up timesheets in google sheets for my employees. Each employee has their own document, and each week at the start of the pay period, I'll make a new sheet in each document and hide the sheet from the previous week. The new sheet is named by the dates of that pay period (i.e. Feb 12 - Feb 18) I'm trying to write a script that can do this automatically for me. The script involves two functions that run on a time-based trigger. The first function is working perfectly and creates a new sheet each week at the start of the pay period with the correct dates as the name of the sheet. The second function to hide the old sheet is not working. I have the triggers staggered, so that the new sheet is created several hours before the old one should be hidden. Here is what I've tried for hiding the old sheet (the Template sheet is what is getting copied to each of the employee's documents, where B2 is the start date of the pay period and H2 is the end of the pay period).
var ss = SpreadsheetApp.openById('TEMPLATE SHEET ID').getActiveSheet()
var newName1 = Utilities.formatDate(ss.getRange("B2").getValue(),"CST","MMM dd");
var newName2 = Utilities.formatDate(ss.getRange("H2").getValue(),"CST","MMM dd");
var EMPLOYEE = SpreadsheetApp.openById('EMPLOYEE SHEET ID');
var hideEMPLOYEE = EMPLOYEE.getSheets();
for(var i =0;i<hideEMPLOYEE.length;i++){
Logger.log(i);
if(hideEMPLOYEE[i].getName()!== newName1 + "-" + newName2){
hideEMPLOYEE[i].hideSheet();
}
}
Try this:
If B2 or H2 are already dates that's okay this will just create another date from them but if they are strings that the constructor is familiar with then this will create a new date for them as well.
var ss = SpreadsheetApp.openById('TEMPLATE SHEET ID').getActiveSheet()
var newName1 = Utilities.formatDate(new Date(ss.getRange("B2").getValue()),"CST","MMM dd");
var newName2 = Utilities.formatDate(new Date(ss.getRange("H2").getValue()),"CST","MMM dd");
var EMPLOYEE = SpreadsheetApp.openById('EMPLOYEE SHEET ID');
var hideEMPLOYEE = EMPLOYEE.getSheets();
for(var i=0;i<hideEMPLOYEE.length;i++){
Logger.log(i);
if(hideEMPLOYEE[i].getName()!= newName1 + "-" + newName2){
hideEMPLOYEE[i].hideSheet();
}
}
Related
I'm trying to to do the following tasks using Apps Script:
Create a new spreadsheet. The name will be "My spreadsheet" + Date of the day
Write a random value in the new spreadsheet
Copy the entire sheet (1st tab) from the new spreadsheet
Paste the value in another spreadsheet (in a specific sheet)
Here is the script I've written so far:
function copyPasteAllData() {
var date = Utilities.formatDate(new Date(), "GMT+7", "dd/MM/yyyy");
// get today's date
var ss = SpreadsheetApp.create("Existing Data - Apps Script - "+ date);
// create a new spreadsheet
var ssId = ss.getId();
// get ID of new spreadsheet
var existing = Sheets.Spreadsheets.Values.get('MyspreadsheetID', "Existing Data");
// get existing Spreadsheet + sheet location
var newSheet = Sheets.Spreadsheets.Values.get(ssId, "Sheet1");
// get new Spreadsheet + sheet location
ss.getRange('A1').setValue('1')
// setup a random value
var rangeAllData = newSheet.getRange(1, 1, newSheet.getMaxRows(), newSheet.getMaxColumns());
// copy the entire sheet from the
existing.rangeAllData.setValue()
}
I think the line below need to be changed but I'm not sure how to fix this.
I'm still quite a beginner with Apps Script and coding in general, apologies if it seems obvious.
var existing = Sheets.Spreadsheets.Values.get('MyspreadsheetID', "Existing Data");
var newSheet = Sheets.Spreadsheets.Values.get(ssId, "Sheet1");
Feel free to change anything in the script. Just note that I can only get the sheet ID and not the name
Thank you
Updated from the comment below:
In this case you can use the method getDataRange() to get the data from the new Sheet.
Then on the destination you can use the same range from the new sheet or use the one you want from the old sheet:
function copyPasteAllData() {
//getDate
var date = Utilities.formatDate(new Date(), "GMT+7", "dd/MM/yyyy");
//Create new sheet + set value
var newSheet = SpreadsheetApp.create("Existing Data - Apps Script - " + date);
newSheet.getRange('A1').setValue('this is new');
//get new sheet DataRange
var source = newSheet.getId();
var newSheetDataRange = SpreadsheetApp.openById(source).getSheets()[0].getDataRange().getA1Notation();
Logger.log(newSheetDataRange)
var newSheetValues = SpreadsheetApp.openById(source).getSheets()[0].getDataRange().getValues();
Logger.log(newSheetValues)
//copy the data to the old sheet
SpreadsheetApp.openById('OLD SHEET ID').getSheets()[0].getRange(newSheetDataRange).setValues(newSheetValues);
}
The code below is used to perform some simple functions in a Google Sheet.
It creates two new sheets (makes them (0) and (1), names them, and adds color) and hides another sheet.
The code has been extremely unreliable. If I create a blank google sheet and test it works fine but when I add it to the live version of the sheet it times out and fails to run all the code.
I also tested copying the live version (in case there was some corruption in the file) and initially it seemed to work but then the same problem occurred. I am brand new to app script so perhaps I am missing something obvious. I would appreciate any suggestions.
function New_Tabs() {
var spreadsheet = SpreadsheetApp.getActive();
var curDate = Utilities.formatDate(new Date(), "GMT+1", "M/d") //sets format for current
date as month/day
//Selects and activates the Day_date sheet / Gets calculated date info
var sheet = SpreadsheetApp.getActive().getSheetByName('Day_Date');
sheet.activate();
var val = SpreadsheetApp.getActiveSheet().getRange(2,6).getValue();
//Logger.log(val) Used this to check the value was pulled correctly
//Insert the sheet for today's date - Data from portal/Excel macro will be pasted here
spreadsheet.insertSheet(0); //Makes it the first sheet
spreadsheet.getActiveSheet().setName(val); //pulls calculated date from Day_Date sheet
spreadsheet.getActiveSheet().setTabColor('#00ff00'); //Colors the sheet tab green
//Insert the sheet for Logistics
spreadsheet.insertSheet(1); //Makes it the second sheet
spreadsheet.getActiveSheet().setName("Logistics " + curDate ); //names the sheet with text
and current date
spreadsheet.getActiveSheet().setTabColor('#00ff00'); //Colors the sheet tab green
//trying to slow down to make hiding the tab more reliable
Utilities.sleep(2000);// pause for 2 seconds
//selects the sheet for today's date - Data from portal/Excel macro will be pasted here
spreadsheet.setActiveSheet(spreadsheet.getSheetByName(val), true);
//trying to slow down to make hiding the tab more reliable
Utilities.sleep(2000);// pause for 200 milliseconds
//selects the Day_date sheet and hides it
spreadsheet.setActiveSheet(spreadsheet.getSheetByName('Day_Date'), true);
spreadsheet.getActiveSheet().hideSheet();
SpreadsheetApp.getUi().alert("Completed");
};
Try it this way:
function New_Tabs() {
const ss = SpreadsheetApp.getActive();
const curDate = Utilities.formatDate(new Date(), "GMT+1", "M/d");
const sh = SpreadsheetApp.getActive().getSheetByName('Day_Date');
const val = sh.getRange(2,6).getValue();
let ns = ss.insertSheet(0);
ns.setName(val);
ns.setTabColor('#00ff00');
let ns1 = ss.insertSheet(1);
ns1.setName("Logistics " + curDate );
ns1.setTabColor('#00ff00');
ns.hideSheet();
ss.toast("Completed")
}
I am currently using a google sheet to manage my portfolio. I want to save the value of my portfolio every day and save those numbers to create a growth graph. I want to take the value from one cell, paste it to another and the next day grab the value again from the same cell and paste on the cell under the one of the previous day without loosing my previous value. I am trying to create an AppScript script but I cant figure out how to go to the next cell once the day changes.
function Paste() {
var date = Utilities.formatDate(new Date(), "GMT+1", "dd/MM/yyyy")
var cellNumber = 3;
var cell = "C" + cellNumber;
var spreadsheet = SpreadsheetApp.getActive();
spreadsheet.getRange(cell).activate();
spreadsheet.getRange('J11').copyTo(spreadsheet.getActiveRange(), SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);
};
I want to increase cellNumber once a day!
function Paste() {
var ts=Utilities.formatDate(new Date(), "GMT+1", "dd/MM/yyyy")
var srcss=SpreadsheetApp.openById('sssid');//source of information spreadsheet
var desss=SpreadsheetApp.openById('dssid');//storage destination spreadsheet
var srcsh=srcss.getSheetByName('source sheet name');
var dessh=desss.getSheetByName('destination sheet name');
var value=srcsh.getRange('C3').getValue();
dessh.appendRow([ts,value]);
};
I'm creating a script in Google Sheets that will copy the active sheet and create 30 duplicate sheets within the same workbook. Each duplicated sheet will have a different name based on the value within a cell on the active sheet. The cell will contain a date; duplicated sheets will have names of dates after the date listed in the cell. Example, cell B3 is "7/5/2019". The duplicated sheets should be named, "July 6, 2019" (B3+1), "July 7, 2019" (B3+2), & "July 8, 2019" (B3+3), etc.
I'm using code that is already embedded within Google Sheets. Some of it was created by recording a macro and other parts were created through what little I know about coding and research online.
function duplicatesheet(){
//copy active sheet
var as = SpreadsheetApp.getActiveSpreadsheet()
SpreadsheetApp.getActiveSpreadsheet().duplicateActiveSheet();
//rename sheet
var myValue =
SpreadsheetApp.getActiveSpreadsheet().getRange('B3').getValue();
SpreadsheetApp.getActiveSpreadsheet().renameActiveSheet(myValue);
}
The code works in duplicating the active sheet once, but it is not making 30 duplicates. It is also not renaming the sheets properly as described above based on the date listed in cell B3. I need help creating code that will accomplish both of those tasks.
This is edited w.r.t. comments. You can also see the excellent answer by Tedinoz.
Try this code:
function duplicatesheet() {
var as = SpreadsheetApp.getActiveSpreadsheet(); // active spreadsheet
var s = as.getActiveSheet(); // first sheet object
var dateCell = "B3"; // cell containing first date
var N = 30; // number of copies to make
var startDate = new Date(s.getRange(dateCell).getValue()); // get the date stored in dateCell
var day = startDate.getDate(); // extract the day
var month = startDate.getMonth(); // extract the month
var year = startDate.getFullYear(); // extract the year
// loop over N times
for (var i = 0; i < N; i++) {
var asn = s.copyTo(as); // make a duplicate of the first sheet
var thisSheetDate = new Date(year, month, day+(i+1)); // store the new date as a variable temporarily
asn.getRange(dateCell).setValue(thisSheetDate); // writes the date in cell "B3"
asn.setName(Utilities.formatDate(thisSheetDate, undefined, "MMMMM d, yyyy")); // sets the name of the new sheet
}
}
I suggest putting N=30 there to something small, like N=2 to see whether it works with your formatting first.
The formatting here used by the Utilities.formatDate() method, I have assumed it to be MMMMM d, yyyy, which will print tab names in this format:
July 6, 2019
You may change it as you wish according to the reference [3] below.
You can see the references for all the functions used here:
Sheet.copyTo() method
Sheet.getRange() method
Java's SimpleDateFormat, used by Utilities.formatDate()
This code takes the single date entered by the OP in Cell "B3" of sheet name, say, "Sheet1; it loops thirty times creating a duplicate of the initial spreadsheet, incrementing the data-based sheet name by 1 day each time.
To ensure accurate date math, it's suggested that the format of Cell "B3" should be in the same style ("MMMM dd, yyyy") as the proposed sheet names.
function so5691088602(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheetname = "Sheet1";
var basesheet = ss.getSheetByName(sheetname);
var newSheetName = new Date(basesheet.getRange("B3").getValue());
var NumDups = 30;
for (var i=0;i<NumDups;i++){
basesheet.activate;
var tempDate = new Date();
var printdate01 = Utilities.formatDate(new Date(tempDate.setDate(newSheetName.getDate()+1+i)), "GMT+10", "MMMM dd, yyyy");
// Logger.log("DEBUG: Sheet Date = "+printdate01);
ss.insertSheet(printdate01, {template: basesheet});
}
}
Screenshot
I have very little experience, in fact near none so some of my terminology is just recently 'herd' not known.
I have two Spreadsheets with 1 sheet named the same in each.
Spreadsheet "Production" with sheet "Master" - Sheet ID is 1goG0TS1_2jwlGRetREYNRVk-Q6TEy3iWG_5VXFoZlus
Spreadsheet "Archived_Production" "Master" - Sheet ID is 1Mr4LJmp1SmpDs1i8U_PE5uLOEVjLc599Vq87m9HwCx0
With an onOpen script, or maybe timed trigger, set in my "Production" spreadsheet I need to MOVE all rows to my "Archived_Production" spreadsheet that meet 2 criteria
Criteria 1 - the Date in Column B is 7 days older than the current date
BUT ONLY IF, also
Criteria 2 - the entry in Column O is "100%"
In the included screenshot example, given today's date is 11/19/14, only the first entry highlighted in yellow would get moved upon next opening of the spreadsheet.
Thank you, as always, in advance for any help.
Sorry, not enough postings yet to allow image upload, but hopefully text explains.
You can use this function to perform the operation as you want on onOpen() script.
function onOpen() {
// I moved data from sheet1 to sheet2
var production_sheet_id = 'Put your production sheet's id here'; // This is your source sheet
var archived_sheet_id = 'Put your archived sheet's id here'; // This is your destination sheet
var sheet1 = SpreadsheetApp.openById(production_sheet_id).getSheets()[0];
var sheet2 = SpreadsheetApp.openById(archived_sheet_id).getSheets()[0];
var rows = sheet1.getDataRange();
var numRows = rows.getNumRows();
var values = rows.getValues();
for (var i = 0; i < numRows; i++) {
var oldDate = values[i][1]; // or var oldDate = new Date('values[i][1]')
var curDate = new Date();
// Count time difference in milliseconds, convert them into days then.
var diffInMilliSecs = (curDate.getTime() - oldDate.getTime());
var diffInDays = diffInMilliSecs/1000/60/60/24;
var diffInDays = Math.round(diffInDays);
if(values[i][14] == 1.0 && Math.abs(diffInDays+30) >= 7) // It evaluates 100% to 1.0
sheet2.appendRow(values[i]);
}
}