Kontakt

Fancy Reports mit Google Ads Scripts selber bauen

veröffentlicht am:
Tipps & Tricks zur Reporterstellung mit Google Ads Scripts

Wir Google Ads-Manager lieben Zahlen. Schließlich sind diese für das tägliche Auswerten der Performance unabdingbar. Um sich diese jedoch besonders schön darzustellen, stößt man mit den Berichtsmöglichkeiten im Google Ads-Interface oft an seine Grenzen. Investiert man aber etwas Zeit in das Einarbeiten in Google Ads Scripts, kann man sich so sehr hilfreiche und komplexe Reports automatisiert erstellen lassen. In diesem Artikel möchte ich mit einigen Tipps & Tricks zeigen, wie man sich mit etwas Einarbeitung selber fancy Reports mit Google Ads Scripts bauen kann.

 

1.   Den Report konfigurieren mit Google Tabellen

 

Ein Report soll natürlich nicht wild irgendwelche Daten anzeigen, sondern genau die, die gerade benötigt werden. Dabei können sich bestimmte Parameter auch mal ändern. Damit dazu nicht jedes Mal der Code des Skriptes angepasst werden muss, ist es sinnvoll, dieses von Anfang an möglichst konfigurierbar zu bauen. Anstatt aber nun extrem viele Variablen im Code des Skriptes zu verwenden, ist es deutlich einfacher, den Report in einem Google Spreadsheet konfigurierbar zu machen. So können hier z. B. der Zeitraum für die Daten oder alle gewünschten Metriken in einem schönen Konfigurations-Spreadsheet dargestellt werden, mit dem jeder etwas anfangen kann, auch wenn er oder sie vorher noch nie ein Google Ads Skript gesehen hat. Um diese Daten nun in das Skript zu bekommen, kann man mit der SpreadsheetApp arbeiten. Dies ist eine eigene Bibliothek mit einigen vordefinierten Methoden um Daten aus Google Tabellen auszulesen, etwas in diese hineinzuschreiben oder diese umzuformatieren. Ein Tipp ist, hier die Funktion „benannte Bereiche“ von Google Tabellen zu verwenden. Diese sind unter dem Menüpunkt „Daten“ in der Menüleiste zu finden (siehe Screenshot). Mit dieser kann man entweder für einzelne Zellen oder auch ganze Bereiche eigene Namen vergeben. Dies bringt den Vorteil nicht mehr mit kryptischen Kombinationen aus Buchstaben und Zahlen auf einzelne Zellen zugreifen zu müssen. So kann für die Zelle Zeitraum die sich z. B. immer fest in der Zelle „B2“ befindet, der Name „Zeitraum“ vergeben werden.  In dem Skript wird dann über den Befehl .getRange("Zeitraum") anstatt .getRange(„B2“) auf die Zelle zugegriffen.

Screenshot benannte Bereiche Google Tabellen Screenshot für benannte Bereiche in Google Tabellen

Im folgenden Codeschnipsel werden Daten aus den benannten Bereichen in die jeweils dafür vorgesehenen Variablen geschrieben:

function main() {
  var spreadsheet = SpreadsheetApp.openByUrl("https://docs.google.com/spreadsheets/d/xxx").getActiveSheet();
  
  var timeRange = spreadsheet.getRange("timeRange").getValue();
  var value1 = spreadsheet.getRange("impressions").getValue();
  var value2 = spreadsheet.getRange("cost").getValue();
  var value3 = spreadsheet.getRange("conversionValue").getValue();
}

2. Daten über Google Ads-Reports Bibliothek ziehen

