google app script copy values !=0 into new column - javascript

I am trying to copy cells with the value 0 into another cell. Can't seem to get the if statement to work.
function pushGeo()
{
var ssA = SpreadsheetApp.openById('###')
var ss = ssA.getSheetByName('thissheet');
var lastRow = ss.getLastRow();
for(var row=2;row<=lastRow;row++)
{
if(ss.getRange('G'+row).getValue() != 0){
var source = ss.getRange('G2:G'+lastRow);
var destination = ss.getRange('N2:N'+lastRow);
source.copyTo(destination);
}
}
Right now it's copying all cells into the new column.
==
Ah, nevermind. I was silly with the range. Time to stop coding for the day.
function pushGeo()
{
for(var row=2;row<=lastRow;row++)
{
if(ss.getRange('G'+row).getValue() != 0){
var source = ss.getRange('G'+row);
var destination = ss.getRange('N'+row);
source.copyTo(destination);
}
}

Ah, nevermind. I was silly with the range. Time to stop coding for the day.
function pushGeo()
{
for(var row=2;row<=lastRow;row++)
{
if(ss.getRange('G'+row).getValue() != 0){
var source = ss.getRange('G'+row);
var destination = ss.getRange('N'+row);
source.copyTo(destination);
}
}

Related

Copy values to next column(if blank) in the same row. If not blank, copy to the second column(if blank) in same row. Repeat

Disclaimer: Im very new to google scripts. I jumbled together this code with mixed success.
When I run the script, it works fine with the first two attempts. Then it doesnt work after that because column Q now has values in other cells within the column and the script is technically correct but not running at intended. I need to ignore column Q cells that are not blank and still run the script to copy P values to the other cells in column Q.
Also, when column Q with in the same row is not blank, I need to copy the value from column P to column R (if blank). Rinse and Repeat script...
function copyVals () {
var ss = SpreadsheetApp.getActiveSpreadsheet ();
var source = ss.getRange ("Sheet1!P2:P");
var destSheet = ss.getSheetByName("Sheet1");
var destRange = destSheet.getRange('Q2:Q')
var destRange2 = destSheet.getRange('R2:R')
if (destRange.isBlank()) {
source.copyTo (destRange, {contentsOnly: true});
source.clear ();
}
if (destRange2.isBlank()) {
source.copyTo (destRange2, {contentsOnly: true});
source.clear ();
}
}
You need to do the blank check for each cell separately
However, if you do it wiht the Apps Script method isBlank() - this will make your code a bit slow.
I suggest you to
retreive the existing values both in the source and destination ranges with getValues
check for each of the destinations values either those are empty and replace the empty values through source values
assign the modified values back to the sheet with setValues
Sample code:
function copyVals () {
var ss = SpreadsheetApp.getActiveSpreadsheet ()
var sheet = ss.getSheetByName("Sheet1")
var lastRow = sheet.getLastRow()
var source = sheet.getRange ("P2:P" + lastRow)
var destSheet = sheet
var destRange = destSheet.getRange('Q2:Q' + lastRow)
var destRange2 = destSheet.getRange('R2:R' + lastRow)
var sourceValues = source.getValues().flat()
var destValues = destRange.getValues()
var dest2Values = destRange2.getValues()
sourceValues.forEach(function(value, i){
console.log("i" + i)
if (destValues[i][0] == "") {
destValues[i][0] = value
}
if (dest2Values[i][0] == "") {
dest2Values[i][0] = value
}
})
destRange.setValues(destValues)
destRange2.setValues(dest2Values)
source.clear ();
}
UPDATE
If you want to copy to column Q and R alternately, you can use script properties to save the run count of the script and execute different code blocks for odd and even number.
Sample:
function copyVals () {
var ss = SpreadsheetApp.getActiveSpreadsheet ()
var sheet = ss.getSheetByName("Sheet1")
var lastRow = sheet.getLastRow()
var source = sheet.getRange ("P2:P" + lastRow)
var destSheet = sheet
var destRange = destSheet.getRange('Q2:Q' + lastRow)
var destRange2 = destSheet.getRange('R2:R' + lastRow)
var sourceValues = source.getValues().flat()
var destValues = destRange.getValues()
var dest2Values = destRange2.getValues()
var scriptProperties = PropertiesService.getScriptProperties()
var myProperty = scriptProperties.getProperty('timesCalled')
if (!myProperty){
myProperty = "1"
}
myProperty = JSON.parse(myProperty)
var isOdd = myProperty % 2
if(isOdd){
sourceValues.forEach(function(value, i){
console.log("i" + i)
if (destValues[i][0] == "") {
destValues[i][0] = value
}
})
destRange.setValues(destValues)
} else{
sourceValues.forEach(function(value, i){
if (dest2Values[i][0] == "") {
dest2Values[i][0] = value
}
})
destRange2.setValues(dest2Values)
}
source.clear ()
myProperty++
scriptProperties.setProperty('timesCalled', JSON.stringify(myProperty))
}

How to solve a problem time expired in javasrcipt

I am trying to send data to Google Sheet in my mobile application.
The data arrives well but the code does not return the result quickly
here is my JavaScript code.
The problem is that it takes a long time (around 360s) to return the result
it's ok
var ss = SpreadsheetApp.openByUrl("https://docs.google.com/spreadsheets/d/177kUZc61U8huVsq2OcGsiF2OGdPCSxMjkoh2C4KIWPM/edit#gid=0");
var sheet = ss.getSheetByName('Info');
function doGet(e) {
var action = e.parameter.action;
if (action == 'UpdateInfo') {
//return UpdateInfo(e);
}
}
function doPost(e) {
var action = e.parameter.action;
if (action == 'UpdateInfo') {
return UpdateInfo(e);
}
}
function UpdateInfo(e) {
var values = sheet.getRange(2, 1, sheet.getLastRow(), sheet.getLastColumn()).getValues();
var email = e.parameter.email;
var password = e.parameter.password;
//var date = sheet.getRange('A').getValues();//new Date();
var name = e.parameter.name; ///Item1
var lname = e.parameter.lname;
var itemuserImage = e.parameter.itemuserImage;
var region = e.parameter.region;
var provaince = e.parameter.provaince;
var ecole = e.parameter.ecole;
var Unite = e.parameter.unite;
var niveau = e.parameter.niveau;
//var flag = 0;
var lr = sheet.getLastRow();
for (var i = 1; i <= lr; i++) {
var IDuser = sheet.getRange(i, 1).getValue();
//row[1];
var shetemail=sheet.getRange(i,2).getValue();
var shetpassword=sheet.getRange(i,3).getValue();
if (shetpassword==password && shetemail==email ) {
sheet.getRange(i,4).setValue(name);
// sheet.getRange(i,5).setValue(lname);
//row[2];
///zoydghnmayad sheet.getRange(i,7).setValue(region);
//row[4];
sheet.getRange(i,8).setValue(provaince);
//row[5];
sheet.getRange(i,9).setValue(ecole);
//row[5];
sheet.getRange(i,10).setValue(Unite);
//row[5];
sheet.getRange(i,11).setValue(niveau);
//row[5];
var dropbox="USERSIMAGE prof";
var folder, folders=DriveApp.getFoldersByName(dropbox);
if (folders.hasNext()) {
folder=folders.next();
} else {
folder=DriveApp.createFolder(dropbox);
}
var fileName=IDuser+"profile_pic.jpg";
var contentType="image/jpg" , bytes=Utilities.base64Decode(itemuserImage), blob=Utilities.newBlob(bytes, contentType,fileName);
var file=folder.createFile(blob);
file.setSharing(DriveApp.Access.ANYONE_WITH_LINK,DriveApp.Permission.VIEW);
var fileIdumage=file.getId();
var fileUrlumage="https://drive.google.com/uc?export=view&id=" +fileIdumage; sheet.getRange(i,6).setValue(fileUrlumage);
//row[5];
return ContentService.createTextOutput("its ok").setMimeType(ContentService.MimeType.TEXT);
}
} ///thiya loop
}
Not quite sure.But do you check your image size of "profile_pic.jpg".
In my experience,if you capture the profile image using mobile app camera,the image size is extremely large.It will take ages to upload the image if you forget to compress it(no need such high HD image for profile, and compression is neccesary).
As a matter of that,please double check size of the image you were uploading.And please do not forget to compress it if it occupy too much space.

Prevent google script from duplicating protected ranges

I have this script that I am using to copy over (convert formulas to values) and then protect the range when a user enters a value "Burned" in to a certain cell (A2, A6, etc) at the end of each month (can't make it triggered by date as users may be completing data entry on slightly different dates). The spreadsheet needs users to lock the data every month, so the script is set up for converting and protecting data each month as the user enters "Burned" into each month. The script is working well to convert formulas to values and it is also working to protect the range. However, every time I edit the sheet, it creates duplicate protected ranges so I end up with multiple protected ranges called January Burned, February Burned, etc. Is there any way to prevent the script from duplicating the protected ranges? Any help is greatly appreciated.
function onEdit(e)
//January
{
var ss = SpreadsheetApp.getActive();
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Caseload");
var valueToCheckA = sheet.getRange("A2").getValue();
var rangeA = sheet.getRange("A2:AZ5");
{
if(valueToCheckA == "Burned")
{
rangeA.copyTo(rangeA, {contentsOnly:true});
var protection = rangeA.protect().setWarningOnly(true).setDescription('January Burned');
}
}
}
//February
{
var ss = SpreadsheetApp.getActive();
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Caseload");
var valueToCheckB = sheet.getRange("A6").getValue();
var rangeB = sheet.getRange("A6:AZ9");
{
if(valueToCheckB == "Burned")
{
rangeB.copyTo(rangeB, {contentsOnly:true});
var protection = rangeB.protect().setWarningOnly(true).setDescription('February Burned');
}
}
}
//March
{
var ss = SpreadsheetApp.getActive();
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Caseload");
var valueToCheckC = sheet.getRange("A10").getValue();
var rangeC = sheet.getRange("A10:AZ13");
{
if(valueToCheckC == "Burned")
{
rangeC.copyTo(rangeC, {contentsOnly:true});
var protection = rangeC.protect().setWarningOnly(true).setDescription('March Burned');
}
}
}
You had some weird things going on in your code. So I'd reformat it like this:
//January
function onEdit(e)
{
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Caseload");
var valueToCheckA = sheet.getRange("A2").getValue();
var rangeA = sheet.getRange("A2:AZ5");
if(valueToCheckA == "Burned")
{
rangeA.copyTo(rangeA, {contentsOnly:true});
var protection = rangeA.protect().setWarningOnly(true).setDescription('January Burned');
}
}
Try it again and let me know if anything has changed.
After looking over you code again. I grabbed entire code and took a close look at it and I made an interesting discovery. Several of your sections of code are not within the function onEdit so they run every time you access your scripts even when onEdit is not called. In fact, when I think about it, I believe you just run this once a month so why not just put it in a separate function and call once a month and forget the onEdit trigger.
function onEdit(e)
{
var ss = SpreadsheetApp.getActive();//January
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Caseload");
var valueToCheckA = sheet.getRange("A2").getValue();
var rangeA = sheet.getRange("A2:AZ5");
if(valueToCheckA == "Burned")
{
rangeA.copyTo(rangeA, {contentsOnly:true});
var protection = rangeA.protect().setWarningOnly(true).setDescription('January Burned');
}
}
// This section is not in the onEdit function so it's run every time you come to this page
var ss = SpreadsheetApp.getActive();//February
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Caseload");
var valueToCheckB = sheet.getRange("A6").getValue();
var rangeB = sheet.getRange("A6:AZ9");
if(valueToCheckB == "Burned")
{
rangeB.copyTo(rangeB, {contentsOnly:true});
var protection = rangeB.protect().setWarningOnly(true).setDescription('February Burned');
}
// This section is not in the onEdit function so it's run every time you come to this page
var ss = SpreadsheetApp.getActive();//March
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Caseload");
var valueToCheckC = sheet.getRange("A10").getValue();
var rangeC = sheet.getRange("A10:AZ13");
if(valueToCheckC == "Burned")
{
rangeC.copyTo(rangeC, {contentsOnly:true});
var protection = rangeC.protect().setWarningOnly(true).setDescription('March Burned');
}
So here's a rough start of a function that could do the job for you and you can just run it once a month. I haven't tested it and it most likely has some mistakes in it so check it out.
function monthlyBurn()
{
var ui = SpreadsheetApp.getUi();
var response = ui.prompt('Enter checkCell,protectRange,description all separate by commas', ui.ButtonSet.OK);
var t = response.getResponseText().split(',');
if(t.length !== 3)
{
ui.alert('Invalid input. Your missing a parameter')
return;
}
var ss = SpreadsheetApp.getActive();
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Caseload");
var valueToCheckC = sheet.getRange(t[0]).getValue();
var rangeC = sheet.getRange(t[1]);
if(valueToCheckC == "Burned")
{
rangeC.copyTo(rangeC, {contentsOnly:true});
var protection = rangeC.protect().setWarningOnly(true).setDescription(t[2]);
}
}
Thanks for all the input and assistance, I have spoken with a colleague who was able to write this script which is working great.
function onEdit(e)
{
var sheet = e.range.getSheet();
if (sheet.getName() != "Caseload" || e.value != "Burned") return;
var moment = Moment.load();
var date = moment.utc(e.range.offset(0, 1).getValue());
if (!date.isValid()) return;
var month = date.format('MMMM');
var range = sheet.getRange(e.range.getRow(), e.range.getColumn(), 4, 26*2); // 4 rows and 26*2 columns (AZ)
range.copyTo(range, {contentsOnly: true});
range.protect().setWarningOnly(true).setDescription(month + ' Burned');

sending data from a google spreadsheet program to google calender

Here is my case.
A user fills a form for event booking, the submitted form is stored in a google spreadsheet which I have synced to a google calender so that it automatically sends the data to it.
Everything is working fine apart from the fact that event times could clash.
When customers book an event centre for let's say on 13/3/2015 T 10:00AM, if another user enters the same date and time, the entry should not be accepted.
To summarise it, I want to avoid a clash of events booking. Thank you all.
here is my script.
var calendarId = "mycalenderid";
//below are the column ids of that represents the values used in the spreadsheet (these are non zero indexed)
var startDtId = 9;
var endDtId = 10;
var titleId = 6;
var descId = 11;
var formTimeStampId = 1;
function getLatestAndSubmitToCalendar() {
var sheet = SpreadsheetApp.getActiveSheet();
var rows = sheet.getDataRange();
var numRows = rows.getNumRows();
var values = rows.getValues();
var lr = rows.getLastRow();
var startDt = sheet.getRange(lr,startDtId,1,1).getValue();
//set to first hour and minute of the day.
//startDt.setHours(0);
//startDt.setMinutes(00);
var endDt = sheet.getRange(lr,endDtId,1,1).getValue();
//set endDt to last hour and minute of the day
//endDt.setHours(23);
//endDt.setMinutes(59);
var subOn = "Submitted on:"+sheet.getRange(lr,formTimeStampId,1,1).getValue();
var desc = "Added by :"+sheet.getRange(lr,descId,1,1).getValue()+"\n"+subOn;
var title = sheet.getRange(lr,titleId,1,1).getValue()+"DIA";
createEvent(calendarId,title,startDt,endDt,desc);
}
function createEvent(calendarId,title,startDt,endDt,desc) {
var cal = CalendarApp.getCalendarById(calendarId);
var start = new Date(startDt);
var end = new Date(endDt);
var loc = 'Script Center';
var event = cal.createEvent(title, start, end, {
description : desc,
location : loc
});
};
Here's a pseudocode of what you're trying to do:
function findEvent(desiredDateTime)
{
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("Sheet1");
var range = sheet.getDataRange();
var data = range.getValues();
var lRow = range.getLastRow();
var flag = true;
var count = 0;
while (flag == true || count < lRow)
{
if (desiredDateTime >= data[count][startDtId] && desiredDateTime <= data[count][endDtId])
{
flag = false;
}
else
{
count++;
}
}
if (flag == true)
{
//Call function to add event
}else{
//Tell user desired date-time is not available.
//If you're asking for user's email address,
//simplest approach would be to send an email.
}
}
You might have to modify other bits and pieces of your code as well to accommodate this but it shouldn't be too hard. Hope this provides you with a certain direction to follow through.

Compare value to another spreadsheet using array loop and write new values

Hello all I'm having trouble implementing array loops in my project... Here is what I want to do.
I have a spreadsheet called "Red Book" this sheet gets updated regularly once the staff have updated it I have a column where they can select to submit the data they've just entered on that specific row (editing this column calls an onEdit function).
The data will then be written to another spreadsheet (different file) called "Raw Data"
For each submit I have a unique identifier. I need the onEdit code to do the following...
Iterate through the column A to find the unique identifier
Once found update the data in columns 1 through 5
Below is the script I have so far:
function TransferToAppData(e) {
var destFile = SpreadsheetApp.openById('xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx');
var destSheet = destFile.getSheetByName("Raw App Data");
var ss = e.source;
var s = ss.getActiveSheet();
var uniConstRng = s.getRange("A1");
var uniqueConstVal = uniConstRng.getValue();
var NextOpenRow = destSheet.getLastRow() + 1;
var ActiveRow = e.range.getRow();
Logger.log(ActiveRow);
var uniqueVal = s.getRange(ActiveRow,1).getValue();
var add = s.getRange(ActiveRow,2).getValue();
var name = s.getRange(ActiveRow,3).getValue();
var dt = s.getRange(ActiveRow,5).getValue()
if (uniqueVal == "") {
s.getRange(ActiveRow,1).setValue(uniqueVal + 1);
uniConstRng.setValue(uniqueVal + 1);
var transferVals = s.getRange(ActiveRow,1,1,5).getValues();
Logger.log(transferVals);
destSheet.getRange(NextOpenRow,1,1,5).setValues(transferVals);
destSheet.getRange(NextOpenRow, 6).setValue("Applicant");
}
else {
var destLastRow = destSheet.getLastRow();
var destDataRng = destSheet.getRange(2,1,destLastRow,5)
var destValues = destDataRng.getValues();
var sourceValues = s.getRange(ActiveRow,1,1,5).getValues();
for( var i = 0; i < destValues.length; ++i){
if (destValues([i][0])==uniqueVal) {
for(n=0;n<destValues[0].length;++n){
///I"m stuck!!!
}
}
}
}
}
As you can see I have the first array loop going, but I'm having trouble figuring out how to do a second loop that iterates only on the row where the unique value is found and write the source data to ONLY to row where the unique value was found not the whole sheet.
I figured it out...
Below is the code and here is how it works...
When values in certain columns are edited this code is fired.
1--It finds the unique identifier located in the row which was edited.
2--Compares that identifier with a column of unique identifiers in another spreadsheet.
3--When a match is found it writes the change to the new spreadsheet and exits the loop
function TransferToAppData(e) {
var destFile = SpreadsheetApp.openById('1V3R2RnpA8yXmz_JDZSkBsK9tGR2LjHZp52p5I1CuQvw');
var destSheet = destFile.getSheetByName("Raw App Data");
var ss = e.source;
var s = ss.getActiveSheet();
var uniqueConstRng = s.getRange("A1");
var uniqueConstVal = uniqueConstRng.getValue();
var NextOpenRow = destSheet.getLastRow() + 1;
var ActiveRow = e.range.getRow();
var uniqueVal = s.getRange(ActiveRow,1).getValue();
if (s.getRange(ActiveRow,2).getValue() == "" || s.getRange(ActiveRow,3).getValue()=="" || s.getRange(ActiveRow,4).getValue()=="" || s.getRange(ActiveRow,5).getValue()=="") {
s.getRange(ActiveRow,13).clearContent();
Browser.msgBox("Address, Name, Date Entered & Rent are required fields!");
} else{
if (uniqueVal == "") {
s.getRange(ActiveRow,1).setValue(uniqueConstVal + 1);
uniqueConstRng.setValue(uniqueConstVal + 1);
var transferVals = s.getSheetValues(ActiveRow,1,1,5);
destSheet.getRange(NextOpenRow,1,1,5).setValues(transferVals);
destSheet.getRange(NextOpenRow, 6).setValue("Applicant");
}
else {
var destLastRow = destSheet.getLastRow();
var destValues = destSheet.getSheetValues(2,1,destLastRow,5);
var sourceValues = s.getSheetValues(ActiveRow,1,1,5);
for(var i = 0; i < destValues.length; ++i){
if (destValues[i][0]===uniqueVal) {
destSheet.getRange(i+2,1,1,5).setValues(sourceValues);
break;
}
}
}
s.sort(1,false);
destSheet.sort(1,false);
}
}

Categories

Resources