CTC – Chaos To Calendar

Wenn ich freiwillig in meiner Freizeit etwas programmiere, dann muss das wohl einen triftigen Grund haben. Den gab es tatsächlich. Dieser Beitrag ist also die Geschichte, wie ich für meine Arbeitskollegen etwas Struktur in die Firma bringen konnte.

1. Der triftige Grund

In unserer Firma ist der Dienstplan in einem Google Sheet Dokument aufgelistet, das mit allen Mitarbeitenden geteilt ist. Eine an sich sehr einfache und flexible Lösung. Für jede Kalenderwoche gibt es ein Tabellenblatt, jeder Mitarbeitende hat seine eigene Zeile und jeder Wochentag eine Spalte. Nun war es aber immer sehr mühsam, ständig das Dokument aufrufen zu müssen, dann im Kalender nachzusehen welche Kalenderwoche gerade ist, und dann ständig in der Zeile zu verrutschen, wenn in der mobilen Ansicht zum Wochenende nach rechts gescrollt wird. Es kam bereits vor, dass Missverständnisse beim Arbeitsbeginn oder der Aufgabenverteilung entstanden sind, nur weil sich eben jemand in der Zeile verschaut hatte.

Vor allem in einer Fernsehproduktionsfirma, in der es nicht jeden Tag die gleichen Arbeitszeiten oder Aufgaben gibt, ist ein funktionierender und übersichtlicher Dienstplan wichtig. Da ich persönlich meinen vollen Alltag nur im Griff behalten kann weil ich alles über meinen zentralen Kalender im Handy organisiere, habe ich bisher meine Arbeitseinsätze immer händisch in diesen Kalender eingetragen. Das hat dazu geführt, dass ich oft nicht mehr auf den richtigen Dienstplan geschaut und dadurch wichtige Aktualisierungen verpasst habe.

Eine Situation, die nicht nur mich, sondern auch meine Kollegen langsam ehrlich genervt hat. Allerdings ist das Tabellendokument für meinen Chef die einfachste, übersichtlichste und Kostengünstigste Lösung, denn er muss schliesslich über 30 Dienstpläne gleichzeitig den Überblick behalten. Es musste also eine andere Lösung als ein externes Dienstplantool her.

2. Die Lösung

Die Lösung war schliesslich der gemeinsame Nenner zwischen aktuellem Dienstplan und meinem Kalender: Google. Ein wenig Recherche und ein Anstoss von ChatGPT haben mir erklärt, dass Google eine eigene, bereits in all ihre Programme integrierte Lösung für Automationen bietet: Google Apps Script. GAS kann man sich vorstellen wie die App Shortcuts auf iOS Geräten, nur deutlich weniger benutzerfreundlich. Das Programm bietet einen einfachen Weg Anwendungen mit einfachen Java Codes umzusetzen und bietet bereits alle nötigen Schnittstellen zum Google Workspace.

Mit diesem Programm musste ich also «nur noch» ein Java Script schreiben, das automatisch die Einträge aus dem Dienstplan-Tabellendokument in meinen Google Kalender überträgt. Ich werde dieses Skript in diesem Beitrag liebevoll «CTC» nennen.

3. Das Tool und sein Code

Die Kernfunktionen von CTC waren schnell definiert:

  1. Zugriff auf die entsprechenden Dokumente (Tabellendokument und Kalender) gewinnen
  2. Daten aus dem Tabellendokument auslesen und bereinigen
  3. Eintrag im Kalender erstellen und Daten korrekt eintragen
  4. Benachrichtigung des Mitarbeitenden via Email bei Änderungen im Kalendereintrag
  5. Laufende Aktualisierung und Überprüfung der Kalendereinträge

Zugriff auf die Dokumente
Durch die bereits bestehende integration von GAS in den Google Workspace reicht hier ein einfacher Befehl der mit Dokument-IDs arbeitet. Die IDs findet man einerseits in der URL des Tabellendokuments und in den Einstellungen des Kalenders.

Daten auslesen und bereinigen
Das Skript geht dabei wie folgt vor:

  1. Die erste Spalte A wird nach einem bestimmten Namen durchsucht. (z.B. Bihlmayer in Zeile 21)
  2. Nun werden alle Zellen in der Zeile auf Einträge durchsucht. (Zelle D21: Lager Inventur)
  3. Ist ein Eintrag vorhanden wird aus Zeile 3 in der betreffenden Spalte das Datum ausgelesen. (Zelle D3: Mi. 8.1.)
  4. Die restlichen Informationen für den Kalendereintrag werden aus der Zelle selbst ausgelesen. («09:00-17:30 Lager Inventur»)
  5. Dieser Vorgang wiederholt sich für alle Tabellenblätter. (KW1 bis KW52)