Hat man nun alle Werte aus dem Konfigurationssheet in das Skript gebracht, geht es als nächstes darum, sich die Daten von Google Ads zu holen und ebenfalls in das Skript zu bekommen. Hierzu gibt es im Grunde zwei Möglichkeiten: Zum einen kann man mit einem Iterator über die einzelnen Objekte laufen und sich so die Daten von Google Ads ziehen. Dies hat allerdings den Nachteil, dass hier bei jedem Aufruf die Google Ads API aufgerufen werden muss und somit das Skript langsamer durchläuft. Schneller geht es über die Reports Bibliothek, die über AdWordsApp.report aufgerufen werden kann. Hier kann auf eine Vielzahl von vordefinierten Reports zugegriffen werden. Welche es davon gibt ist in folgender Übersicht zu sehen: https://developers.google.com/adwords/api/docs/appendix/reports?hl=de Die Werte aus den Reports werden wiederum über eine AWQL-Abfrage (AdWords Query Language) abgerufen. Wer sich bereits etwas mit SQL auskennt, sollte sich auch hier relativ schnell zurechtfinden. Es gibt dabei folgende wichtige Anweisungen:

  • SELECT: Hier werden alle Attribute, Segmente und Metriken aufgezählt, die in dem Report enthalten sein sollen. Dabei muss man sich jedoch immer daran halten, welche davon auch in dem jeweils verwendeten Report vorhanden sind. Möchte man alles auswählen, schreibt man einfach ein „SELECT *“
  • FROM: Hier wird definiert von welchem vordefinierten Bericht die Daten gezogen werden sollen
  • WHERE: Hier können Filter definiert werden wie z. B. eine Mindestanzahl an Klicks
  • DURING: Werden Performancedaten aufgerufen, muss hier ein Zeitraum definiert werden. Für einige Standard-Zeiträume kann man einfach einen vordefinierten String verwenden wie z. B. „LAST_30_DAYS“. Möchte man einen eigenen Zeitraum definieren ist dieser nach dem Schema YYYYMMDD,YYYYMMDD zu beschreiben, wobei der erste Wert das Start- und der zweite das Enddatum ist.

Auf die einzelnen Reihen greift man wiederum mit der Funktion .rows() zu, um dann anschließend mit einem Iterator durch die Zeilen zu laufen. Hier wird zwar wieder ein Iterator wie bei der ersten Vorgehensweise verwendet, da sich die Daten nun jedoch nach dem Aufrufen des Reports  schon im Zwischenspeicher des Skriptes befinden, müssen nicht jedes Mal Daten von der Google Ads API abgegriffen werden. Im folgenden Codeschnipsel wird der Report für die Performance der Suchanfragen in das Skript geladen. Anstatt direkt die auszuwählenden Werte hinter der SELECT-Anweisung zu verwenden, werden hier die Variablen mit den Werten aus dem Config-Spreadsheet verwendet. Außerdem ist die Suchanfrage mit der Variable minImpressions für die Mindestanzahl an Impressionen konfigurierbar:

var minClicks = 10;
  
var report = AdWordsApp.report(
"SELECT Query,“ + value1 + “,” + value2 + “,” + value3 + " “ +
"FROM SEARCH_QUERY_PERFORMANCE_REPORT " +
"WHERE Clicks > " + minClicks + " " +
"DURING " + timeRange);

2. Daten über Google Ads-Reports Bibliothek ziehen

 

