I would like to have a short Google docs script which makes it possible to automatically see only the last two rows in a Google spreadsheet. So what I want is, when I add new data in a new row and hit ENTER, it automatically shows only the last two rows and hide all other rows.
I self started with the below codes but I don't know what to do further. Any help will be really appreciated.
function HideDone() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var test = sheet.getLastRow() - 2;
sheet.hideRows(1,test);
}
This task can be accomplished with an onEdit() Trigger.
Code:
function hide () {
var ss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('REPLACE');
ss.hideRows(1, ss.getLastRow()-2);
}
Set a trigger -> select hide function -> event on edit
Related
I have mashed together a Google Apps script to create an event in the calendar based on values in my Google sheet. The script should work in the following conditions:
Whenever a new row is added (achived by a trigger - the 1st function)
Only apply to the last row on the spreadsheet
Only create an event if the "id" cell (28) is empty
It should then create the calendar event and populate cell 28 with the event ID.
The new rows are created when a client fills out a form on my website. I'm using Ninja Forms in WordPress that has a Google Sheets plugin. So the filled out form is automatically added to the sheet, then this function fires.
Everything is almost working. When I test manually (eg I delete the id cell in the last row or I create a new row or copy an existing row) it works perfectly. The event is created only if there is no event ID in cell 28 already, and it successfully fills out cell 28 with the ID. Great!
However, when the row is created using the WordPress form I get two calendar events. IE - it's like the function runs twice. Each event is identical and both are created at the same time.
I'm guessing this has something to do with how the form integrates with the sheet. It is somehow triggering my function twice. I have tried using Utilities.sleep at different points in the function with different values to see if maybe waiting between strps helps, but to no avail.
Can anyone think of a way I can stop this from occurring? Is there some kind of check I might be able to build into my function? Or have I missed something obvious? I would really appreciate any suggestions.
Here is my code:
function initializeTrigger(){ // run once only to create the trigger
var sheet = SpreadsheetApp.getActive();
ScriptApp.newTrigger("NewCalEvent")
.forSpreadsheet(sheet)
.onChange()
.create();
}
function NewCalEvent() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('Bookings2');
var row = sheet.getLastRow();
var calId = "xxxyyy#group.calendar.google.com";
var cal = CalendarApp.getCalendarById(calId);
var date = sheet.getRange(row, 1).getValue();
var title = sheet.getRange(row, 26).getValue();
var tz = sheet.getRange(row, 23).getValue();
var tstart = new Date(sheet.getRange(row, 32).getValue());
var tstop = new Date(sheet.getRange(row, 33).getValue());
var loc = sheet.getRange(row, 2).getValue();
var desc = sheet.getRange(row, 27).getValue();
var guests = sheet.getRange(row, 29).getValue();
var id = sheet.getRange(row, 28).getValue();
if (id == ""){
var newEvent = cal.createEvent(title, tstart, tstop, {description:desc,location:loc,guests:guests,sendInvites:true}).getId();
sheet.getRange(row, 28).setValue(newEvent)
}
}
Possible Solution:
Add a check to see if the calendar event has already been created for this time.
More Information:
As it is not clear exactly where this trigger duplication is coming from, a way to circumvent the event being created twice is to search the calendar for the specified time frame for events which have the description you intend to enter, and then wrap the event creation code inside the check so it only runs if the event doesn't yet exist.
Code Snippet:
// ...
var id = sheet.getRange(row, 28).getValue();
var events = cal.getEvents(tstart, tstop, {search: desc})
.map(function(e) {
try {
return e.getDescription();
}
catch {
return "";
}
});
if (!events.includes(desc)) {
if (id == ""){
var newEvent = cal.createEvent(title, tstart, tstop,
{description:desc,location:loc,guests:guests,sendInvites:true}).getId();
sheet.getRange(row, 28).setValue(newEvent)
}
}
This way, if the script is run twice, then as the event already exists the second time, it will not be created again.
NB: This checks for all Calendar event exists within the time frame tstart to tstop that have a description of desc. If you happen to have other events within this time frame with the same description, this script may not behave as expected.
References:
Class CalendarApp - getEvents(startTime, endTime, options) | Apps Script | Google Developers
So I have two separate sheets, one with a data list full of unique names, their location and their current status. The second would have an input to type someones name and it would pull up the row that contains their current location/status(first function), from there I could change the status and run the second function that updates the first sheet with the new status. I have been googling all day trying to cobble together something that would work and I think I am almost there on the first function but I am stuck and any help to point me in the right direction would be greatly appreciated.
Ideally the first function would trigger upon typing the name in and the second would trigger upon changing the status but I can find a manual workaround if need be.
function dataPull() {
var data = SpreadsheetApp.openById('Spreadsheet_ID'); //replace with Data spreadsheet ID
var filteredRows = data.filter(function (data) {
var employee = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getRange('b2').getValue();
if (data[1] === employee) {
return data
}
});
SpreadsheetApp.getActiveSheet().getRange('A2:D').setValue(filter)
}
Here are some screenshots that will hopefully better explain what I am looking to accomplish.
Sample data
Type someones name in Input sheet
Pull up current status w/ function one
Update Status and run function two
Sample data updates to reflect change in status
Edit Dialog in a Sheet
There is two sections to this function. The top section triggers off of edits to the Edit sheet in column 2 and row 2 which is a dropdown that contains all of the name in the Data Sheet. An edit here cause the top section to run which reads the the data on the Data sheet and file a matching name when it finds it that line is loaded into columns 1 through 4 and row 2 of the Edit sheet. Then you can edit the status and click the checkbox to save it back to the Data sheet. The lower portion then runs which reset's the checkbox, clears the Edit range and loads the edits back into the Data Sheet.
Please take a look at the animation to see the process in action.
Just to let you know upfront, you can run this function from the script editor you must put it into you sheet and name your sheets properly. You must also set up the data validations for the two drop downs. If you try to run this function from the script editor you will get the Error: Cannot find method getsheet() of undefined
function onEdit(e) {
e.source.toast('Entry');
var sh=e.range.getSheet();
if(sh.getName()=='Edit' & e.range.columnStart==2 && e.range.rowStart==2) {
e.source.toast('flag1');
var found=false;
var dsh=e.source.getSheetByName('Data');
var vA=dsh.getRange(2,1,dsh.getLastRow()-1,dsh.getLastColumn()).getValues();
for(var i=0;i<vA.length;i++) {
if(vA[i][1]==e.range.getValue()) {
sh.getRange(2,1,1,4).setValues([vA[i]]);
found=true;
e.source.toast('Value Found at i = ' + i + 'value = ' + vA[i][1],'',-1);
break;
}
}
if(!found) {
e.source.toast('No Value found = ' + e.value);
}
Logger.log(vA);
}
if(sh.getName()=='Edit' & e.range.columnStart==5 && e.range.rowStart==2) {
e.range.setValue("FALSE");
dsh=e.source.getSheetByName('Data');
dsh.getRange(Number(e.range.offset(0,-4).getValue()+1),4).setValue(e.range.offset(0,-1).getValue());
sh.getRange(2,1,1,4).clearContent();
}
}
Data Sheet:
Edit Sheet:
Animation:
You can't use the built-in onEdit(e) trigger; as it behaves in the same manner as a custom function would eg.(Restricted to the sheet it's bound to).
You can install a trigger in your bound script, and have it execute your un-restricted function.
function importData(e){
// Get the cell where the user picked its name
var range = e.range;
// The Id of your data source sheet
var dataSheetId = 'XXXXXXXXXXXXX';
// Get all values from source sheet as an array
var data_values = SpreadsheetApp.openById(dataSheetId).getDataRange().getDisplayValues();
// Return the row with data for matching employee
var filteredRow = data_values.filter(check)[0];
// Input location data in input sheet
SpreadsheetApp.getActiveSheet().getRange(range.getRow(),range.getColumn()+1).setValue(filteredRow[2]);
}
function check(row) {
// Get the name that the user picked
var employee_name = SpreadsheetApp.getActiveSheet().getActiveCell().getValue();
// Check if it matches and return the row
if (row[1].toLowerCase() === employee_name.toLowerCase()) {
return row
}
}
You can install the trigger from within your Apps Script by following Edit/Current project's triggers/Add trigger.
As the event source for the trigger select: "From spreadsheet"; and for function to run select "importData" (or the name of your function).
I was trying to create an GoogleSheet Script but I'm no expert so i can't figure it out my self. (can't even declare the sheet where i want this event to happen)
Here's my current code which is very far from what I want to happen
function minsTriggers() {
ScriptApp.newTrigger('myFunction')
.timeBased()
.everyMinutes(1)
.create();
function refresh() {
var spreadsheet = SpreadsheetApp.getActive();
spreadsheet.getRange('B2').activate();
spreadsheet.getCurrentCell().setValue('')
.setFormula('=IMPORTRANGE("Link","Table!A2:E5000")');};}
What I want to happen is when Cell b3 on Sheetname "Imported Data" become blank(its becoming blank due to importrange error) Cell b2 has to re:enter its formula(Like refreshing the formula in the cell")
Try this:
function check(){
var formula = '=IMPORTRANGE("Link","Table!A2:E5000")';
var ss = SpreadsheetApp.getActiveSheet();
if(ss.getRange("B3").getValue() == "")
ss.getRange("B2").clear().setFormula(formula);
}
This will check if B3 is blank, and if so, it will set the formula in B2. As for the trigger, I would suggest you set a time-based installable trigger (instructions here). You could also use an onEdit, but changes made by scripts don't trigger it, there are plenty of options, but it all depends on how you access the sheet.
I feel like this should be pretty simple but I can't find anything on here or online that copies the full column and moves it to a different column WITHIN THE SAME SHEET. I don't need other criteria other than copy the data in column 'A' and paste that data into column 'B'.
Please advise if you can!
Thanks.
I'm really not sure why I got downvoted for this but I figured out how to simply copy from one row to another:
function copyValuesOnly() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var source = ss.getRange('List!C2:C10');
source.copyTo(ss.getRange('List!D2'), {contentsOnly: true});
}
Below script should help you out. After pasting it in the script editor, run the onOpen function first. It should create an extra menu-item in your spreadsheet from where you can run the copy function.
function onOpen() {
SpreadsheetApp.getUi()
.createMenu('Custom Menu')
.addItem('Copy Col A', 'copyCol')
.addToUi();
}
function copyCol() {
var ss = SpreadsheetApp.getActiveSheet();
ss.getRange('A:A')
.copyTo(ss.getRange('B:B'), {contentsOnly: true});
}
I'm trying to program a spreadsheet so that whenever I add a new entry to it, it copies the data from that cell into another spreadsheet. Here's my code (that doesn't seem to work):
function onEdit(e) {
var sheet = SpreadsheetApp.getActiveSheet();
var target = SpreadsheetApp.openById("*************");
var target_sheet = target.getSheetByName("Dashboard");
var last_row = target_sheet.getLastRow();
target_sheet.insertRowAfter(last_row);
var target_range = target_sheet.getRange("A"+(last_row+1)+":G"+(last_row+1));
e.range.copyTo(target_range);
}
Any ideas what I'm doing wrong?
There are two types of triggers in Apps Scripts - simple triggers and installable triggers.
onEdit() is an example of a simple trigger (the name is implicit). And there are limits to what you can do inside a simple trigger. And that includes opening another spreadsheet.
So, coming to the solution.
Rename your function to something else, say onEdit1() . And set up an installable trigger manually and set it to run each time the spreadsheet is edited.
Hint: Use Resources --> Current project's triggers from the script editor