Eingabemasken für Google Docs

Immer wieder die gleiche Vorlage öffnen, sich zu den relevanten Stellen vorarbeiten, Anpassungen vornehmen, abspeichern, abschicken … wenn man das 1000-mal gemacht hat, dann ist es an der Zeit, über eine Dokumentenvorlage nachzudenken, die automatisiert befüllt werden kann.

Das geht natürlich mit einer ganzen Reihe von Programmen. Ich habe mir Google Docs vorgenommen. Google bietet mit Google Apps Script eine Möglichkeit, Dokumente automatisiert zu erstellen und zu editieren.

Tobias Sell hat auf seiner Webseite ein Skript vorgelegt. Die Lösung funktioniert mit allen Dokumenten, in denen man Platzhalter mit Paaren von zwei geschweiften Klammern umschließt. Für jeden Platzhalter, den das Programm noch nicht kennt, wird der Nutzer aufgefordert, einen Wert anzugeben. Das ist sehr flexibel.

Ich wollte jedoch eine Lösung, bei der der Nutzer alle Eingaben auf einmal angeben kann. Dafür bietet Google Docs die Möglichkeit, Formulare via HTML zu definieren.

So sieht meine Lösung aus: Man hat ein Dokument, in dem man Platzhalter mit geschweiften Klammern definiert:

Das Skript erstellt auch ein Menü, wenn man das Dokument aufruft. Drückt man dort „neues Dokument erstellen“ wird eine Eingabemaske aufgerufen:

Nun füllt der Nutzer die benötigten Felder aus. Wenn er das Formular abschickt,

  1. wird eine Kopie der Vorlage in einem speziellen Ordner in Google Drive angelegt
  2. in der Kopie werden alle in der Form definierten Felder, die in doppelt geschweiften Klammern daherkommen, ersetzt
  3. das Dokument wird gespeichert und als PDF dem Nutzer auf eine vordefinierte E-Mail-Adresse geschickt

Der Code gliedert sich in einen JavaScript-Teil und einen HTML-Teil. Zuerst das Skript:

const FOLDER_NAME   = 'TestOrdner'; 
const USER_EMAIL    =  YOUR_EMAIL_ADDRESS;
const USER_GREETING = 'Geben Sie die Daten ein:';
const EMAIL_SUBJECT = 'Neues Dokument'; 
const DOCUMENT_NAME = "doc_search_form_"; 

var ui = DocumentApp.getUi(); 

function onOpen() {

  ui.createMenu('Neues Dokument')
  .addItem('Neues Dokument erstellen', 'openInputDialog')
  .addToUi(); 
} 

function openInputDialog() {
  
  var html = HtmlService.createHtmlOutputFromFile('index')
    .setWidth(350)
    .setHeight(300);

  var dialog = ui.showModalDialog(html, USER_GREETING);
}

function createDocAndMail(form) {

  var newDocument = createDocFromTemplate(form);  

  var body=newDocument.getBody();

 for (var [key, value] of Object.entries(form)){
   body.replaceText("{{"+key+"}}", value) 
  }

  newDocument.saveAndClose();

  GmailApp.sendEmail(USER_EMAIL, EMAIL_SUBJECT, "Schöne Grüße!",{
     attachments: [newDocument.getAs(MimeType.PDF)],
     name: 'Automatic Emailer Script'
  });
}

function createDocFromTemplate (form) {

  const documentName = DOCUMENT_NAME + form.feld1; 
  var matchingFolders = DriveApp.getFoldersByName(FOLDER_NAME);
  if (matchingFolders.hasNext()) {
    var documentFolder =  matchingFolders.next();
  }
  else {
    var documentFolder = DriveApp.createFolder(FOLDER_NAME);
  }
  
  var file = DriveApp
  .getFileById(DocumentApp.getActiveDocument().getId())
  .makeCopy(documentName, documentFolder); 
  
  return DocumentApp.openById(file.getId()); 
}

Am Anfang werden globale Variablen definiert. Hier muss vor allem die eigene E-Mail-Adresse anstelle von YOUR_EMAIL_ADDRESS hinterlegt werden. An diese Adresse soll der Nutzer das erstellte PDF-Dokument gesendet bekommen. Die Funktion onOpen lässt beim Öffnen der Vorlage einen Punkt im Menü erscheinen, von dem man aus die Funktion openInputDialog aufrufen lassen kann. openInputDialog wiederum lässt die unten definierte Eingabemaske erscheinen. Die eigentlichen Ersetzungen passieren in der Funktion createDocAndMail, die ich zu einem großen Teil von Tobias Sell übernommen habe. Im Unterschied zu seiner Lösung wird nicht das Dokument nach Platzhaltern durchsucht, sondern die Felder der Eingabemaske werden nacheinander durchlaufen.