Hat man nun alle Werte aus dem Konfigurationssheet in das Skript gebracht, geht es als nächstes darum, sich die Daten von Google Ads zu holen und ebenfalls in das Skript zu bekommen. Hierzu gibt es im Grunde zwei Möglichkeiten: Zum einen kann man mit einem Iterator über die einzelnen Objekte laufen und sich so die Daten von Google Ads ziehen. Dies hat allerdings den Nachteil, dass hier bei jedem Aufruf die Google Ads API aufgerufen werden muss und somit das Skript langsamer durchläuft. Schneller geht es über die Reports Bibliothek, die über AdWordsApp.report aufgerufen werden kann. Hier kann auf eine Vielzahl von vordefinierten Reports zugegriffen werden. Welche es davon gibt ist in folgender Übersicht zu sehen: https://developers.google.com/adwords/api/docs/appendix/reports?hl=de Die Werte aus den Reports werden wiederum über eine AWQL-Abfrage (AdWords Query Language) abgerufen. Wer sich bereits etwas mit SQL auskennt, sollte sich auch hier relativ schnell zurechtfinden. Es gibt dabei folgende wichtige Anweisungen:

  • SELECT: Hier werden alle Attribute, Segmente und Metriken aufgezählt, die in dem Report enthalten sein sollen. Dabei muss man sich jedoch immer daran halten, welche davon auch in dem jeweils verwendeten Report vorhanden sind. Möchte man alles auswählen, schreibt man einfach ein „SELECT *“
  • FROM: Hier wird definiert von welchem vordefinierten Bericht die Daten gezogen werden sollen
  • WHERE: Hier können Filter definiert werden wie z. B. eine Mindestanzahl an Klicks
  • DURING: Werden Performancedaten aufgerufen, muss hier ein Zeitraum definiert werden. Für einige Standard-Zeiträume kann man einfach einen vordefinierten String verwenden wie z. B. „LAST_30_DAYS“. Möchte man einen eigenen Zeitraum definieren ist dieser nach dem Schema YYYYMMDD,YYYYMMDD zu beschreiben, wobei der erste Wert das Start- und der zweite das Enddatum ist.

Auf die einzelnen Reihen greift man wiederum mit der Funktion .rows() zu, um dann anschließend mit einem Iterator durch die Zeilen zu laufen. Hier wird zwar wieder ein Iterator wie bei der ersten Vorgehensweise verwendet, da sich die Daten nun jedoch nach dem Aufrufen des Reports  schon im Zwischenspeicher des Skriptes befinden, müssen nicht jedes Mal Daten von der Google Ads API abgegriffen werden. Im folgenden Codeschnipsel wird der Report für die Performance der Suchanfragen in das Skript geladen. Anstatt direkt die auszuwählenden Werte hinter der SELECT-Anweisung zu verwenden, werden hier die Variablen mit den Werten aus dem Config-Spreadsheet verwendet. Außerdem ist die Suchanfrage mit der Variable minImpressions für die Mindestanzahl an Impressionen konfigurierbar:

var minClicks = 10;
  
var report = AdWordsApp.report(
"SELECT Query,“ + value1 + “,” + value2 + “,” + value3 + " “ +
"FROM SEARCH_QUERY_PERFORMANCE_REPORT " +
"WHERE Clicks > " + minClicks + " " +
"DURING " + timeRange);

3. Daten aggregieren und bearbeiten (mehrdimensionale Arrays)

 

Nachdem sich alle Daten nun im Zwischenspeicher des Skriptes befinden, geht es als nächstes an das Bearbeiten und Aufbereiten dieser. Dazu bieten sich mehrdimensionale Arrays an. Bei einem Array handelt es sich um eine Liste von Variablen. Mehrdimensionale Arrays wiederum sind Arrays innerhalb eines anderen Arrays. Zunächst sollte ein einfaches eindimensionales Arrays erzeugt werden. Hier kann nun ein Element dieses gerade erzeugten Arrays ausgewählt werden, in dem wiederum ein weiteres Array geschrieben werden soll. Schon hat man ein zweidimensionales Array. Dies kann auch noch mit unendlich weiteren Dimensionen fortgeführt werden,  nur wird es dann irgendwann etwas unübersichtlich. Mit diesem zweidimensionalen Array können nun auch Berechnungen angestellt werden, wie z. B. die KUR mithilfe der Kosten und dem Conversion Wert zu berechnen. Im folgenden Codeschnipsel werden die Daten aus dem Report in ein zweidimensionales Array geschrieben. Hier ist es wichtig zu beachten die Zahlen vorher durch parseInt oder parseFloat in eine Zahl umzuwandeln, da diese sonst als String aus dem Report kommen und dies zu Fehlern führen kann:

var data = new Array();
  
var rows = report.rows();
  
while (rows.hasNext()) {
  var row = rows.next();
    
  var query = row["Query"];
  var impressions = parseInt(row["Impressions"]);
  var cost = parseFloat(row["Cost"]);
  var conversionValue = parseFloat(row["ConversionValue"]);  
    
    
  data[query] = new Array();
  data[query]["Impressions"] = impressions;
  data[query]["Cost"] = cost;
  data[query]["ConversionValue"] = conversionValue;
  data[query]["KUR"] = cost / conversionValue;
}

