Google sheet script to shift content once a day - google-apps-script

I would like to move the content of B2:F8 to C2:G8 (one column to the right) once a day, at 4am.
How can I achieve that?

Move Stuff one column to the right
function movestuff() {
const ss = SpreadsheetApp.getActive();
const sh = ss.getSheetByName("Enter you sheetname");
sh.getRange("B2:F8").moveTo(sh.getRange("C2:G8"));
}
Run the following function once to create the trigger
function createTrigger() {
if(ScriptApp.getProjectTriggers().filter(t => t.getHandlerFunction() == "moveStuff").length == 0) {
ScriptApp.newTrigger("moveStuff").timeBased().everyDays(1).atHour(4).create();
}
}

You can run AppScript triggers to run your custom function once a Day.
For example, you have a function to do this content shifting in your Apps Script.
Then go to your Triggers > Add Trigger > Choose your function to run once in a day > Select the Select event source to Time Driven > Select type of time-based trigger to Day Timer
That's it. It will run a function once a day or you can customize your event whatever you like
From #Cooper solution you can take his code & call it in a daily based event timer.
function contentShifter() {
const ss = SpreadsheetApp.getActive();
const sh = ss.getSheetByName("Enter you sheet tab name");
sh.getRange("B2:F8").moveTo(sh.getRange("C2:G8"));
}
Run the function contentShifter in daily event timer that's it. Hope it will help you.

Related

Reference data from cell then timestamp it

I am currently using Sheetgo to timestamp data. Unfortunately my trial is about to expire. I'm assuming a script with a trigger would provide me with the same results, but I am unsure how to go about it.
I am pulling the value "A1" from an api:
Sheetgo then logs the value every hour on a separate sheet:
Any assistance with creating a script/trigger that could perform this task would be much appreciated. Thanks.
Logging a value every hour
function getA1() {
const ss = SpreadsheetApp.getActive();
const sh = ss.getSheetByName("Sheet0");//wherever the data is
const A1 = sh.getRange("A1").getValue();//wherever the data is
ss.getSheetByName("log").appendRow([A1,new Date()]);
}
Run the following atleast once
function ctrig() {
if(ScriptApp.getProjectTriggers().filter(t => t.getHandlerFunction() == "getA1").length == 0) {
ScriptApp.newTrigger("getA1").timeBased().everyHours(1).create();
}
}
Script App newTrigger

Google Spreadsheet Marcro App Script Adding Delay for The Macro Functions Lists

