How to limit the information sent in the CSV (Google Sheets)? - google-sheets

I used the script below to create a submit order button which emails the current sheet as a CSV and then clears range I6:I. How can I update it so that only items with a response in range I6:I are included in the CSV? I don't want the CSV to include anything if I6:I is empty. I know the code isn't very clean. I'm new to this. Any help would be really appreciated.
function SUBMIT_ORDER() {
SpreadSheetId = SpreadsheetApp.getActiveSpreadsheet().getId();
SheetId = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getSheetId();
var today = new Date();
var date = today.getFullYear()+'-'+(today.getMonth()+1)+'-'+today.getDate();
var time = today.getHours() + ":" + today.getMinutes() + ":" + today.getSeconds();
var dateTime = date+' '+time;
var actualSheetName = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getName();
var recipients = "EMAILADDRESS"; 
var ssID = SpreadsheetApp.getActiveSpreadsheet().getId();
var sheetName = SpreadsheetApp.getActiveSpreadsheet().getName();
var email = Session.getActiveUser().getEmail();
var subject = "BMVS " +actualSheetName+ " New Purchase Order " +dateTime ;
var body = email+ " submitted a new purchase order for " +actualSheetName+ " on " +date+ " at " +time+ " ****THANK YOU****";
var requestData = {"method": "GET", "headers":{"Authorization":"Bearer "+ScriptApp.getOAuthToken()}};
var url = 'https://docs.google.com/spreadsheets/d/' + SpreadSheetId + "/export?format=csv&gid=" + SheetId;
var result = UrlFetchApp.fetch(url, requestData);
var contents = result.getContent();
RESET_QUANTITIES = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet()
MailApp.sendEmail(recipients, subject, body, {attachments:[{fileName:actualSheetName+'-'+dateTime+ ".csv", content:contents, mimeType:"application//csv"}]});
RESET_QUANTITIES.getRange("i6:i").clearContent();
var spreadsheet = SpreadsheetApp.getActive();
var sheet = spreadsheet.getActiveSheet();
sheet.getRange(1, 1, sheet.getMaxRows(), sheet.getMaxColumns()).activate();
spreadsheet.setCurrentCell(spreadsheet.getRange('E1'));
}

solution by script
Try
var contents = result.getContentText().split('\n').filter(r => (r.split(',')[8] != '')).join('\n')
instead of var contents = result.getContent();
solution by query
apply in a new tab
=query('Feuille 1'!A:J,"select * where I is not null",1)

Related

Print a certain range of a Google Spreadsheet using a script

I would like to create a button to print just a certain range of a Google Spreadsheet. I am playing arroud with .getRangeByName class but it wont work. Maybe someone can help me with some ideas?
I am playing arround with some code I found here on stackoverflow.
I am just stuck by replacing the columns and rows by a certain range name or namedRange.
All in all the result of the script below works fine for me so far.
Thanks and Regards!
function printPdf() {
SpreadsheetApp.flush();
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var gid = sheet.getSheetId();
var pdfOpts = '&size=A4&fzr=false&portrait=false&fitw=true&gridlines=false&printtitle=false&sheetnames=false&pagenum=UNDEFINED&attachment=false&gid='+gid;
var last_row = sheet.getLastRow(); var printRange = '&c1=0' + '&r1=0' + '&c2=34' + '&r2='+last_row // B2:APn var url = ss.getUrl().replace(/edit$/, '') + 'export?format=pdf' + pdfOpts + printRange;
var app = UiApp.createApplication().setWidth(200).setHeight(50);
app.setTitle('Verze pro tisk');
var link = app.createAnchor('Zobrazit PDF', url).setTarget('_new');
app.add(link);
ss.show(app);
}

How to parse Gmail messages to extract data to Google Sheets