4. Daten in einer Google Tabelle ausgeben

 

Nun sollen die Daten noch in einem passenden Format ausgegeben werden. Als Ausgabe bieten sich hier nun wieder Google Tabellen an. Zu Beginn sollte man erst einmal eine Titelzeile in die Google Tabelle schreiben. Anschließend kann mit einer For-Schleife auf die einzelnen Elemente des mehrdimensionalen Arrays zugegriffen werden, um diese dann in die jeweils letzte Zeile der Google Tabelle zu schreiben. Im folgenden Codeschnipsel werden die Zahlen aus dem mehrdimensionalen Array wieder in eine Google Tabelle geschrieben. Hier sollten die Performance-Werte zunächst wieder in einen String umgewandelt, dann die Kommas entfernt und schließlich die Punkte durch Kommas ersetzt werden, damit diese auch nach dem deutschen Format aus dem Skript kommen. 

var spredsheet.getSheetByName(„Ausgabe“);  

  spreadsheet.getRange("A" + 1).setValue("Query");
  spreadsheet.getRange("B" + 1).setValue("Impressions");
  spreadsheet.getRange("C" + 1).setValue("Cost");
  spreadsheet.getRange("D" + 1).setValue("ConversionValue");
  spreadsheet.getRange("E" + 1).setValue("KUR");
  
  
  var row = 2;
  
  for (var query in data) {
    spreadsheet.getRange("A" + row).setValue(query);
    spreadsheet.getRange("B" + row).setValue(data[query]["Impressions"].toString().replace(",", "").replace(".", ","));
    spreadsheet.getRange("C" + row).setValue(data[query]["Cost"].toString().replace(",", "").replace(".", ","));
    spreadsheet.getRange("D" + row).setValue(data[query]["ConversionValue"].toString().replace(",", "").replace(".", ","));
    (data[query]["KUR"] != Infinity) ? spreadsheet.getRange("E" + row).setValue(data[query]["KUR"].toString().replace(".", ",")) : "";
    row++;
  }

5. Fazit

 

Natürlich bietet dieser Artikel nur einen ersten Einblick in eine Vielzahl von verfügbaren Möglichkeiten. Mit diesen Tipps & Tricks sollte es allerdings jedem leichter fallen, sich in die Welt der Skripte zu wagen und einmal selbst ein Report Skript zu schreiben. So können die Daten aus der Google Tabelle anschließend noch in dem Datenvisualisierungstool von Google, dem Data Studio, in schönen Graphen und Diagrammen dargestellt werden. Außerdem gibt es bereits eine neue Entwicklung die wohl eines der größten Probleme von Google Ads Skripts löst: die langsame Laufzeitgeschwindigkeit und die Laufzeitbegrenzung auf 30 Minuten pro Skript-Durchlauf. Hierbei handelt es sich um Google BigQuery, mithilfe dessen noch schneller und mit weniger Code auf die Google Ads API zugegriffen werden kann.

6.   Beispielskript zum selber Anwenden: Prüfung von Remarketing-Listen

 

Zuletzt noch ein Skript, in dem bis auf eine Konfigurations-Tabelle alle oben genannten Punkte verwendet werden. Dieses Skript vergleicht die Performance von Remarketing-Listen mit der der kompletten Anzeigengruppe. So kann auf einen Blick entschieden werden, ob diese nach oben oder unten geboten werden sollen. Aktuell funktioniert das Skript nur bei Remarketing-Listen auf Anzeigengruppen-Ebene. Bevor das Skript das erste Mal ausgeführt wird, muss lediglich der Link zu einem leeren Google Tabellenblatt in der Variable spreadsheetUrl hinterlegt werden.

/*************************************
Title: Remarketing Performance Checker
Author: Sebastian Zehelein
Latest version: 1.0
Last Update: 19.06.2018

Change Log:
1.0  Release
**************************************/