Hello I have a Macro Record which calling URL fetch function which getting some metadata from the specific URL
For Example i have 12 records in the Macro and want to have like 2 seconds pause after each macro trigger.
function FetchMetaData() {
var spreadsheet = SpreadsheetApp.getActive();
spreadsheet.getRange('AV4').activate();
spreadsheet.getCurrentCell().setFormula('=HtmlLang($G$2)');
spreadsheet.getRange('AV6').activate();
spreadsheet.getCurrentCell().setFormula('=MetaCharset($G$2)');
spreadsheet.getRange('AV9').activate();
spreadsheet.getCurrentCell().setFormula('=MetaViewport($G$2)');
spreadsheet.getRange('AV10').activate();
spreadsheet.getCurrentCell().setFormula('=Title($G$2)');
spreadsheet.getRange('AV11').activate();
spreadsheet.getCurrentCell().setFormula('=MetaD($G$2)');
spreadsheet.getRange('AV15').activate();
spreadsheet.getCurrentCell().setFormula('=MetaPropertyLocale($G$2)');
};
Where i am suppossed to add the delay function Utillty in the code above
Utilities.sleep(500);
I am trying this because the overall script macros will be to fetch the whole single domain with fecth(url) function and the number of total live checks will be near 200 sepatrate macros i have already in dropdown menus in the spreadsheet.
Once i make all macros recorded in a single macro the script above will have loke 200 records. Obviously all of them are using fetch function and running all in one will add huge amount of lag on the spreadsheet and probably some blocks based on the number of urls the site have.
I already try adding the
Utilities.sleep(500);
below the var function but this is not add a delay between fetch runner
like
function FetchMetaData() {
var spreadsheet = SpreadsheetApp.getActive();
Utilities.sleep(500);
Also try this way
function FetchMetaData() {
var spreadsheet = SpreadsheetApp.getActive();
spreadsheet.getRange('AV4').activate();
Utilities.sleep(3500);
spreadsheet.getCurrentCell().setFormula('=HtmlLang($G$2)');
spreadsheet.getRange('AV6').activate();
Utilities.sleep(3500);
spreadsheet.getCurrentCell().setFormula('=MetaCharset($G$2)');
};
And this way
function FetchMetaData() {
var spreadsheet = SpreadsheetApp.getActive();
spreadsheet.getRange('AV4').activate();
spreadsheet.getCurrentCell().setFormula('=HtmlLang($G$2)');
Utilities.sleep(3500);
spreadsheet.getRange('AV6').activate();
spreadsheet.getCurrentCell().setFormula('=MetaCharset($G$2)');
Utilities.sleep(3500);
};
Also between every .activate value but the macro runn all of the functions without delay
Any idea how can i do this in more elegant way to add the delay with a few rows of code.
Should i add all Range in Loop and For Each Function to run the Sleep Delay
Or Any Help i will Appreciate
Thanks
Try it this way:
function FetchMetaData() {
const ss = SpreadsheetApp.getActive();
const sh = ss.getActiveSheet();
const rgA = sh.getRangeList(['AV4','AV6','AV9','AV10','AV11','AV15']).getRanges();
const fA = ['=HtmlLang($G$2)','=MetaCharset($G$2)','=MetaViewport($G$2)','=Title($G$2)','=MetaD($G$2)','=MetaPropertyLocale($G$2)'];
rgA.forEach((r,i) => {
r.setFormula(fA[i]);
SpreadsheetApp.flush();
});
}

Show/Hide Columns Using A Checkbox

I am a wanna-be developer who is trying to figure out how to hide a set of columns based off a checkbox being clicked.
Would anyone want to help with this code?
I have 12 different sheets(one for each month) and I would like to hide columns A-H with the checkbox in I being clicked.
Ideally I can implement on each individual sheet.
Link to spreadsheet
There are few ways one can do it.
Easiest and most recommended among all is to group those column and it will have pretty much same use which you're looking for.
If you're willing to use appscript for it. Here how it should be done:-
Open Script Editor from your spreadsheet.
Declare the onEdit simple trigger which will run every time when sheet will be edited.
So whenever you'll click on tickbox on I1 this function will trigger.
When a trigger fires, Apps Script passes the function an event object as an argument, typically called e.
For this object, we're gonna have the information we need to do our task, and also to restrict our operation to only to those months sheet and range belongs to it.
Here is the code, I tried my best to explain what happening in the code:-
function onEdit(e)
{
var rangeEdited = e.range; // This will us range which is edited
var sheetEdited = rangeEdited.getSheet().getName() // from range we can get the sheetName which is edited
var mySheets = ["Jan List","Feb List"] // Put all the month sheet name in this array where you want to have this functionality
var rowEdited = rangeEdited.getRow() // From Range we can get Row which is edited
var columnEdited = rangeEdited.getColumn() // From Range we can get Column which is edited
if(mySheets.indexOf(sheetEdited) > -1) // Now we want to only restrict the operation on those sheets,so if other sheet is edited, we shouldn't run our hide function
{
if(rowEdited === 1 && columnEdited === 9) // we're further restricting the range of operation to run this function when only I1 is edited that is Row:- 1 and Col:- 9
{
hideUnhide(sheetEdited) // calling our hide function within OnEdit and passing sheetName as an argument in it
}
}
}
function hideUnhide(sheetEdited) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var ssname = ss.getSheetByName(sheetEdited) // accessing the sheet which is edited
var isItHidden = ssname.isColumnHiddenByUser(1) // checking if range is already hidden
if(isItHidden === false) // if No, hide that range
{
ssname.hideColumns(1, 6)
}
else // if Yes, unhide that range
{
var hideThisRange = ssname.getRange('A:H')
ssname.unhideColumn(hideThisRange)
}
}
Documentation:-
AppScript Events

Daily change of the active sheet in the Google Sheets