Der HTML-Teil, in index.html, definiert die Eingabemaske. Außerdem wird im HTML-Teil die oben definierte Funktion createDocAndMail mit den Nutzerdaten als Eingabe aufgerufen:

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
    <link rel="stylesheet" href="https://ssl.gstatic.com/docs/script/css/add-ons1.css"> 
  </head>
  <body>
  <form>

    <table>
      <col width="130">
      <col width="100">
      <tr>
        <td> Feld 1: </td> <td><input type="text" name="feld1"> </td> 
      </tr>
      <tr> 
        <td> Feld 2: </td> <td> <input type="text" name="feld2"> </td>
      </tr>
    </table>

    <input type="button" class="action" value="Abschicken"
        onclick="processForm(this.parentNode)" />
    <input type="button" value="Abbrechen" onclick="google.script.host.close()" />

  </form>
  </body>
  <script>
  function processForm(form){
    google.script.run.createDocAndMail(form); 
    google.script.host.close();
  }
  </script>
</html>

Zuerst wird das Layout über das Google-CSS definiert. Ein Tipp, den ich der Lösung von Yaginasatode entnommen habe. Darauf wird eine Form mithilfe einer Tabelle definiert, und am Ende gibt es zwei Buttons, die entweder die Form via google.script.host.close schließen oder via google.script.run die Serverfunktion createDocAndMail aufrufen. Das kleine Stück JavaScript im HTML-Teil wartet nicht darauf, dass createDocAndMail fertig wird, sondern geht gleich zur nächsten Zeile und schließt die Form.

Bauen, Bauen, Bauen

Hier ist ein spannender Artikel zur Wohnungskrise in den Staaten. Laut den Autoren hat die Wohnungskrise tiefgreifendere gesellschaftliche Folgen, als es die Berliner Diskussion um den Mietenspiegel vielleicht vermuten lässt:

Nearly all of the biggest challenges in America are, at some level, a housing problem. Rising home costs are a major driver of segregation, inequality, and racial and generational wealth gaps.

Dougherty, Conor. „Build Build Build Build Build Build Build Build Build Build Build Build Build Build“. The New York Times, 13. Februar 2020

Via Managerial Econ.

Versteckte Log-Skalierungen

Hier ist ein interessanter Blog-Artikel, der die Vor- und Nachteile von logarithmischen Skalen in Graphen diskutiert. Logarithmen erlauben es uns, alle Datenpunkte in eine Graphik zu quetschen, aber unsere Intuition kann uns bei der Beurteilung des Graphen in die Irre führen. Das Gleiche gilt für Wachstumsraten: Der Unterschied zwischen 2% und 4% Wachstum scheint klein, aber die Konsequenzen können gewaltig sein.

Lesestoff: Clean Code

Clean Code von Robert C. Martin ist ein Buch, das einem beibringen möchte, wie man „sauberen“ Code schreibt. Sauberer Code ist für ihn und seine Co-Autoren nicht nur lesbarer, sondern auch durch und durch testbarer Code, der zudem nach gewissen Prinzipien geordnet ist.

Das Buch redet nicht viel darüber, was guten Code eigentlich ausmacht. Stattdessen werden nach und nach Bereiche diskutiert, in denen man Verbesserungen in der Codequalität erzielen kann. Beispielsweise beginnt das Buch mit einem Abschnitt zur Variablen- und Methodenbenennung. Darauf werden Funktionen diskutiert usw.

Ein großes Thema des Buches ist der Ausdruck der Programmierabsicht. Das bedeutet u. a., dass man soweit wie möglich versucht, den Kontext in jeder Zeile Code zu erfassen. Erst der Kontext erschließt den Zweck einer Anweisung. Die Mittel dazu sind vor allem Namensgebung, aber auch die Verwendung von Objekten.

Ein anderes, für mich wesentliches Thema ist das der Trennung bzw. der Entkopplung von Aufgaben im Code. Beispielsweise sollen Funktionen nur „eine“ Sache auf „einer“ Abstraktionsebene erledigen. Dies steigert die Übersichtlichkeit und Testbarkeit des Codes und bietet weitere Vorteile.

Was mir manchmal gefehlt hat, waren dann doch konkrete Techniken, um die Empfehlungen umzusetzen. Es gibt allerdings auch eine Prüfliste in einem der letzten Kapitel des Buches. Um die Praktiken des Buches zu verinnerlichen, habe ich mir jedenfalls vorgenommen, den Code einiger Hobbyprojekte nach den vorgeschlagenen Prinzipien zu bereinigen. Hoffentlich bringt’s was.

Martin, Robert C., Hrsg. Clean Code: A Handbook of Agile Software Craftsmanship. Upper Saddle River, NJ: Prentice Hall, 2009.