//***Start Config
//Time range for performance Data
var timeRange = 'LAST_30_DAYS';

//Url to destination spreadsheet for the report
var spreadsheetUrl = "https://docs.google.com/spreadsheets/d/xxx";

//Minimum amount of impressions for the remarketing lists
var minImpressions = 100;

//***End of Config

var spreadsheet = SpreadsheetApp.openByUrl(spreadsheetUrl).getActiveSheet();

function main() {
  
  //Gets the report for the performance of the remarketing list
  var report = AdWordsApp.report(
    "SELECT CampaignId, CampaignName, AdGroupId, AdGroupName, UserListName, Impressions, Clicks, Cost, AveragePosition, Conversions, CostPerConversion, ConversionValue, BidModifier " +
    "FROM AUDIENCE_PERFORMANCE_REPORT " +
    "WHERE Impressions > " + minImpressions + " " +
    "DURING " + timeRange);
  var rows = report.rows();
  
  var performanceRemarketing = new Array();
  
  while (rows.hasNext()) {
    var row = rows.next();
    var campaignId = row['CampaignId'];
    var adGroupId = row['AdGroupId'];
    var remarketingListName = getRemarketingListName(campaignId, adGroupId, row['AdGroupName'], row['UserListName']);
    
    //Goes through the rows of the report and writes the data into an array
    if (performanceRemarketing[campaignId] == undefined) {
      performanceRemarketing[campaignId] = new Array();
      if (performanceRemarketing[campaignId][adGroupId] == undefined) {
        performanceRemarketing[campaignId][adGroupId] = new Array();
        performanceRemarketing = writeData1(performanceRemarketing, campaignId, adGroupId, remarketingListName, row);
      }
      else {
        performanceRemarketing = writeData1(performanceRemarketing, campaignId, adGroupId, remarketingListName, row);
      }
    } else {
      if (performanceRemarketing[campaignId][adGroupId] == undefined) {
        performanceRemarketing[campaignId][adGroupId] = new Array();
        performanceRemarketing = writeData1(performanceRemarketing, campaignId, adGroupId, remarketingListName, row);
      }
      else {
        performanceRemarketing = writeData1(performanceRemarketing, campaignId, adGroupId, remarketingListName, row);
      }
    }
  }
  
  //Gets the report for the performance of the normal adgroups
  var report = AdWordsApp.report(
    "SELECT CampaignId, CampaignName, AdGroupId, AdGroupName, Impressions, Clicks, Cost, AveragePosition, Conversions, CostPerConversion, ConversionValue " +
    "FROM ADGROUP_PERFORMANCE_REPORT " +
    "DURING LAST_30_DAYS");
  
  var rows = report.rows();
  
  var performanceNormal = new Array();
  
  while (rows.hasNext()) {
    var row = rows.next();
    var campaignId = row['CampaignId'];
    var adGroupId = row['AdGroupId'];
    
    //Goes throught the roews oft the report and writes the data into an array
    if (performanceNormal[campaignId] == undefined) {
      performanceNormal[campaignId] = new Array(); 
      performanceNormal = writeData2(performanceNormal, campaignId, adGroupId, row);
    } else {
      performanceNormal = writeData2(performanceNormal, campaignId, adGroupId, row);      
    }
  }
  
  try {
  //Clears all contents and borders from the spreadsheet
  spreadsheet.getRange(3, 1, spreadsheet.getLastRow() - 2, spreadsheet.getLastColumn()).setBorder(null, null, null, null, false, false);
  spreadsheet.getRange(3, 1, spreadsheet.getLastRow() - 2, spreadsheet.getLastColumn()).clearContent();
  } catch (e) {
  }
  
  var row = 3;
  
  spreadsheet.getRange("A" + 1).setValue("Check Remarketing Performance");
  spreadsheet.getRange("A" + 2).setValue("Campaign");
  spreadsheet.getRange("B" + 2).setValue("AdGroup");
  spreadsheet.getRange("C" + 2).setValue("Remarketing List");
  spreadsheet.getRange("E" + 1).setValue("Rem");
  spreadsheet.getRange("F" + 1).setValue("Nor");
  spreadsheet.getRange("G" + 1).setValue("Rem");
  spreadsheet.getRange("H" + 1).setValue("Nor");
  spreadsheet.getRange("I" + 1).setValue("Rem");
  spreadsheet.getRange("J" + 1).setValue("Nor");
  spreadsheet.getRange("K" + 1).setValue("Rem");
  spreadsheet.getRange("L" + 1).setValue("Nor");
  spreadsheet.getRange("M" + 1).setValue("Rem");
  spreadsheet.getRange("N" + 1).setValue("Nor");
  spreadsheet.getRange("O" + 1).setValue("Rem");
  spreadsheet.getRange("P" + 1).setValue("Nor");
  spreadsheet.getRange("Q" + 1).setValue("Rem");
  spreadsheet.getRange("R" + 1).setValue("Nor");
  
  spreadsheet.getRange("D" + 2).setValue("BidMod");
  spreadsheet.getRange("E" + 2).setValue("Impressions");
  spreadsheet.getRange("F" + 2).setValue("Impressions");
  spreadsheet.getRange("G" + 2).setValue("Clicks");
  spreadsheet.getRange("H" + 2).setValue("Clicks");
  spreadsheet.getRange("I" + 2).setValue("Cost");
  spreadsheet.getRange("J" + 2).setValue("Cost");
  spreadsheet.getRange("K" + 2).setValue("AvgPos");
  spreadsheet.getRange("L" + 2).setValue("AvgPos");
  spreadsheet.getRange("M" + 2).setValue("Conversions");
  spreadsheet.getRange("N" + 2).setValue("Conversions");
  spreadsheet.getRange("O" + 2).setValue("Cost/Conv");
  spreadsheet.getRange("P" + 2).setValue("Cost/Conv");
  spreadsheet.getRange("Q" + 2).setValue("ConvVal/Cost");
  spreadsheet.getRange("R" + 2).setValue("ConvVal/Cost");
  
  spreadsheet.getRange(1,1,2,18).setBackground("#083058");
  spreadsheet.getRange(1,1,2,18).setFontColor("#ffffff");
  
  spreadsheet.setFrozenColumns(4);
  
  //Writes the data from the array into the spreadsheet
  for (var campaignId in performanceRemarketing) {
    for (var adGroupId in performanceRemarketing[campaignId]) {
      for (var remarketingListName in performanceRemarketing[campaignId][adGroupId]) {
        spreadsheet.getRange("A" + row).setValue(performanceRemarketing[campaignId][adGroupId][remarketingListName]['CampaignName']);
        spreadsheet.getRange("B" + row).setValue(performanceRemarketing[campaignId][adGroupId][remarketingListName]['AdGroupName']);
        spreadsheet.getRange("C" + row).setValue(remarketingListName);
        
        spreadsheet.getRange("D" + row).setValue(parseFloat(performanceRemarketing[campaignId][adGroupId][remarketingListName]['BidModifier']));
        spreadsheet.getRange("E" + row).setValue(parseInt(performanceRemarketing[campaignId][adGroupId][remarketingListName]['Impressions']));
        spreadsheet.getRange("E" + row).setNumberFormat("#,##0");
        spreadsheet.getRange("G" + row).setValue(parseInt(performanceRemarketing[campaignId][adGroupId][remarketingListName]['Clicks']));
        spreadsheet.getRange("G" + row).setNumberFormat("#,##0");
        spreadsheet.getRange("I" + row).setValue(parseFloat(performanceRemarketing[campaignId][adGroupId][remarketingListName]['Cost']));
        spreadsheet.getRange("I" + row).setNumberFormat("#,###.## €");
        spreadsheet.getRange("K" + row).setValue(parseFloat(performanceRemarketing[campaignId][adGroupId][remarketingListName]['AveragePosition']));
        spreadsheet.getRange("M" + row).setValue(parseFloat(performanceRemarketing[campaignId][adGroupId][remarketingListName]['Conversions']));
        spreadsheet.getRange("O" + row).setValue(parseFloat(performanceRemarketing[campaignId][adGroupId][remarketingListName]['CostPerConversion']));
        spreadsheet.getRange("O" + row).setNumberFormat("#,###.## €");
        spreadsheet.getRange("Q" + row).setValue(parseFloat(performanceRemarketing[campaignId][adGroupId][remarketingListName]['Conv./Cost']));
        spreadsheet.getRange("Q" + row).setNumberFormat("#,###.## €");
        
        spreadsheet.getRange("F" + row).setValue(parseInt(performanceNormal[campaignId][adGroupId]['Impressions']));
        spreadsheet.getRange("F" + row).setNumberFormat("#,##0");
        spreadsheet.getRange("H" + row).setValue(parseInt(performanceNormal[campaignId][adGroupId]['Clicks']));
        spreadsheet.getRange("H" + row).setNumberFormat("#,##0");
        spreadsheet.getRange("J" + row).setValue(parseFloat(performanceNormal[campaignId][adGroupId]['Cost']));
        spreadsheet.getRange("I" + row).setNumberFormat("#,###.## €");
        spreadsheet.getRange("L" + row).setValue(parseFloat(performanceNormal[campaignId][adGroupId]['AveragePosition']));
        spreadsheet.getRange("N" + row).setValue(parseFloat(performanceNormal[campaignId][adGroupId]['Conversions']));
        spreadsheet.getRange("P" + row).setValue(parseFloat(performanceNormal[campaignId][adGroupId]['CostPerConversion']));
        spreadsheet.getRange("P" + row).setNumberFormat("#,###.## €");
        spreadsheet.getRange("R" + row).setValue(parseFloat(performanceNormal[campaignId][adGroupId]['Conv./Cost']));
        spreadsheet.getRange("R" + row).setNumberFormat("#,###.## €");
        
        spreadsheet.getRange("F" + row).setBackground("#c8def1");
        spreadsheet.getRange("H" + row).setBackground("#c8def1");
        spreadsheet.getRange("J" + row).setBackground("#c8def1");
        spreadsheet.getRange("L" + row).setBackground("#c8def1");
        spreadsheet.getRange("N" + row).setBackground("#c8def1");
        spreadsheet.getRange("P" + row).setBackground("#c8def1");
        spreadsheet.getRange("R" + row).setBackground("#c8def1");
        row++;
      }
    }
  }
  
  //Sets all borders to white
  spreadsheet.getRange(3, 1, spreadsheet.getLastRow(), spreadsheet.getLastColumn()).setBorder(true, true, true, true, true, true, "white", SpreadsheetApp.BorderStyle.SOLID);
  
  //Sorts the spreadsheet by costs
  spreadsheet.getRange(1, 1, spreadsheet.getLastRow(), spreadsheet.getLastColumn()).sort([{column: 10, ascending: false}, {column: 9, ascending: false}]);
  
  var i = 3;
  
  //Sets the borders to the spreadsheet
  while (i < spreadsheet.getLastRow()) {
    if (spreadsheet.getRange(i, 2).getValue() != spreadsheet.getRange(i + 1, 2).getValue()) {
      spreadsheet.getRange(i, 1, 1, spreadsheet.getLastColumn()).setBorder(null, null, true, null, null, null);
    }
    i++;
  }
}

