Create Script to clear cell every time sheet is opened - google-apps-script

I am very new to scrips on google sheets and have been having no success
I have been trying to create a script that clears the content of 1 cell every time the sheet is opened but have had no luck, i have looked up how to do it but every example i try just errors. I need cell A2 to be clear every time someone new opens the sheet
https://docs.google.com/spreadsheets/d/1vvq7k_sdP2CBLZXzkpfxGvcmoTPdxC0NaH3I7-8wAoo/edit?usp=sharing

After you create the function in the script editor, Goto "Edit->Current Project's Triggers" and click on "add one now". Set the function that you want and under Events, choose "From SpreadSheet". On the next drop down list, choose "On Open"
I have create a function that clear the content of cell "A2" just to show how it works.
function myFunction() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheets()[0];
var range = sheet.getRange("A2");
range.clearContent();
}
Please Note that after you open the sheet, it will take upto 5 seconds to clear the cell.

Related

Creating a backup of data entered into a sheet via Google App Scripts

I have a spreadsheet where users can enter data and then execute a function when clicking on a button. When the button is clicked it logs the time and entered data in a new row on another sheet in that spreadsheet.
To make sure that sheet is not accidentally edited by the users I want to create a non-shared backup of that data.
I import the range to another spreadsheet, but just importing the range means that if the original sheet is edited/erased that data will also be edited/erased, so I wrote the following script to log the changes as they come in.
function onEdit(event){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var incomingSheet = ss.getSheetByName('Incoming');
var lastRow = incomingSheet.getLastRow();
var incomingData = incomingSheet.getRange(lastRow,1,1,7);
var permanentSheet = ss.getSheetByName('PermanentLog')
var newdataRow = permanentSheet.getLastRow();
incomingData.copyTo(permanentSheet.getRange(newdataRow+1,1));
}
This works when Run from the Apps Script Editor, however, when I enter new data and click the button on the original spreadsheet, it logs the data to the log sheet there, and the range is imported to the 'Incoming' sheet of the new Spreadsheet, but the data is not copied over to the 'Permanent Log' sheet (unless I Run it manually from within the Apps Script Editor). It also works if I remove the ImportRange function from the first sheet and then just manually enter data in on the 'Incoming' sheet.
So does this mean new rows from an Imported Range do not trigger onEdit? What would be the solution? I don't want to run this on a timed trigger, I want to permanently capture each new row of data as it comes in.
Also, am I overlooking a more elegant and simple solution to this whole problem?
Thank you for your time.
This function will copy the data to a new Spreadsheet whenever you edit column 7 which I assume is the last column in your data. It only does it for the sheets that you specify in the names array. Note: you cannot run this from the script editor without getting an error unless you provide the event object which replaces the e. I used an installable onEdit trigger.
The function also appends a timestamp and a row number to the beginning of the archive data row
function onMyEdit(e) {
e.source.toast('entry');//just a toast showing that the function is working for debug purposes
const sh = e.range.getSheet();//active sheet name
const names = ['Sheet1', 'Sheet2'];//sheetname this function operates in
if (~names.indexOf(sh.getName()) && e.range.columnStart == 7) {
const ass = SpreadsheetApp.openById('ssid');//archive spreadsheet
const ash = ass.getSheetByName('PermanentLog');//archive sheet
let row = sh.getRange(e.range.rowStart, 1, 1, 7).getValues()[0];
let ts = Utilities.formatDate(new Date(), Session.getScriptTimeZone(), "yyyy/MM/dd HH:mm:ss");//timestamp
row.unshift(ts, e.range.rowStart);//add timestamp and row number to beginning
Logger.log(row);//logs the row for debug purposes
ash.appendRow(row);//appends row to bottom of data with ts and row
}
Logger.log(JSON.stringify(e));
}
Restrictions
Script executions and API requests do not cause triggers to run. For example, calling Range.setValue() to edit a cell does not cause the spreadsheet's onEdit trigger to run.
https://developers.google.com/apps-script/guides/triggers
So yeah, as far as I understand you it can't be done that way.

onChange to Run ONLY if A3 has data - Google Apps Script / Google Sheets