Can you please tell me how to automatically change the active sheet in google tables every day with Apps Script, like this: 1-2-3-1-2-3... And hide the inactive ones.
This is needed to show the current dining room menu.
Explanation:
You have three sheets in a spreadsheet file and your goal is to have only one sheet shown at a given day.
The first day you show only the first sheet and you hide the other two. The next day you hide all the sheets except for the second one and the third day you hide all sheets except for the third one.
The fourth day you start over again and you show only the first sheet.
This exercise needs two frameworks to work properly:
You need to store the day counter and the library you can use for that purpose is the PropertiesService class.
You need a time driven trigger to execute the script every day.
Solution:
The only thing you should do is to execute only and once the function createTrigger. The other function in this script is going to be executed every day automatically between 8-9 am and you should not execute it manually.
// execute only and once createTrigger
// Runs myFunction between 8am-9am in the timezone of the script
function createTrigger(){
ScriptApp.newTrigger("myFunction")
.timeBased()
.atHour(8)
.everyDays(1) // runs every day
.create();
}
// this should not be executed manually
function myFunction() {
const spreadsheet = SpreadsheetApp.getActive();
const sheets = spreadsheet.getSheets();
const sp = PropertiesService.getScriptProperties();
const breakPoint = 2; // after third sheet start over
const vs = sp.getProperty("visibleSheet");
let index;
if(vs){
index = parseInt(vs);
}
else {
index = 0;
sp.setProperty("visibleSheet",index);
}
sheets.map(sh=>sh.showSheet());
sheets.forEach((sh,i)=>{
if(i!=index){
sheets[i].hideSheet();
};
});
index==breakPoint ? sp.setProperty("visibleSheet",0)
: sp.setProperty("visibleSheet",index+1);
}
Things you can modify in the script:
Change 8 in atHour(8) if you want to execute the script in a different time rather than 8am.
Change variable breakPoint if you have more sheets (and not only 3). The counter starts from 0 this is why 2 indicates the third sheet. If you have six sheets then change it to breakPoint = 5;. In this way, the code is general and not restricted to the number of sheets.
Solution:
Apart from needing an Installable Trigger to have the script executed daily, this function should rotate the sheets per execution.
Prerequisites:
Take the Sheet ID of your spreadsheet from the URL and replace SHEET-ID in the code: https://docs.google.com/spreadsheets/d/**SHEET-ID**/edit#gid=0
Hide all sheets except one. The active sheet will be the starting point.
// execute this function first
function createTimeDrivenTriggers() {
// Trigger every 24 hours. Set preferred time here:
ScriptApp.newTrigger('myFunction')
.timeBased()
.atHour(10)
.everyHours(24)
.create();
}
// this should not be executed manually
function myFunction() {
var ss = SpreadsheetApp.openById("SHEET-ID");
var sheets = ss.getSheets();
for (var i = 0; i < sheets.length; i++) {
if (!sheets[i].isSheetHidden()) {
sheets[(i+1) % sheets.length].showSheet();
sheets[i].hideSheet();
break;
}
}
}

Create a trigger that works if the person is not an editor

I want people to jump to the current date row when opening the sheet. However, this should be the case for everyone viewing the sheet and irrespective of their edit-rights. For example, I want that people edit the current date row in the sheet every day over the link. In this case, onOpen() does not work. Is there any alternative or modification to the function?
I am informed about onOpen trigger, however, this would not work if somebody is editing the sheet only over the link with edit rights.
This is e.g. the code I would like to work for everyone:
function onOpen() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var range = sheet.getRange("B:B");
var values = range.getValues();
var day = 24*3600*1000;
var today = parseInt((new Date().setHours(0,0,0,0))/day);
var ssdate;
for (var i=0; i<values.length; i++) {
try {
ssdate = values[i][0].getTime()/day;
}
catch(e) {
}
if (ssdate && Math.floor(ssdate) == today) {
sheet.setActiveRange(range.offset(i,0,1,1));
break;
}
}
}
I found the options: Edit Triggers
To manually create an installable trigger through a dialog in the script editor, follow these steps:
From the script editor, choose Edit > Current project's triggers.
Click the link that says: No triggers set up. Click here to add one now.
Under Run, select the name of function you want to trigger.
Under Events, select either Time-driven or the Google App that the script is bound to (for example, From spreadsheet).
Select and configure the type of trigger you want to create (for example, an Hour timer that runs Every hour or an On open trigger).
Optionally, click Notifications to configure how and when you are contacted by email if your triggered function fails.
Click Save.
Google Explanation to Edit Triggers