//Writes the data from the spreadsheet for the remarketing lists into an array
function writeData1(data, campaignId, adGroupId, remarketingListName, row) {
  data[campaignId][adGroupId][remarketingListName] = new Array();
  data[campaignId][adGroupId][remarketingListName]['CampaignName'] = row['CampaignName'];
  data[campaignId][adGroupId][remarketingListName]['AdGroupName'] = row['AdGroupName'];
  data[campaignId][adGroupId][remarketingListName]['Impressions'] = row['Impressions'];
  data[campaignId][adGroupId][remarketingListName]['Clicks'] = row['Clicks'];
  data[campaignId][adGroupId][remarketingListName]['Cost'] = row['Cost'];
  data[campaignId][adGroupId][remarketingListName]['AveragePosition'] = row['AveragePosition'];
  data[campaignId][adGroupId][remarketingListName]['Conversions'] = row['Conversions'];
  data[campaignId][adGroupId][remarketingListName]['CostPerConversion'] = row['CostPerConversion'];
  data[campaignId][adGroupId][remarketingListName]['Conv./Cost'] = (parseFloat(row['Cost'].replace(",", "")) == 0) ? 0 : (parseFloat(row['ConversionValue'].replace(",", "")) / parseFloat(row['Cost'].replace(",", "")));
  data[campaignId][adGroupId][remarketingListName]['BidModifier'] = (isNaN(parseInt(row['BidModifier']))) ? 0 : row['BidModifier'];
  return data;
}

