I created two google sheet with an exchange of data from sheet 1 to 2 with the IMPORTRANGE function.
I would like to save my data on the second sheet while importing. But I don't know how.
Below is my code which allows me to delete the lines as soon as 30 days have passed.
function onEdit() {
// Sheet the data is on.
var SHEET = "Copie de TF VBX";
// The value that will cause the row to hide.
var VALUE = "date";
// The column we will be using
var COLUMN_NUMBER = 12
var ss = SpreadsheetApp.getActiveSpreadsheet();
var activeSheet = ss.getActiveSheet();
var cell = ss.getActiveCell()
var cellValue = cell.getValue();
var colonne = cell.getColumn();
var ligne = cell.getRow();
var date2 = new Date(Date());
var date1 = new Date(cellValue);
// différence des heures
var time_diff = date2.getTime() - date1.getTime();
// différence de jours
var days_Diff = time_diff / (1000 * 3600 * 24);
//Ensure on correct sheet.
if(SHEET == activeSheet.getName()){
//Ensure we are looking at the correct column.
if(colonne == COLUMN_NUMBER){
//If the cell matched the value we require,hide the row.
if(days_Diff>31){
activeSheet.deleteRow(ligne)
//Browser.msgBox(days_Diff)
};
};
};
}
Thank you for your help.
function onEdit(e) {
const sh = e.range.getSheet();
if (sh.getName() = "Copie de TF VBX" && e.range.columnStart == 12 && e.value) {
const td = new Date()
const thd = new Date(td.getFullYear(), td.getMonth(), td.getDate() - 31).valueOf();
const date1v = new Date(e.value).valueOf();
if (date1v > thd) {
sh.deleteRow(e.range.rowStart);
e.source.toast(DiffInDays(td,new Date(e.value));
}
}
}
function DiffInDays(Day1,Day2) {
if(Day1 && Day2 && (Object.prototype.toString.call(Day1) === '[object Date]') && (Object.prototype.toString.call(Day2) === '[object Date]')) {
var day=86400000;
var t1=new Date(Day1).valueOf();
var t2=new Date(Day2).valueOf();
var d=Math.abs(t2-t1);
var days=Math.floor(d/day);
//Logger.log(days);
return days;
} else {
throw 'Invalid Inputs';
}
}
Related
I am learning Javascript and this is my first time working with Google Sheets Apps Script. What I am doing is taking a large JSON file and importing it into my sheet. After that I am populating a few hundred properties based on the key:value found in the JSON.
This is how it kinda works right now:
Go to first column and first row of my sheet.
Get the name (property name).
Search the JSON for the key and then grab the value.
Update a neighbor cell with the value found in the JSON.
Right now it all works the only issue is it seems to be pretty slow. It takes about .5-1 second per lookup and when I have 200+ properties it just seems slow. This might just be a limitation or it might be my logic.
My sheet can be found here: https://docs.google.com/spreadsheets/d/1tt3eh1RjL_CbUIaPzj10DbocgyDC0iNRIba2B4YTGgg/edit#gid=0
My function that does everything:
function parse() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheets()[0];
var range = sheet.getRange(2,1);
var range1 = sheet.getRange("A2");
var cell = range.getCell(1, 1);
var event_line = cell.getValue();
var tmp = event_line.split(". ");
var col_number = tmp[0];
var event_name = tmp[1];
event_json = get_json_from_cell(col_number);
const obj = JSON.parse(event_json);
var traits = obj.context.traits;
var properties = obj.properties;
//Get the range for the section where properties are
var traits_range = sheet.getRange("contextTraits");
var allprop = sheet.getRange("testAll");
var alllen = allprop.getNumRows();
var length = traits_range.getNumRows();
for (var i = 1; i < length; i++) {
var cell = traits_range.getCell(i, 1);
var req = traits_range.getCell(i, 4).getValue();
var trait = cell.getValue();
var result = traits[trait];
var result_cell = traits_range.getCell(i, 3);
if (result == undefined) {
if (req == "y"){
result = "MISSING REQ";
result_cell.setBackground("red");
} else {
result = "MISSING";
result_cell.setBackground("green");
}
} else {
result_cell.setBackground("blue");
}
result_cell.setValue(result);
Logger.log(result);
}
for (var i = 1; i < alllen; i++) {
var cell = allprop.getCell(i,1);
var req = allprop.getCell(i, 4).getValue();
var prop = cell.getValue();
var result = properties[prop];
var result_cell = allprop.getCell(i, 3);
if (result == undefined) {
if (req == "y"){
result = "MISSING REQ";
result_cell.setBackground("red");
} else {
result = "MISSING";
result_cell.setBackground("green");
}
} else {
result_cell.setBackground("blue");
}
result_cell.setValue(result);
}
Logger.log(result);
}
This is what I've got:
function onEdit(e) {
var range = e.range;
var val = range.getValue();
var row = range.getRow();
var col = range.getColumn();
var shift = 1;
var ss = SpreadsheetApp.getActiveSheet().getRange(row, (col+shift));
if (col == 3){
ss.setValue(new Date()).setNumberFormat("MM/dd/yyy hh:mm:ss");
}
if (val == ""){
ss.setValue("").setNumberFormat("MM/dd/yyy hh:mm:ss");
}
}
This is what is happening:
However, when I edit a cell in barcode, it doesn't update the timestamp...
function onEdit(e) {
//e.source.toast("Entry");
//console.log(JSON.stringify(e));
const sh=e.range.getSheet();
if(sh.getName()=="Sheet1" && e.range.columnStart==3 && e.value) {
e.range.offset(0,1).setValue(Utilities.formatDate(new Date(),Session.getScriptTimeZone(),"MM/dd/yyyy HH:mm:ss"));
}
}
I presume you wouldn't want to this for all sheets but I could be wrong.
I am trying to make a script to automate deleting duplicate data based on column A. This is the current script I am using and it works.
// This scripts works but deleting new data instead of old data
function removeDuplicates() {
var sheetName = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getName();
var ss = SpreadsheetApp.getActive();
var sh = ss.getSheetByName(sheetName);
var vA = sh.getDataRange().getValues();
var hA = vA[0];
var hObj = {};
hA.forEach(function(e, i) {
hObj[e] = i;
});
var uA = [];
var d = 0;
for (var i = 0; i <= vA.length; i++) {
if (uA.indexOf(vA[i][hObj['key']]) == -1) {
uA.push(vA[i][hObj['key']]);
} else {
//sh.deleteRow(i + 1 - d++);
sh.deleteRow((parseInt(i)+1) - d);
d++;
}
}
};
But this one is deleting the newly added row, what I want to achieve is it should delete the old duplicate row instead. How can I do that?
In else part instead of using i which represent your current row, use the indexOf the row you want to delete. Delete it first and then push the new one into array
// This scripts works but deleting new data instead of old data
function removeDuplicates() {
var sheetName = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getName();
var ss = SpreadsheetApp.getActive();
var sh = ss.getSheetByName(sheetName);
var vA = sh.getDataRange().getValues();
var hA = vA[0];
var hObj = {};
hA.forEach(function(e, i) {
hObj[e] = i;
});
var uA = [];
var d = 0;
for (var i = 0; i <= vA.length; i++) {
if (uA.indexOf(vA[i][hObj['key']]) == -1) {
uA.push(vA[i][hObj['key']]);
} else {
//sh.deleteRow(i + 1 - d++);
let j = uA.indexOf(vA[i][hObj['key']]);
sh.deleteRow((parseInt(j)+1) - d);
d++;
uA.push(vA[i][hObj['key']]);
}
}
};
I am using Google Sheets and I have two functions onEdit and onCommsEdit that work great and add a timestamp to their respective sheets. If I copy and paste one of them exactly and give a new function name - the additional functionality will not seem to work.
Am I ordering things incorrectly? Or should I be naming all sheets in the same function? (I had created duplicates because the write to columns varied by the sheet.)
function onOpen() {
var sheet = SpreadsheetApp.getActiveSpreadsheet();
var entries = [{name:"Last Row", functionName:"goto_last"}];
sheet.addMenu("Shortcuts", entries);
myFunction();
};
function goto_last() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var mysheet = ss.getActiveSheet();
var lastrow = mysheet.getLastRow();
mysheet.setActiveCell(mysheet.getDataRange().offset(lastrow-1, 0, 1, 1));
};
function onEdit() {
var s = SpreadsheetApp.getActiveSheet();
if( s.getName() == "Primary Log" ) {
var r = s.getActiveCell();
var user = Session.getActiveUser().getEmail();
if( r.getColumn() != 13 ) { //checks the column
var row = r.getRow();
var time = new Date();
time = Utilities.formatDate(time, "GMT-08:00", "yyyy-MM-dd, hh:mm:ss");
SpreadsheetApp.getActiveSheet().getRange('M' + row.toString()).setValue(time);
SpreadsheetApp.getActiveSheet().getRange("N" + row.toString()).setValue(user);
}
};
};
function myFunction() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var mysheet = ss.getActiveSheet();
var lastrow = mysheet.getLastRow();
mysheet.setActiveCell(mysheet.getDataRange().offset(lastrow-1, 0, 1, 1));
};
function onCommsEdit() {
var s = SpreadsheetApp.getActiveSheet();
if( s.getName() == "Received Report" ) {
var r = s.getActiveCell();
var user = Session.getActiveUser().getEmail();
if( r.getColumn() != 11 ) { //checks the column
var row = r.getRow();
var time = new Date();
time = Utilities.formatDate(time, "GMT-08:00", "yyyy-MM-dd, hh:mm:ss");
SpreadsheetApp.getActiveSheet().getRange('K' + row.toString()).setValue(time);
SpreadsheetApp.getActiveSheet().getRange("L" + row.toString()).setValue(user);
}
};
};
You must create a trigger in order for a function to be called automatically.
It is not recommended to have multiple functions all called with an onEdit condition, as the execution order is not well defined. I also do not recommend naming a function that requires an installed trigger such that it matches the corresponding simple trigger -- in other words, a function that requires authorization scopes and is to be run after the spreadsheet values are modified should not be called onEdit(e), as that is the name of function which activates the simple trigger. If your function does not require authorization scopes, then you can use the simple trigger.
As far as your program design, you should use flow control. Rather than multiple functions, simply branching is sufficient:
function calledOnEdit(e) {
if(!e) { throw new Error("This function requires an event object"); }
// Use the event object rather than lookups that assume the active cell was the edited cell:
var s = e.range.getSheet();
var row = e.range.getRow();
var col = e.range.getColumn();
if( s.getName() == "Primary Log" && col != 13 ) { //checks the column
logTimestamp(s, "M" + row + ":N" + row);
} else if( s.getName() == "Received Report" && col != 11 ) { //checks the column
logTimestamp(s, "K" + row + ":L" + row);
}
}
function logTimestamp(sheet, a1ref) {
var user = Session.getActiveUser().getEmail();
var time = Utilities.formatDate(new Date(), "GMT-08:00", "yyyy-MM-dd, hh:mm:ss");
sheet.getRange(a1ref).setValues([[time, user]]);
}
I have the following script
function scraper() {
var url = 'http://gpa.shet.com.aspx';
var sss = SpreadsheetApp.getActiveSpreadsheet();
//var ss = SpreadsheetApp.openById('1im78ip4Wcmb1xbfZs8Lqy3-LP1SU9rC8E5OfKbOjJDg');
//var sss = SpreadsheetApp.setActiveSpreadsheet(ss);
var sheet = sss.getSheetByName("Sheet1");
var rows = sheet.getDataRange();
var numRows = rows.getNumRows();
var response = UrlFetchApp.fetch(url);
var contentText = response.getContentText();
var pr = sheet.getRange('A1:Z1000');
var cstring = contentText.tostring;
var ui = SpreadsheetApp.getUi();
var NHL = "New Agent";
var nlength = contentText.length;
// ui.alert(nlength);
//ui.alert(contentText);
//var g = 5;
var clength = 200000;
///
var temp = contentText;
var count = (temp.match(/New Hot Lead/g) || []).length;
var C6 = sheet.getRange('C6');
var C8 = sheet.getRange('C8');
var C10 = sheet.getRange('C10').getValue();
var C10r = sheet.getRange('C10');
if (count > 0) {
var d = new Date();
var hrs = d.getHours();
var mins = d.getMinutes();
var time1 = hrs + ":" + mins;
if (C6.isBlank() == true) {
C6.setValue(time1);
} else if (C6.isBlank() == false) {
C8.setValue(time1);
}
}
if (count == 0) {
C6.clear();
C8.clear();
}
var time2 = 0.00347222222222222;
if (C10 >= time2) {
var D10 = sheet.getRange("D10");
var alert = "NHLs for more than 5 minutes!";
D10.setValue(alert);
D10.setFontColor('Red');
}
}
Now, the problem is not the code itself, since when I run it manually it does work the way it's expected. My problem is with the time-driven trigger. I have tried to manually set it for every minute, and to add the triggerbuilder code at the end and outside of the function, but it still won't work. What are some suggestions?
Try using the sleep function for 60 seconds.
sleep(60000);