Was ist Dein Output?

Andrew Grove, Mitgründer von Intel, stellte seinen Managern genau diese Frage. In seinem Buch, High Output Management, präsentiert er seine eigene Antwort: Der Output eines Managers sei der Output seines Teams.

Das Buch ist sehr populär. Es wird von vielen Silicon-Valley-Ikonen hoch gelobt. Die obige Einsicht, die ich hier etwas verkürzt wiedergebe, wird besonders hervorgehoben und ist charakteristisch für die Herangehensweise des Autors, alle Aktivitäten innerhalb eines Unternehmens aus einer Produktionssicht zu analysieren.

Warum ist die Antwort auf die Frage so wichtig? Sie zeigt sofort den
Unterschied zwischen den Aktivitäten eines Managers, was
Führungskräfte so tun, und seiner Aufgabe auf. Dadurch wird klar, wie er
seine Aktivitäten zu bewerten hat. Der Manager hat damit eine Art Kompass. Er zeigt die Richtung auf, in der all seine Aktivitäten gehen
sollten.

Die Frage kann man aber auch bei jeder beliebigen Position in einer
Organisation stellen. Was produziert eine Sekretärin? Was produziert
ein Analyst? Diese Überlegungen sollten letztlich zu einem besserem Verständnis der Rolle und des Anforderungsprofils einer Position führen.

Mir scheint, dass die Produktionsmetapher nützlich aber eben auch nur eine Metapher ist. Die Rollen, die wir ausfüllen, sind oft vielfältiger, als es die Metapher suggeriert. Ob sie das sein sollten, ist eine andere Frage.

Grove, A.S., 1995. High output management, 2nd Vintage Books ed. ed. Vintage, New York.

Moderne Geldtheorie

Ein Gespenst geht um in Amerika – das Gespenst der Modern Monetary
Theory (MMT). So erscheint es jedenfalls Paul Krugman in seinem
Beitrag in der New York Times: Weil niemand sage, was denn eigentlich
MMT genau sei, müsse man sich selbst auf die Suche begeben. Paul
Krugman nimmt Abba Lerners „Functional Finance“-Theorie als
Ausgangspunkt, um über MMT zu sprechen – quasi als Stellvertreter.

Lerners Theorie gehe ungefähr so: Wenn ein Staat in seiner eigenen Währung Schulden aufnimmt und diese nicht an eine natürliche
Ressource (Gold bspw.) koppelt, dann braucht er sich um die
Finanzierung der Staatsausgaben keine großen Gedanken machen. Er
kann ja sein Geld selber drucken. Das einzige Problem, was eine Regierung dabei hat, ist, dass zu viel staatliches Geldausgeben die Inflation erhöht. Daher muss man die Gesamtnachfrage im Auge behalten, um eine inflationäre Überhitzung zu vermeiden. Die Verschuldungsquote an sich sollte für die Politik nicht relevant sein.

Während Krugman den Kerngedanken erst einmal für gut hält, sieht er
zwei Probleme: Zum einen ignoriere Lerner, dass eine Zentralbank auf
staatliche Mehrausgaben üblicherweise mit Zinserhöhungen reagieren
würde. Damit würde der private Sektor zu schlechteren Konditionen
finanziert und das hätte letztlich Kosten. Zum anderen setze das
Gesamtvermögen einer Volkswirtschaft eine Verschuldungsobergrenze:
Wenn der Staat sich gegenüber dem privaten Sektor verschuldet, geht das nur solange, wie der private Sektor auch etwas zu verleihen hat.

Das bedeutet, dass der Staat die Verschuldung ab einem bestimmten
Punkt über Steuern oder Ausgabenkürzungen finanzieren müsse, damit die Verschuldungsquote stabil bleibe. Krugman veranschaulicht das Argument mit einer Modellrechnung, welcher primärer Überschuss bei einer bestimmten Verschuldungsquote notwendig wäre, aber er schließt mit der Bemerkung, dass die genannten Probleme im Moment wenig relevant seien.

Der HP-2310ti-Monitor gibt unter Windows 10 keinen Ton mehr von sich

Mein Rechner hatte schon lange unter Windows 10 Probleme. Zuletzt konnte ich noch nicht mal Updates einspielen. Vielleicht lag es auch am Dual-Boot mit Linux. Jedenfalls habe ich über die Platte gebügelt und Windows 10 neu installiert und – siehe da – ein neues Problem. Nun ging der Sound meines HP-2310ti-Monitors nicht mehr. Letztlich lässt sich das Problem aber einfach lösen: Man muss einen Audio-Codec-Treiber zurücksetzen. Die Einzelheiten dazu findet man unter dem Eintrag des Microsoft-Forums.