I am trying to get this script to only run if is sees data in A3. the data is coming to this sheet from another sheet. I tried the onChange but it wouldnt trigger when the new data arrived in "Top Up Needed". add the onchange to the project triggers but still doesnt run script.
function TopUpNeeded() {
var spreadsheet = SpreadsheetApp.getActive();
spreadsheet.setActiveSheet(spreadsheet.getSheetByName('TOP UP NEEDED'), true);
var sheet = spreadsheet.getSheetByName('TOP UP NEEDED');
sheet.getRange('J3').activate().setFormula('=QUERY({\'SKU & Qty\'!$A$3:$C},"SELECT * WHERE Col1 MATCHES \'" & JOIN("|",FILTER(I2:I, NOT(ISBLANK(I2:I)))) & "\' ")');
}
also tried this code above my code,but no good.
function onChange() {
var sheet = SpreadsheetApp.getActive();
ScriptApp.newTrigger("TopUpNeeded")
.forSpreadsheet(sheet)
.onChange()
.create();
}
Thanks In Advance
onChange does not run if changes were not made by a human, see restrictions
The exception is if the data is being updated with the cell formula IMPORTRANGE
You can paste into cell "A3" of sheet "Top Up Needed" the formula
IMPORTRANGE(spreadsheet_url, range_string)
specifying the spreadsheet and range that is expected to populate the cell content.
In this case your first function will fire on onChange trigger each time the content of A3 updates.

Google sheet script - copy & plase a cell value

I need a simple script for Google sheet which will automatically daily will do simple task - copy a 3 cell's values and paste into another 3 cells as a plain text.
Is anyone can help me?
Assuming your spreadsheet page is named PAGE 1 and you want to copy the data from A1 to A3 and paste it into the same PAGE 1 in cells B1 through B3, this is the script to use:
function MyFunction() {
var ss = SpreadsheetApp.getActive();
ss.getRange('Page 1!A1:A3').copyTo(ss.getRange('Page 1!B1:B3'), SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);
}
To achieve what you want to do. I recommend you to use the Time-driven triggers, which help you to trigger events every "n" time (mins, hours, days). Follow these steps to configure the Time-driven triggers.
1) Go to your Apps Script project
2) Click Edit->Current project's triggers
3) Click "+ Add Trigger"
4) Select :
Choose which function to run -> setTimeTrigger
Select event source->Time-driven
Select type of time based trigger->Day timer
Select time of day->[Hour you want]
5) Click Save
6) Use this code in your Apps Script project:
// Name this function as "setTimeTrigger"
function setTimeTrigger(){
// Get first sheet in the active Spreadsheet
var ss = SpreadsheetApp.getActive().getSheets()[0];
// Parameters you set
var sourceVals = "A1:A3";
var destination = "B1:B3";
// Copy and paste the values where you want to
ss.getRange(sourceVals).copyTo(ss.getRange(destination));
}
Docs
You can learn more about triggers and Spreadsheet Class in the following docs:
Installable Triggers
Class Spreadsheet

In Google script is there a way to reference a specific sheet instead of the active sheet?

Is there a way to have scripts/macros run on a specific sheet instead of the active sheet?
In my trix, i want my first tab to always be updated with the data from my calendar. The script works, but it only updates the active sheet, not the first tab. I am also trying to make a macro to copy that first tab but i can't find a way to reference the first tab, only the active sheet. Help?
function CopyAllDataTab() {
var spreadsheet = SpreadsheetApp.getActive();
spreadsheet.getRange('A1').activate();
spreadsheet.duplicateActiveSheet();
};
Do you know the name of the sheet? If the sheet name stays the same, you can call the sheet by saying:
function CopyAllDataTab() {
var sheet = SpreadsheetApp.getActiveSpreadsheet.getSheetByName("Name of the sheet")
sheet.getRange('A1').activate();
sheet.duplicateActiveSheet();
};

Pasting a value into a new cell each time another is updated?

I'm hoping to have 2 cells that update their value every week. Each time these cells get their values updated I would like them to also be printed onto another two cells on a different sheet. Each week these cells that they are printed onto moving down by one. For example Week 1, the two cells are printed in A1 and B1. Week 2 they are printed in A2 and B2, and so on.
I know how to do this in Excel but no idea how I can change that over to Google Sheets / Scripts.
Assumptions:
Your new inputs are in input!A1 and input!B1; and
Your outputs will by in output!A and output!B.
You can write a script by clicking on Tools on the menu and entering Script Editor.
Then write this function:
function writeData() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var input = ss.getSheetByName("input")
.getRange(1, 1, 1, 2)
.getValues();
var outputSheet = ss.getSheetByName("output");
var numRows = outputSheet.getLastRow();
outputSheet.getRange(numRows + 1, 1)
.setValue(input[0][0]);
outputSheet.getRange(numRows + 1, 2)
.setValue(input[0][1]);
}
Next, set up a trigger. Within Script Editor, under Resources, select Current project's triggers and then set up your trigger. If you want it to run weekly, use a time-driven trigger. You can also set a spreadsheet-driven trigger to run on every edit. Save everything.
If you don't want to use automatic triggers, you can execute the writeData() function by adding an item on the menu bar of the spreadsheet:
function onOpen() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var menuEntries = [];
menuEntries.push({name: "Write data", functionName: "writeData"});
ss.addMenu("Custom functions", menuEntries);
}
Save, and if you refresh the spreadsheet you'll see a new item on the menu bar.