I'm working on a R&D project where I collect my server side statistics using Linux commands and output the same to my mail. Now my plan is to read and parse the Gmail content which has my data of the server (as below) and extract it to Google Sheets. My Gmail content looks like below which has data in rows and columns.
Date&Time JVM PID CPU MEM FGC
03-09-2017-09-08-PM abc01_xzy01 12345 1.2% 2.75 3
03-09-2017-09-08-PM abc01_xzy01 12345 3.5% 2.71 4
03-09-2017-09-08-PM abc01_xzy01 12345 4.6% 2.79 5
My idea here is to pull exactly the same way into a Google Sheet. I'm using the below code but it's unable to read the content. I'm thinking if it's related to the RegExp used. Could you please tell me how exactly the code has to be written in the if statement.
function parseEmailMessages(start) {
start = start || 0;
var threads = GmailApp.getInboxThreads(start, 100);
var sheet = SpreadsheetApp.getActiveSheet();
for (var i = 0; i < threads.length; i++) {
var tmp,
message = threads[i].getMessages()[0],
// subject = message.getSubject(),
subject = "SERVER TEST REPORT",
content = message.getPlainBody();
if (content) {
tmp = content.match(/Date&Time:\s*([A-Za-z0-9\s]+)(\r?\n)/);
var username = (tmp && tmp[1]) ? tmp[1].trim() : 'No Date & Time';
tmp = content.match(/JVM:\s*([A-Za-z0-9\s]+)(\r?\n)/);
var username = (tmp && tmp[1]) ? tmp[1].trim() : 'No JVM';
sheet.appendRow([username, email, subject, comment]);
}
}
}
My output just prints No Date & Time and No JVM in the Google Sheets. I want to print the names and data in the columns and rows as given in the mail. Can someone please help me on this and tell me what is the mistake and how to pull the data like expected. Thanks in advance.
If all that is in your email is what you posted above, this will put it in your spreadsheet. Change the email subject and sheet name to suit your needs.
function getGmail() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var threads = GmailApp.search('IMPORTANT1', 0, 10);
for (var i = 0; i < threads.length; i++) {
var messages = GmailApp.getMessagesForThread(threads[i]);
for (var j = 0; j < messages.length; j++) {
var msg=messages[j].getPlainBody();
var msg=msg.trim()
}
}
result1(msg)
}
function result1(range) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet1 = ss.getSheetByName("Sheet1")
var lr=sheet1.getLastRow()
var output=[]
var line=range.split("\n")
for(j=0;j<line.length;j++){
output.push(line[j].split(" "))
}
sheet1.getRange(lr+1, 1, output.length, output[0].length).setValues(output)
}

How to make TODAY function static with a script

I have a cell that needs to lock the day when something is approved. I have tried many formulas, but this might need a script.
This is the formula:
=IF(R17=0, TODAY())
Link to file
Thank you in advance for the help!
It does require script. This will freeze the date when approved.
function onEdit(e){
var sheet = e.source.getActiveSheet().getName()
var editRow=e.range.getSheet().getActiveCell().getRow()
var editColumn=e.range.getSheet().getActiveCell().getColumn()
var ss = SpreadsheetApp.getActiveSpreadsheet()
var s=ss.getSheetByName("Show Management")//get sheet by name
var Ap=s.getRange(editRow,11,1,1).getValue()
if(sheet!="Show Management"){return}
if(editColumn==11 && editRow>=12 && Ap=="Approved"){
var d=s.getRange(editRow,27.1,1).getValue().toString()
if(d="[object Date]"){
var cpy=s.getRange(editRow,27 ,1, 1).getDisplayValue()
var cpyVal=s.getRange(editRow,27 ,1, 1).setValue(cpy)
}
}}
Here is my shared test spreadsheet:
https://docs.google.com/spreadsheets/d/1qIfVfLTOpjOHaOP8_1_I3B8uteBCX-yj-TjxkGkTv1c/edit?usp=sharing

run onedit on active sheet

