Calc-Fotokalender mit Formeln

Aus EasyLinux 04/2017

Calc-Fotokalender mit Formeln

© homestudio, 123RF

Kalender-Automat

In der Tabellenkalkulation Calc können Sie Zellinhalte nicht nur berechnen, sondern auch von Inhalten anderer Zellen und weiteren Faktoren abhängig machen. Den Jahreskalender aus dem vorherigen Artikel können Sie damit fast automatisch erzeugen.

Wenn Ihnen das manuelle Ausfüllen der Kalenderblätter, wie Sie es im vorherigen Artikel gesehen haben, zu umständlich ist, können Sie das auch von Calc erledigen lassen. Das setzt allerdings voraus, eine etwas längliche Formel zu basteln, die für jeden Monat erkennen kann, an welche Positionen die Tageszahlen 1 bis 31 gehören (und wie viele Tage jeder Monat hat, so dass z. B. der Februar korrekt bei 28 oder in Schaltjahren bei 29 endet). Wir zeigen Schritt für Schritt, wie die richtige Formel entsteht.

Automatisierung

Zunächst überlegen wir, wie viele Zeilen mit Kalendertagen gefüllt werden. Betrachen Sie zum Beispiel den August 2016, der mit einem Montag beginnt:

$ cal 8 2016
    August 2016
Mo Di Mi Do Fr Sa So
 1  2  3  4  5  6  7
 8  9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31

Die Tage verteilen sich auf fünf Zeilen, und das ist in den meisten Monaten so. Es sind aber auch vier oder sechs Zeilen möglich:

  • Beginnt der Monat Februar mit einem Montag und liegt in keinem Schaltjahr (hat also 28 Tage), reichen vier Zeilen aus.
  • Hat ein Monat 30 oder 31 Tage und beginnt an einem Samstag oder Freitag (oder noch später), wird eine sechste Zeile nötig.

Wir planen darum sechs Zeilen ein und füllen diese zunächst mit je sieben Werten (einer pro Tag), wofür wir eine Formel verwenden: Diese berechnet abhängig von Zeilen- und Spaltennummer die Zahlen 1 bis 42. Die Position in der Tabelle können Sie in Calc über die Funktionen ZEILE() und SPALTE() abfragen, die Werte sind jeweils ab 1 nummeriert – in Zelle B5 hat also ZEILE() den Wert 5 und SPALTE() den Wert 2.

Da wir in Zelle A4 (wie im vorherigen Artikel) die erste Zahl sehen wollen, ergibt sich die Formel

=7*(ZEILE()-4)+SPALTE()

Wenn wir diesen Wert in alle relevanten Felder (A4–G9) eintragen, ergibt sich das wenig hilfreiche Bild aus Abbildung 1.

Abbildung 1: Ein Kalenderblatt mit 42 Tagen lässt das gewünschte Ergebnis noch nicht erahnen.

Abbildung 1: Ein Kalenderblatt mit 42 Tagen lässt das gewünschte Ergebnis noch nicht erahnen.

Der bisher erzeugte Kalender hat zu viele Tage und beginnt an einem Montag – wir kümmern uns zuerst um das zweite Problem und betrachten dazu den Januar 2017: Er beginnt an einem Sonntag (das ist der Tag mit der Nummer 7 in der gängigen Reihenfolge Montag–Sonntag), also sollte die Zahl 1 in der letzten Spalte stehen. Wir können das erreichen, indem wir in der Formel den Wert 6 abziehen. Die neue Formel lautet also

=7*(ZEILE()-4)+SPALTE()-6

Der Februar 2017 beginnt an einem Mittwoch (Tag 3), und hier wäre entsprechend eine Korrektur in der Form

=7*(ZEILE()-4)+SPALTE()-2

