I have a Google AdWords script that is taking yesterdays cumulative spend (filtered) and inputting the value into a Google Sheet row. The logic I have in place is tested and works correctly, but when I try to replicate the logic for a different filter condition the value that is passed back for the replicated logic comes back with a value of 0. I believe the issues has to do with my .withCondition filter logic, but it looks correct to me.
Adwords Script:
function main() {
var sheet = SpreadsheetApp.openByUrl("https://docs.google.com/spreadsheets/d/1kKPwvazsT9YOfL5swKRkjHYAdUtetetetetetet/edit#gid=0").getActiveSheet();
var emptyRow = findEmptyRow(sheet);
var yesterday = new Date(new Date()-1);
var range = sheet.getRange(emptyRow + 1, 1, 1, 10);
var row = range.getValues();
var campaignIteratorPaidSearch = AdWordsApp.campaigns().withCondition("Name NOT_IN ['Remarketing', 'GSP', 'YouTube'] ").forDateRange('YESTERDAY').get();
var campaignIteratorDisplay = AdWordsApp.campaigns().withCondition("Name IN ['Remarketing', 'GSP', 'YouTube'] ").forDateRange('YESTERDAY').get();
var totalPaidSearchCost = 0;
var totalDisplayCost = 0;
var date = new Date();
date.setDate(date.getDate() - 1);
//Paid Search Spend
while (campaignIteratorPaidSearch.hasNext()) {
var campaignStats = campaignIteratorPaidSearch.next();
var stats = campaignStats.getStatsFor('YESTERDAY');
totalPaidSearchCost += stats.getCost();
}
//Display Spend
while (campaignIteratorDisplay.hasNext()) {
var displayCampaignStats = campaignIteratorDisplay.next();
var displayStats = displayCampaignStats.getStatsFor('YESTERDAY');
totalDisplayCost += displayStats.getCost();
}
row[0][0] = date;
row[0][1] = totalPaidSearchCost;
row[0][2] = totalDisplayCost;
range.setValues(row);
}
function findEmptyRow(sheet) {
var dates = sheet.getRange(1, 1, 365, 1).getValues();
for (var emptyDate = 0; emptyDate < dates.length; emptyDate++) {
if (dates[emptyDate][0].length == 0) {
return emptyDate;
}
}
}
The campaign name is a String so you can not use NOT_IN and IN operators, you should use:
= != STARTS_WITH STARTS_WITH_IGNORE_CASE CONTAINS CONTAINS_IGNORE_CASE DOES_NOT_CONTAIN DOES_NOT_CONTAIN_IGNORE_CASE
https://developers.google.com/adwords/scripts/docs/reference/adwordsapp/adwordsapp_campaignselector#withCondition_1
Related
The code below is overwriting on the existing data.
#OMila helped me with the original code, I could not articulate exactly what I needed hence starting a new question.
function Dom() {
var origin_sheet = SpreadsheetApp.getActive().getSheetByName('Dom_Sum');
var firstRow = 1;
var firstCol = 1;
var numRows = origin_sheet.getLastRow();
var numCols = 22;
var origin_values = origin_sheet.getRange(firstRow, firstCol, numRows, numCols).getValues();
var dest_values = [];
for(var i = 0; i < origin_values.length; i++) {
if(origin_values[i][0] != '') {
dest_values.push(origin_values[i]);
}
}
var dest_id = "1ZGq7L7bvF1INuDgZxhHnVsihkYkYubmncSAE5uC-Pq4";
var dest_sheet = SpreadsheetApp.openById(dest_id).getSheetByName("Master_Db");
var numRowsDest = dest_values.length;
var dest_range = dest_sheet.getRange(1, 1, numRowsDest, 22);
dest_range.setValues(dest_values);
}
I would like to add the data created in the "Dom_Sum" worksheet below the last row of data in the other workbook with the worksheet name "Master_Db"
#OMila I'm really grateful to you, and if you like we could offer you a consultation fee for future projects. (boseav#gmail.com)
Instead of writing your value into the range dest_sheet.getRange(1, 1, numRowsDest, numCols)
retrieve the last row of your destination sheet and write starting with the next row
var destLastRow=dest_sheet.getLastRow();
var dest_range = dest_sheet.getRange(destLastRow+1, 1, numRowsDest, numCols);
dest_range.setValues(dest_values);
The code below is overwriting on the existing data.
#OMila helped me with the original code, I could not articulate exactly what I needed hence starting a new question.
function Dom() {
var origin_sheet = SpreadsheetApp.getActive().getSheetByName('Dom_Sum');
var firstRow = 1;
var firstCol = 1;
var numRows = origin_sheet.getLastRow();
var numCols = 22;
var origin_values = origin_sheet.getRange(firstRow, firstCol, numRows, numCols).getValues();
var dest_values = [];
for(var i = 0; i < origin_values.length; i++) {
if(origin_values[i][0] != '') {
dest_values.push(origin_values[i]);
}
}
var dest_id = "1ZGq7L7bvF1INuDgZxhHnVsihkYkYubmncSAE5uC-Pq4";
var dest_sheet = SpreadsheetApp.openById(dest_id).getSheetByName("Master_Db");
var numRowsDest = dest_values.length;
var dest_range = dest_sheet.getRange(1, 1, numRowsDest, 22);
dest_range.setValues(dest_values);
}
I would like to add the data created in the "Dom_Sum" worksheet below the last row of data in the other workbook with the worksheet name "Master_Db"
#OMila I'm really grateful to you, and if you like we could offer you a consultation fee for future projects. (boseav#gmail.com)
Instead of writing your value into the range dest_sheet.getRange(1, 1, numRowsDest, numCols)
retrieve the last row of your destination sheet and write starting with the next row
var destLastRow=dest_sheet.getLastRow();
var dest_range = dest_sheet.getRange(destLastRow+1, 1, numRowsDest, numCols);
dest_range.setValues(dest_values);
I have a script that runs in a google sheet that parses emails and creates new lines in the sheet. This is used to create a log file from periodically emailed log updates. This works very well.
Currently, I have a variable that is used to determine which emails are ingested based on the month (0=January, etc.)
That variable has to be adjusted every month and then I have to create a new monthly sheet (tab in the main) and do a bunch of sorting and moving emails in gmail.
I'd like to set this up so it automatically puts the January emails in a sheet for January and the February emails in a sheet for February.
I thought about cascading if elseif statements, but that got too unwieldy fast.
I thought about iterating using a for loop through an array holding all emails, but that seems convoluted too.
Any suggestions?
::EDIT::
To be clear, I'm really interested in how to parse all of the emails and send the ones from January to the January sheet (for example).
::EDIT:: Added current script
function myFunction() {
var label = GmailApp.getUserLabelByName(myLabel);
var label2 = GmailApp.getUserLabelByName(newLabel);
var threads = label.getThreads();
var data = new Array();
var newData = new Array();
// get all the email threads matching myLabel
for (var i = 0; i < threads.length; i++) {
var messages = GmailApp.getMessagesForThread(threads[i]);
// archive thread
label2.addToThread(threads[i]);
label.removeFromThread(threads[i]);
// get each individual email from the threads
for (var j = 0; j < messages.length; j++) {
var bodyText = messages[j].getPlainBody();
// split the email body into individual "paragraph" strings based on the regExp variable
while (matches = regExp.exec(bodyText)) {
var logdata = matches[1];
for (k in keys) {
logdata = logdata.replace(keys[k], "");
}
// split out each "paragraph" string into an array
var lines = logdata.split(/[\r\n]+/);
for (l in lines) {
lines[l] = lines[l].replace('*F','');
lines[l] = lines[l].trim();
}
for (l in lines) {
lines[l] = lines[l].replace(/^(\:\s)/, "");
}
// Turn the first element in the array into a date element, format it, and put it back
lines[0] = Utilities.formatDate(new Date(lines[0]), "America/Phoenix", "M/d/yy HH:mm:ss");
// Put the array to a new item in the data array for further processing
if (curMonth == (new Date(lines[0]).getMonth())) {
data.push(lines);
}
}
}
}
// Compare the information in the data array to oldData information in the sheet
if (data.length) {
var oldData = s.getRange(range).getValues();
for (h in oldData) {
oldData[h][0] = Utilities.formatDate(new Date(oldData[h][0]), "America/Phoenix", "M/d/yy HH:mm:ss");
}
for (i in data) {
var row = data[i];
var duplicate = false;
for (j in oldData) {
if (row.join() == oldData[j].join()) {
duplicate = true;
}
}
if (!duplicate) {
newData.push(row);
}
}
// check to write newData only if there is newData, this stops an error when newData is empty
if (newData.length) {
s.getRange(s.getLastRow() + 1, 1, newData.length, newData[0].length).setValues(newData);
}
s.getRange(range).sort(1); //sorts the sheet
}
}
Try this:
function getSheet(date) {
var ss=SpreadsheetApp.openById('SpreadsheetId');
var name=Utilities.formatDate(new Date(date), Session.getScriptTimeZone(), "MMMyyyy")
var sh=ss.getSheetByName(name);
if(!sh) {
var sh=ss.insertSheet(name);
}
return sh;
}
I ended up basing my solution on the solution that #cooper provided, but had to go a little further.
var ss = SpreadsheetApp.getActiveSpreadsheet();
var month = new Array("January","February","March","April","May","June","July","August","September","October","November","December");
var curMonth = new Date().getMonth(); //number of month -1 aka: January = 0
var sheetname = month[curMonth] + " " + new Date().getYear();
var s = ss.getSheetByName(sheetname);
function newMonth(){
if (!s) {
var template = ss.getSheetByName('Template').copyTo(ss);
template.setName(sheetname);
s = ss.getSheetByName(sheetname); //"reload" the sheet
s.showSheet(); //unhide the new copy since 'Template' is hidden in the spreadsheet
ss.setActiveSheet(s); //make it active
ss.moveActiveSheet(0); //move it to the first position
}
}
I'm trying to run an IF function to match the date in the first column to "last month" and the date in the last column to "newest date" and copy and paste all of the rows matching this criteria (excluding the first and last column) to the bottom of the list.
This is the script I'm running and it isn't finding any matches when I know for a fact there are at least 100 rows matching this criteria:
function myFunction() {
var MCS = SpreadsheetApp.openById('[ID REMOVED FOR THIS Q]');
var MRB = MCS.getSheetByName('Media Rates Back');
var MRBrange = MRB.getRange(1,1,MRB.getLastRow(),1).getValues();
var dest = MRBrange.filter(String).length + 1;
var LM = new Date();
LM.setDate(1);
LM.setMonth(LM.getMonth()-1);
var LMs = Date.parse(LM);
var Datenew = MRB.getRange(MRB.getLastRow(),MRB.getLastColumn()).getValue();
var Datecol = MRB.getRange(1,6,MRB.getLastRow(),1).getValues();
var Datenews = Date.parse(Datenew);
for(var i=0; i<MRBrange.length; i++) {
if(Date.parse(MRBrange[i])==LMs && Date.parse(Datecol[i])==Datenews ) {
var NewRange = MRB.getRange(i,2,(MRB.getLastRow()-i),5);
var NewRangeV = NewRange.getValues();
var destination = MRB.getRange(MRB.getLastRow()+1,2);
Logger.log(NewRange);
NewRange.copyTo(destination);
}else{
Logger.log(i);
}
}}
Any help would be appreciated!
Rather than get the columns as separate ranges, I would get the entire range as one array, then loop over that and check the two columns.
I'm also assuming your values are formatted as dates in the Sheet, in which case you don't need to use Date.parse(), and that your actual date logic is correct.
You can try using the debugger and set a breakpoint at the IF, so you can check the values it is comparing. or put a Logger.log call to list your comparisons.
var last_month_column = 1;
var newest_date_column = MRB.getLastColumn();
var MRBrange = MRB.getRange(1,1,MRB.getLastRow(),newest_date_column).getValues();
for(var row in MRBrange) {
if(MRBrange[row][last_month_column]==LMs && Datecol[row][newest_date_column] ==Datenews ) {
/* your copy logic here */
}else{
Logger.log(i);
}
}
I think the problem may be that MRBrange is a 2d Array. So I used another loop to convert it to a 1d array.
function myFunction() {
var MCS = SpreadsheetApp.openById('[ID REMOVED FOR THIS Q]');
var MRB = MCS.getSheetByName('Media Rates Back');
var MRBrangeA = MRB.getRange(1,1,MRB.getLastRow(),1).getValues();//2d array
var MRBrange=[];
for(var i=0;i<MRBrangeA.length;i++)
{
MRBrange.push(MRBrangA[i][0]);//1d array
}
var dest = MRBrange.filter(String).length + 1;
var LM = new Date();//current day
LM.setDate(1);//first day of month
LM.setMonth(LM.getMonth()-1);//first day of last month
var LMs = Date.parse(LM);
var Datenew = MRB.getRange(MRB.getLastRow(),MRB.getLastColumn()).getValue();
var Datecol = MRB.getRange(1,6,MRB.getLastRow(),1).getValues();
var Datenews = Date.parse(Datenew);
for(var i=0; i<MRBrange.length; i++) {
if(Date.parse(MRBrange[i])==LMs && Date.parse(Datecol[i])==Datenews ) {
var NewRange = MRB.getRange(i,2,(MRB.getLastRow()-i),5);
var NewRangeV = NewRange.getValues();
var destination = MRB.getRange(MRB.getLastRow()+1,2);
Logger.log(NewRange);
NewRange.copyTo(destination);
}else{
Logger.log(i);
}
}}
I have looked at various solutions posted i.e. parsing, substrings and splitting and none of them either produce a value or the required value.
The format received via Salesforce API is "2014-08-19T02:26:00.000+0000"
Essentially I would like a custom function that can be used within Google Sheets to convert this date/time format and take daylight saving into consideration
Thank you beforehand
I use a simple function like below :
function parseDate(string) {
var parts = string.split('T');
parts[0] = parts[0].replace(/-/g, '/');
var t = parts[1].split(':');
var refStr = new Date(new Date(parts[0])).toString();// use this to get TZ for daylight savings
var fus = Number(refStr.substr(refStr.indexOf('GMT')+4,2));
return new Date(new Date(parts[0]).setHours(+t[0]+fus,+t[1],0));
}
firstly thank you for everyone's input. By using a combination of the info provided by RobG and Serge insas I revised the script and created one that suited my needs. Please see below, any further advice would be welcome.
/*
The script first has all variables declared.
As the script runs inconjunction with an API query running off single trigger for defined sequential functions where the previous parsed date records are cleared and then re-parsed and runs with loop function for a whole column of data within specified range
*/
function parseDate() {
var source_spreadsheet = SpreadsheetApp.openById("Sheet_Id");
SpreadsheetApp.setActiveSpreadsheet(source_spreadsheet);
var sheet = source_spreadsheet.getSheetByName("Sheet_Tab");
var startRow = 2;
var numRows = 4500;
var startCol = 1;
var numCols = 7;
var dataRange = sheet.getRange(startRow, startCol, numRows, numCols)
sheet.getRange(startRow, startCol + 1, numRows, numCols - 1).clear({contentsOnly: true});
var data = dataRange.getValues();
for (var i = 0; i < data.length; ++i) {
var row = data[i];
var SFConnectDate = row[0];
var DConnected = row[1];
var SFCutoverDate = row[2];
var DInUse = row[3];
var Lat = row[5];
var Long = row[6];
if (SFConnectDate != "" && DConnected == "" && Lat != "" && Long != "") {
var parts = SFConnectDate.split('T');
parts[0] = parts[0].replace(/-/g, '/');
var Fdd = parts[0].split('/');
var AllTime = parts[1].split('.');
var Ftt = AllTime[0].split(':');
var D = new Date(Fdd[0],(Fdd[1]-1),Fdd[2] ,Ftt[0],Ftt[1],Ftt[2]);
var TZ = (D.getTimezoneOffset())/60;
var DConnected = new Date(Fdd[0],(Fdd[1]-1),Fdd[2],(Ftt[0]-TZ),Ftt[1],Ftt[2]);
sheet.getRange(startRow + i, 2).setValue(DConnected);
}
}
}