I have looked for an answer for this question, but I am exceptionally green to even rudimentary scripting so I have not been able to understand what I have found.
I have a spreadsheet we are using for a worklist - it is separated into three tabs: Samples / Images / Archive
Users access the spreadsheet to collect items to work - once it is complete they mark Column A as "Complete", and I have code very helpfully provided by ScampMichael to automatically move the row to the "Archive" sheet once they do so:
function onEdit(event) {
// assumes source data in sheet named Samples
// target sheet of move to named Archive
// test column with Completed is col 1 or A
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = event.source.getActiveSheet();
var r = event.source.getActiveRange();
if(s.getName() == "Samples" && r.getColumn() == 1 && r.getValue() == "Complete") {
var row = r.getRow();
var numColumns = s.getLastColumn();
var targetSheet = ss.getSheetByName("Archive");
var target = targetSheet.getRange(targetSheet.getLastRow() + 1, 1);
s.getRange(row, 1, 1, numColumns).moveTo(target);
s.deleteRow(row);
}
}
My challenge is that I can not get this code to work simultaneously for both the "Samples" and the "Images" tab. I gather that this is because you can not have more than one onEdit function per spreadsheet, but so far my efforts to expand the code to look at both tabs has failed.
Any help that can be provided is extremely appreciated!
It is still not exactly clear what you want to do, but I took a shot at it. I assumed the image is on the same row number as the completed row on samples and when copying the image to archive I append it to the end of the row created in the archive. I made some changes to your code. They are noted. If you need it, I can share my testing spreadsheet.
function onEdit(event) {
// assumes source data in sheet named Samples
// target sheet of move to named Archive
// test column with Completed is col 1 or A
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = event.source.getActiveSheet();
var r = event.source.getActiveRange();
if(s.getName() == "Samples" && r.getColumn() == 1 && r.getValue() ==
"Complete") {
var row = r.getRow();
var numColumns = s.getLastColumn();
var targetSheet = ss.getSheetByName("Archive");
var target = targetSheet.getRange(targetSheet.getLastRow() + 1, 1);
s.getRange(row, 1, 1, numColumns).moveTo(target);
s.deleteRow(row);//changed to delete the row
image(row,numColumns)//call function to process Images send row and last column
}}
function image(row,numColumns){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s1=ss.getSheetByName("Images")//get Images sheet
var lc=s1.getLastColumn()
var data=s1.getRange(row, 1, 1,lc)//get row
var targetSheet = ss.getSheetByName("Archive");
var target = targetSheet.getRange(targetSheet.getLastRow() , numColumns+1,1,1);//add image one column after Samples data on same row.
s1.getRange(row, 1, 1, lc).moveTo(target);
s1.deleteRow(row)//delete the copied image row.
}

Google sheets- loop search column, select tow

I have a google spreadsheet that i have one last problem i cant seem to solve.
i added a button to this script, and when i press the button it triggers the AddClient function.
How can i make the script below loop down all rows in column 3 searching for the yes value, when it finds it, copy the row below it to sheet "client" and then stop?
function AddClient(event) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = event.source.getActiveSheet();
var r = event.source.getActiveRange();
if(s.getName() == "SETUP" && r.getColumn() == 3 && r.getValue() == "yes") {
var row = r.getRow() + 1; // Add 1 to the active row
var targetSheet = ss.getSheetByName("client");
var target = targetSheet.getRange(targetSheet.getLastRow() + 1, 1);
s.getRange(row, 2, 1, 4).copyTo(target, {contentsOnly:true}); //Only selecting column 2, then the following 4 columns
}
}
Edit*
Example document:
https://docs.google.com/spreadsheets/d/1DFbAp0IN8_UFv9u8kWiZBTxDogj4e7FnuAPzC0grDw0/edit?usp=sharing
Any help greatly appreciated!
Cheers,
Reiel
Since you have a static form the position of the informatin to be copied will not change
Since we know we want to copy over the data we won't need to do any validation of where we are so all of that stuff can go
Sheets have an appendRow method that take care of the bookkeeping involved with finding the last row
This allows us to simplify the script to the following:
function AddClient() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var data = ss.getSheetByName("SETUP").getRange(25, 2, 1, 4).getValues()[0];
ss.getSheetByName("client").appendRow(data);
}
Edit:
To remove duplicates you could do the following:
function AddClient() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var data = ss.getSheetByName("SETUP").getRange(25, 2, 1, 4).getValues()[0];
var clients = ss.getSheetByName("client").getDataRange().getValues();
if (!clients.filter(function(row) {return data.join("|") === row.join("|");})) {
ss.getSheetByName("client").appendRow(data);
}
}
Note that for the particular example there are some problems because the leading zero gets cut off. Sheets is a bit weird and sometimes tries to force the format to be a number even when you set the cells' formats to Text...

Resources