nötig, damit die Zahlen an den richtigen Positionen stehen. Allgemein gilt: Wir müssen herausfinden, mit welchem Wochentag ein Monat beginnt, dann diese Tageszahl abziehen und 1 addieren. Calc bietet die Funktionen WOCHENTAG() und DATUM(), die genau das leisten, so gilt z. B. WOCHENTAG(DATUM(2017;1;1);2) = 7: Der 01.01.2017 ist ein Sonntag. Dieser verschachtelte Aufruf erzeugt zunächst mit DATUM(2017,1,1) einen Calc-Datumswert für den ersten Januar, der äußere Aufruf von WOCHENTAG() berechnet dann einen Wert zwischen 1 und 7 (für Montag–Sonntag). Der zusätzliche Parameter 2 von WOCHENTAG() ist nötig, um der Funktion zu sagen, dass sie die deutsche Tageszählung 1–7 für Montag–Sonntag verwenden soll; in anderen Ländern ist es üblich, die Woche am Sonntag zu beginnen. Wenn Sie die “2” durch “1” oder “3” ersetzen, erhalten Sie abweichende Werte.

Damit können wir die Formel in einem weiteren Schritt in

=7*(ZEILE()-4)+SPALTE()-WOCHENTAG(DATUM(2017;1;1);2)+1

umwandeln (und in jedes Feld kopieren). Abbildung 2 zeigt den Zwischenstand: Die Tage stehen an der richtigen Position, aber es gibt immer noch zu viele davon, darunter jetzt auch Tageszahlen 0, -1 usw.

Abbildung 2: Hier stehen die Tage schon an den richtigen Stellen, es gibt aber noch zu viele davon.

Abbildung 2: Hier stehen die Tage schon an den richtigen Stellen, es gibt aber noch zu viele davon.

Zwölf Monate

In einem Zwischenschritt passen wir die Formel so an, dass sie für alle zwölf Monate des Jahres funktioniert: Das setzt voraus, dass Sie (wieder wie im vorherigen Artikel) zwölf Tabellen anlegen, welche die Monate Januar bis Dezember enthalten.

Über die Calc-Funktion TABELLE() kann man herausfinden, in welcher der zwölf Tabellen man sich befindet, die Funktion gibt eine Zahl zurück, wobei die Nummerierung bei 1 beginnt. In der Datumsformel kann man also die “1” (für den Januar) durch TABELLE() ersetzen, womit sich

=7*(ZEILE()-4)+SPALTE()-WOCHENTAG(DATUM(2017;TABELLE();1);2)+1

ergibt. Um den Kalender später leicht an die Jahre 2018, 2019 usw. anpassen zu können, tragen Sie in der ersten Tabelle (für den Januar) im Feld B1 die Zahl 2017 ein. Geben Sie der ersten Tabelle (unten bei den Reitern) den Namen Januar (und benennen Sie bei Bedarf die übrigen elf Tabellen entsprechend mit den Monatsnamen), dann können Sie sich in der Formel über $Januar.$B$1 darauf beziehen. (Die drei Dollar-Zeichen sorgen dafür, dass der Zellbezug auf Tabelle, Zeile und Spalte absolut ist, sich beim Kopieren von Formeln also nicht verschiebt.) Die angepasste Formel lautet nun

=7*(ZEILE()-4)+SPALTE()-WOCHENTAG(DATUM($Januar.$B$1;TABELLE();1);2)+1

Über einen ähnlichen Trick können Sie auch den Monatsnamen in Zelle A2 automatisch erzeugen: Tragen Sie dazu in diese Zelle die Formel

=DATUM($Januar.$B$1;TABELLE();1)

ein. Es erscheint dann zunächst eine Datumsangabe (01.01.2017), die Sie über die Zellformatierung auf Datum / Dezember (mit Formatcode MMMM) umstellen.

Kopieren Sie die Inhalte aus der Januar-Tabelle vollständig in die übrigen elf Tabellen, ist der Jahreskalender – bis auf die überflüssigen Tage – schon fertig (Abbildung 3).

Abbildung 3: Diese Version des Kalenders enthält schon zwölf Monate in separaten Tabellen, die alle Tage korrekt platzieren und die Wahl des Jahres durch Änderung der Zelle Januar.B1 erlauben.