Mein Chef macht sich hin und wieder Notizen zu Überstundenkonto und Urlaubstagen. Zum Glück macht er diese im immer gleichen Format, sodass CTC diese Notizen einfach ignorieren kann. Schwieriger war es mit den Zeiten, denn mein Chef schreibt diese nicht immer gleich. Ich musste CTC also beibringen, dass Zeiten aussehen können wie 09.00 09:00 9.00 oder 9:00.

Einträge im Kalender erstellen
CTC erstellt nun für alle gefundenen Ereignisse einen Kalendereintrag nach folgendem Schema:

  • Der Titel des Kalendereintrags ist der gleiche Text wie auch im Dienstplan steht. 
  • Hat ein Eintrag eine Beginn- und eine Endzeit vermerkt wird ein Kalendereintrag mit den entsprechenden Zeiten erstellt.
  • Hat ein Eintrag keine Zeiten vermerkt wird automatisch 09:00 – 17:30 im Kalender eingetragen.
  • Gibt es nur eine Beginnzeit, dann wird ein Eintrag mit dieser Beginnzeit plus automatisch 8,5 Stunden erstellt.
  • Ist ein Tag mit xxxx vermerkt dann wird ein Ganztägiger Kalendereintrag mit dem Titel „Geblockter Tag“ erstellt. 
  • Bei den Einträgen EWE (Ersatzwochenende), ZA (Zeitausgleich), WE, Urlaub, Feiertag, angefragt, geht, usw. wird ein Ganztägiger Eintrag mit eben diesem Titel erstellt.

Bei Einträgen die nur eine Beginnzeit haben und somit automatisch 8,5 Stunden lang sind, bin ich schnell auf ein Problem gestossen. Wenn die Beginnzeit nach 15:30 Uhr lag ging die Arbeitszeit über Mitternacht hinaus und der Code erkannte keinen Überlauf auf den nächsten Tag, sondern lieferte die Fehlermeldung: «Endzeit ist kleiner als Beginnzeit».
Also habe ich CTC so angepasst, dass jeder Kalendereintrag mit einer Startzeit nach 15:30 automatisch die Endzeit 23:59 erhält. Das verhindert auch verwirrende Kalendereinträge.

Email Benachrichtigung
Wenn all diese Vorgänge abgeschlossen sind versendet CTC eine Email an eine bestimmte Email Adresse. GAS macht auch das wieder sehr einfach.

emailRecipient und emailBody sind in Variablen gespeichert. Dazu komme ich gleich noch.

Laufende Aktualisierung
Nun muss CTC natürlich auch regelmässig ausgeführt werden, damit sich die Kalendereinträge auch aktualisieren. GAS macht aus das mit seinem intregrierten Cron-Job Tool «Trigger» sehr einfach. Über diese Funktion kann ein regelmäßiges Abspielen des Skripts programmiert werden.

Bevor ein Kalendereintrag aber effektiv in den Kalender geschrieben wird, passiert ein kleiner Zwischenschritt. Dieser stellt sicher dass Veränderungen in den Dienstplaneinträgen berücksichtigt werden.

  1. CTC kontrolliert, ob für den Tag, an dem ein Dienstplaneintrag gefunden wurde, bereits ein Kalendereintrag besteht.
  2. Ist kein Kalendereintrag vorhanden wird ganz normal fortgefahren und ein Ereignis erstellt.
  3. Ist für den entsprechend Tag bereits ein Ereignis vorhanden wird abgeglichen ob die Inhalte identisch sind.
  4. Sind sie nicht identisch wird der bestehende Kalendereintrag gelöscht und von dem Neuen überschrieben. Ansonsten wird dieser Tag einfach übersprungen und nichts passiert.

Wird in einer Zelle des Tabellendokuments kein Eintrag gefunden, vergleicht CTC ob für diesen Tag ein Kalendereintrag besteht. Wenn es einen gibt, dann wird dieser natürlich gelöscht.

4. Serienreife