//Writes the data from the spreadsheet for the normal adgrousp into an array
function writeData2(data, campaignId, adGroupId, row) {
  data[campaignId][adGroupId] = new Array();
  data[campaignId][adGroupId]['CampaignName'] = row['CampaignName'];
  data[campaignId][adGroupId]['Impressions'] = row['Impressions'];
  data[campaignId][adGroupId]['Clicks'] = row['Clicks'];
  data[campaignId][adGroupId]['Cost'] = row['Cost'];
  data[campaignId][adGroupId]['AveragePosition'] = row['AveragePosition'];
  data[campaignId][adGroupId]['Conversions'] = row['Conversions'];
  data[campaignId][adGroupId]['CostPerConversion'] = row['CostPerConversion'];
  data[campaignId][adGroupId]['Conv./Cost'] = (parseFloat(row['Cost'].replace(",", "")) == 0) ? 0 : (parseFloat(row['ConversionValue'].replace(",", "")) / parseFloat(row['Cost'].replace(",", "")));
  return data;
}

//Returns the name for the "Similar to ..." remarketing lists
function getRemarketingListName(campaignId, adGroupId, adGroupName, listName) {
  if (listName.indexOf("Similar to") != -1) {
    var listId = listName.replace("Similar to UserListId: ", "");
    var audiencesCampaign = AdWordsApp.userlists().withCondition("Id = '" + listId + "'").get().next().getName();
    return "Similar to " + audiencesCampaign;
  } else {
    return listName;
  }
}