Abbildung 3: Diese Version des Kalenders enthält schon zwölf Monate in separaten Tabellen, die alle Tage korrekt platzieren und die Wahl des Jahres durch Änderung der Zelle Januar.B1 erlauben.

Nur echte Tage

In einem letzten Schritt gilt es nun, die überflüssigen Tage rauszufiltern. Im vorderen Teil sind das die negativen Zahlen und die Null, im hinteren Teil ist zunächst die Zahl der Monate im Jahr zu bestimmen. Das ist über die Calc-Funktion TAGEIMMONAT() möglich, die ein Datum als Argument erwartet und dann (je nach Monat und Jahr) 28, 29, 30 oder 31 ausgibt.

Tageszahlen sollen auf dem Kalenderblatt also nur dann erscheinen, wenn die folgenden zwei Bedingungen erfüllt sind:

  • Die Tageszahl ist größer als 0 (damit die “falschen Tage” 0, -1, -2 usw. verschwinden).
  • Die Tageszahl ist kleiner oder gleich der Zahl der Tage im Monat (womit die “zu großen” Tage verschwinden).

Dafür benötigen wir die Calc-Funktionen WENN() und UND():

  • Mit WENN() können wir eine Bedingung prüfen und abhängig vom Ergebnis einen von zwei angegebenen Werten in die Zelle eintragen.
  • Mit UND() lassen sich zwei Bedingungen verknüpfen: Es müssen beide Tests positiv ausgehen, damit auch UND(Test1,Test2) eine positive Rückmeldung gibt.

Die Grundidee ist also, in zwei Bedingungen die Tests “Tag nicht zu klein” und “Tag nicht zu groß” zu formulieren, die beiden Auswertungen mit UND zu verknüpfen und dann mit WENN() im positiven Fall die Tageszahl zu erzeugen. Im negativen Fall soll die Zelle leer bleiben: Wir tragen dann den leeren Text "" ein.

Nehmen wir für einen Moment an, dass wir die Tageszahl als TAG in Formeln verwenden könnten. Dann ergibt sich schrittweise:

  • WENN(TAG > 0; TAG; "") als Test für ausreichend große Tageszahlen,
  • WENN(TAG < 1+TAGEIMMONAT(DATUM($Januar.$B$1;TABELLE();1)); TAG; "") als Test für ausreichend kleine Tageszahlen und
  • WENN(UND(TAG > 0 ; TAG < 1+TAGEIMMONAT(DATUM($Januar.$B$1;TABELLE();1))); TAG; "") als kombinierte Formel, bei der beide Bedingungen erfüllt sein müssen, um eine Tageszahl auszugeben.

Dabei müssen wir aber TAG an allen Stellen durch die Formel für die Berechnung der Tageszahl (also: 7*(ZEILE()-4)+SPALTE()-WOCHENTAG(DATUM($Januar.$B$1;TABELLE();1);2)+1) ersetzen. Das ergibt den folgenden komplexen Ausdruck

=WENN(UND(7*(ZEILE()-4)+SPALTE()-WOCHENTAG(DATUM($Januar.$B$1;TABELLE();1);2)+1 > 0 ; 7*(ZEILE()-4)+SPALTE()-WOCHENTAG(DATUM($Januar.$B$1;TABELLE();1);2)+1 < 1+TAGEIMMONAT(DATUM($Januar.$B$1;TABELLE();1))); 7*(ZEILE()-4)+SPALTE()-WOCHENTAG(DATUM($Januar.$B$1;TABELLE();1);2)+1; "")

und Abbildung 4 zeigt das Resultat: Im Januar (und nach dem Kopieren in die übrigen Tabellen auch dort) sind nun nur noch die Tage zu sehen, die es auch tatsächlich im jeweiligen Monat gibt. In Listing 1 sehen Sie die Formel in einer Darstellung, die Programmierern entgegen kommt: Der Aufbau ist dort besser verständlich. In LibreOffice Calc müssen Sie die Formel aber als langen Einzeiler eingeben – und das nur einmal (z. B. in Zelle A4, wo dann nur ein leeres Feld sichtbar ist). Dann kopieren Sie die Zelle mit [Strg]+[C], markieren alle Tagesfelder des Januars (A4–G10) und fügen die Formel mit [Strg]+[V] ein.