Damit CTC auch bei meinen Kollegen funktioniert braucht es nur drei Variablen welche für jeden Mitarbeitenden individuell sind.

Der Name nach dem im Dienstplan gesucht werden soll:

Die KalenderID des Kalenders in den die Einträge gespeichert werden sollen:

Die Email Adresse an welche die Benachrichtigung geschickt werden soll:

Während des Entwicklungsprozesses habe ich immer die gleiche Kalender-ID und Email Adresse verwendet. Um die Funktionsweise zu überprüfen habe ich allerdings jedes mal den zu suchenden Namen ausgetauscht um verschiedene Ergebnisse zu erzielen.

Nachdem die Funktionalität überprüft war, ging es nur noch darum CTC irgendwie serienreif zu machen und eine Lösung für die Distribution an meine Arbeitskollegen zu finden.
Ich habe lange versucht den originalen Code als WebApp ebenfalls über GAS bereit zu stellen. Jedoch scheiterte das an den individuellen Eingaben. Prinzipiell wäre es möglich eine online Eingabemaske per html zu erstellen und mit dem Code zu verknüpfen, allerdings würde dann aber jeweils eine Person quasi den gesamten Code übernehmen. Google Apps Script ist nicht für diese Art der Distribution ausgelegt. Es braucht für jeden Nutzer eine eigene Iteration des Codes, damit der Prozess für jeden Google Benutzer unabhängig funktioniert.

Also habe ich eine detaillierte Anleitung geschrieben, wie das Tool installiert werden kann. Diese Anleitung findest du hier.

5. Fazit

Die Entwicklung von CTC hat mir nicht nur geholfen, meinen eigenen Arbeitsalltag besser zu organisieren, sondern auch meinen Kollegen die Planung ihrer Einsätze zu erleichtern. Durch die Automatisierung des Dienstplans wurde ein System geschaffen, das Fehlerquellen minimiert und gleichzeitig die Effizienz steigert.

Besonders spannend war die Auseinandersetzung mit Google Apps Script, das zwar mächtig, aber nicht immer benutzerfreundlich ist. Die grösste Herausforderung bestand darin, eine Lösung zu finden, die nicht nur für mich funktioniert, sondern auch von anderen Mitarbeitenden genutzt werden kann. Während der Code in sich gut funktioniert, bleibt die Verteilung an andere Nutzer eine Schwachstelle, da Google Apps Script keine einfache Möglichkeit bietet, ein solches Tool als universelle Web-App zu deployen.

Nichtsdestotrotz zeigt dieses Projekt, dass es oft keine teuren oder komplexen Drittanbieter-Lösungen braucht, um alltägliche Probleme zu lösen. Manchmal reicht es, die vorhandenen Tools kreativ zu nutzen. Für die Zukunft wäre eine Weiterentwicklung spannend, die eine noch einfachere Installation und Nutzung ermöglicht – vielleicht durch eine tiefere Integration mit Google Workspace oder alternative Technologien.

Letztendlich hat sich der Aufwand gelohnt: Der Chaos-Dienstplan wurde zu einem strukturierten und automatisierten Kalender – CTC macht seinem Namen also alle Ehre.

Den gesamten Code findest du unter diesem Link. Aus Sicherheitsgründen ist diese Version nicht funktional, denn der Dienstplan ist ein firmeninternes Dokument.

Der grösste Lernprozess in diesem Projekt war für mich die Arbeit mit Google Apps Script (GAS). Obwohl es auf JavaScript basiert, musste ich mir die spezifischen Funktionen und die Arbeitsweise von GAS komplett neu beibringen. Gerade die Verknüpfung zwischen Tabellen und Kalender stellte mich vor Herausforderungen, weil ich zunächst nicht wusste, wie man die Daten korrekt ausliest und verarbeitet.