Beitragsbild: ©ProStockStudio shutterstock.com

Sebastian Zehelein
Ehem. Senior Online Marketing Manager

Sebastian bis 2022 Senior Online Marketing Manager bei The Boutique Agency.

Ähnliche Artikel
Zum Artikel
Paid Social

YouTube Assets - Mit der richtigen Konzeption zum Erfolg

Dieser Artikel gibt einen umfassenden Überblick, wie Sie mit angemessener Vorbereitungszeit und einer gründlichen Konzeptionsphase ein plattformkonformes Video nach dem Google ABCD-Modell erstellen können.

Zum Artikel
SEO

Marketing-Herausforderungen von Personas in Bezug auf Barrierefreiheit

Die Verwendung von Personas im Marketing ist eine weit verbreitete Methode, um Zielgruppen zu verstehen und maßgeschneiderte Kampagnen zu entwickeln. Es gibt jedoch eine wichtige Dimension, die bei der Erstellung von Personas oft vernachlässigt wird: Barrierefreie Zugänglichkeit.

Zum Artikel
Szene

Recap: SEAcamp Jena 2023

Das SEAcamp feierte 10 jähriges Jubiläum. Sebastian war mit Nadine und Sophie vor Ort und hat seine Highlights und Learnings von dem Event zusammengefasst. Privacy, Automation mit Beispielen von PMAX-Kampagnen und die Nutzung von ChatGTP im SEA waren die Hauptthemen des diesjährigen Events.

Kontakt
Projektanfrage

Wir freuen uns auf Ihre Anfrage und beraten Sie gerne individuell zu Ihren Themen.

Max Höpner, Geschäftsführer

Max Höpner Geschäftsführer

Zum Kontaktformular