Abbildung 4: Nach dem Erg&auml;nzen der Bedingungen mit "WENN()" und "UND()" ist der Kalender fertig.

Abbildung 4: Nach dem Ergänzen der Bedingungen mit “WENN()” und “UND()” ist der Kalender fertig.

Listing 1

Die Masterformel

=WENN(
   UND(
      7*(ZEILE()-4)+SPALTE()-WOCHENTAG(
         DATUM($Januar.$B$1;TABELLE();1);2)+1 > 0 ;
      7*(ZEILE()-4)+SPALTE()-WOCHENTAG(
         DATUM($Januar.$B$1;TABELLE();1);2)+1 <
         1+TAGEIMMONAT(DATUM($Januar.$B$1;TABELLE();1))
   );
   7*(ZEILE()-4)+SPALTE()-WOCHENTAG(
       DATUM($Januar.$B$1;TABELLE();1);2)+1;
   ""
)

Markieren Sie dann die gesamte Tabelle mit [Strg]+[A] und kopieren Sie sie in die Zwischenablage. Wechseln Sie für alle übrigen elf Monate in die zugehörige Tabelle, markieren Sie dort mit [Strg]+[A] die ganze Tabelle und drücken Sie [Strg]+[V], um eine Kopie des Januar-Tabelle einzufügen. Beispiele für Kalenderblätter, die alle sechs Zeilen für die Tagesanzeige benötigen, finden Sie im Juli und Oktober (2017).

Damit steht das technische Gerüst. Jetzt können Sie, wie im vorherigen Artikel beschrieben, noch Bilder einfügen, um die zwölf Kalenderblätter zu individualisieren – fertig. Wenn danach im Januar-Blatt die Jahresangabe (2017) noch sichtbar sein sollte, ändern Sie die Schriftfarbe in diesem Feld. Um später Kalender für 2018 oder 2019 zu erzeugen, ändern Sie dann nur den Inhalt im Feld Januar.B1 und können sofort den Kalender für das neue Jahr drucken. Übrigens: Wenn Sie die Formeln nicht selbst eingeben möchten, können Sie auch einfach die fertige Kalenderdatei verwenden, die wir unter programme/andere/monatskalender/Monatskalender-mit-Formeln.ods auf die Heft-DVD gepackt haben.

Wünschen Sie sich für Ihre Calc-Tabellen noch mehr Automatisierung, könnten Sie sich in die Makro-Programmierung einarbeiten: In einem älteren, dreiteiligen Workshop [1,2,3] in EasyLinux haben wir eine Einführung in das Thema gegeben.

Infos

  1. Makro-Workshop, Teil 1: Hans-Georg Eßer, “Tabellenprogrammierer”, EasyLinux 04/2008, S. 77 ff., http://linux-community.de/16898
  2. Makro-Workshop, Teil 2: Hans-Georg Eßer, “Tabelle unter Kontrolle”, EasyLinux 02/2009, S. 83 ff., http://linux-community.de/17467
  3. Makro-Workshop, Teil 3: Hans-Georg Eßer, “Power-Makros”, EasyLinux 04/2009, S. 67 ff., http://linux-community.de/18622
DIESEN ARTIKEL ALS PDF KAUFEN
EXPRESS-KAUF ALS PDF
EasyLinux 04/2017 KAUFEN
EINZELNE AUSGABE
ABONNEMENTS
TABLET & SMARTPHONE APPS
E-Mail Benachrichtigung
Benachrichtige mich zu:

Hinweis: Dieser Artikel ist älter als ein Jahr, enthaltene Informationen sind möglicherweise veraltet.

0 Kommentare
Älteste
Neuste Beste Bewertung
Nach oben