Dabei hat mir ChatGPT sehr geholfen. Allerdings war es nicht einfach ein Copy-Paste-Prozess. Die grösste Herausforderung war, dass ich mir die Logik und Systematik des Skripts selbst überlegen musste: Welche Schritte in welcher Reihenfolge ablaufen müssen, welche Daten verarbeitet werden und wie der Code sicherstellt, dass die Einträge korrekt erstellt und aktualisiert werden. Das hat mir ein tieferes Verständnis für Codestruktur und Befehlsablauf eines Skripts ermöglicht.
Nach einer Weile hatte ich mit ChatGPT das Problem dass es begonnen hat zu vergessen. Es hat nur noch die Teile des Codes beachtet welche für die aktuelle Anfrage relevant waren und hat daraufhin einfach andere Teile des Codes weggelassen bzw. gelöscht hat. Dementsprechend aufwändig war es dann immer einzelne Codeabschnitte in den Originalcode einzubauen, sodass es auch zusammenpasst und funktioniert. Spannend war aber, dass ich durch diesen Prozess nicht nur Syntax und Funktionen gelernt habe, sondern auch ein besseres Gespür für Code-Struktur und Fehlersuche entwickelt habe. Ich habe gelernt, wie man Vorschläge der KI kritisch hinterfragt, gezielt debuggt und Stück für Stück eine funktionierende Lösung erarbeitet. Gleichzeitig wurde mir bewusst, dass eine KI zwar Unterstützung bietet, aber nicht alle Probleme eigenständig lösen kann – gerade wenn es um die übergeordnete Logik und das Zusammenspiel verschiedener Systeme geht.

Herausforderungen & Learnings

Ich bin im Laufe des Entwicklungs- und Testprozesses auf mehrere Fehler gestossen, die ich erst nach und nach lösen musste:

  • Die unterschiedlichen Zeitformate im Dienstplan (09.00, 09:00, 9.00, 9:00) führten dazu, dass das Skript manche Zeiten nicht erkannte. Ich musste also eine Methode entwickeln, die verschiedene Formate einheitlich umwandelt.
  • Das Skript erkannte Mitternacht und Überläufe auf den nächsten Tag nicht, wenn Endzeiten automatisch ergänzt wurden. Dadurch kam es zu Fehlern bei späten Arbeitszeiten.
  • Ein grosser Stolperstein war, dass ursprünglich für jeden Skriptlauf ein neuer Eintrag erstellt wurde, anstatt den alten zu überschreiben. Erst durch eine Abfrage, ob für den jeweiligen Tag bereits ein Eintrag existiert, konnte ich dieses Problem lösen.
  • Auch das Löschen von Kalendereinträgen war anfangs fehlerhaft. Wenn eine Schicht im Dienstplan entfernt wurde, blieb der Kalendereintrag bestehen. Ich musste eine Methode implementieren, die das überprüft und veraltete Einträge löscht.

Ein weiteres grosses Learning war der Umgang mit unstrukturierten Daten. Während Tabellen eigentlich geordnete Daten enthalten sollten, war das in der Praxis nicht immer der Fall. Mein Chef machte sich Notizen in den Zellen und schreibt nicht immer gleiche Aufgaben im gleichen Format. Ich musste daher immer alle Inhalte die das Gleiche bedeuten zusammensuchen und eine Logik entwickeln, die eben diese Einträge gruppiert erkennt. Ich wusste nämlich dass ich meinem Chef nicht klar machen kann, sich immer an die gleichen Formate zu halten.

Was gut funktioniert hat:

Trotz dieser Herausforderungen gibt es einige Aspekte, die mich doch ein wenig Stolz auf das Projekt machen:

  • Effektive Problemlösung: Ich habe nicht einfach nur Code geschrieben, sondern aktiv nach Lösungen gesucht, wenn etwas nicht funktioniert hat. Besonders stolz bin ich darauf, dass ich komplexe Fehler systematisch analysiert und schrittweise behoben habe.
  • Strukturierte Herangehensweise: Ich habe mir im Vorfeld überlegt, wie das Skript ablaufen soll, anstatt einfach drauflos zu coden. Das hat mir vor allem viel über systematische Zusammenhänge gelehrt und ich bin stolz dass ich mir komplexe Abläufe vorstellen konnte und darauf hin auch funktionell umsetzen.
  • Dankbarkeit meiner Arbeitskollegen: Seitdem mein Tool bei einer Teambesprechung vorgestellt wurde habe ich sehr viele Dankesnachrichten und positives Feedback von meinen Kollegen bekommen. Auch mein Chef ist begeistert von der Lösung. Es freut mich sehr dass ich helfen konnte für alle das Arbeitsumfeld zu verbessern.

Überraschenderweise hat das Coden sehr viel Spass gemacht – überraschend deshalb, weil ich sonst im Modul Interaktive Medien doch recht oft kurz vorm Verzweifeln bin. Ich hoffe damit auch für den kommenden Unterricht eine bessere Grundlage als in den vergangenen Semestern zu haben.