Termine automatisch in Kalender generieren
Hallo,
ich versuche schon jahrelang automatisierte Kalendereinträge zu erstellen, scheitere aber mangels Fachwissen. Das "Baukastenprinzip" führt mich erst recht nicht weiter. Chat GPT wirft mir auch Unbrauchbares aus...
Der Kalender sollte wie folgt generiert werden:
Jeder Schüler hat einen Vertrag (Verknüpfung) aus dessen Datensatz sich Daten für den Kalender entnehmen lassen:
- Beginn des Vertrages
- Wochentag
- Uhrzeit
- Dauer der Unterrichtsstunde
- Schüler aktiv/inaktiv
- Ende des Vertrages
Bedingungen:
- Der Kalender soll wöchentlich Termine ein Jahr im Voraus oder bis Ende des Vertrags erstellen und täglich aktualisieren.
- Termine älter als 2 Jahre sollen gelöscht werden.
- Termine sollen nur erstellt werden, wenn der Schüler als "aktiv" markiert ist.
Ich hoffe auf Euer wohlwollendes Fachwissen!
Manni
19 Antworten
-
Die KI hat mir folgenden Code ausgegeben, leider sind in der ersten Zeile Fehlermeldungen: rot unterstrichen sind: =base. ,der Punkt hinter ("Verträge") und das Semikolon:
let contracts = base.tables("Verträge").selectRecords(); // Lesen Sie alle Vertragsdatensätze
let calendar = base.tables("Kalender"); // Referenz auf den Kalender-Datensatzfor (let i = 0; i < contracts.length; i++) {
let contract = contracts[i];
let startDate = contract.field("Beginn des Vertrages");
let endDate = contract.field("Ende des Vertrags");
let dayOfWeek = contract.field("Wochentag");
let time = contract.field("Uhrzeit");
let duration = contract.field("Dauer der Unterrichtsstunde");
let isActive = contract.field("Schüler aktiv/inaktiv");if (!isActive) {
continue;
}// Berechne das Enddatum der aktuellen Woche
let currentWeekEnd = new Date();
currentWeekEnd.setDate(currentWeekEnd.getDate() + (7 - currentWeekEnd.getDay()));
// Berechne das Enddatum des nächsten Jahres
let nextYearEnd = new Date();
nextYearEnd.setFullYear(nextYearEnd.getFullYear() + 1);
// Verwende das frühere Datum als Enddatum
let targetEndDate = (endDate && endDate < nextYearEnd) ? endDate : nextYearEnd;// Berechne das Startdatum der nächsten Woche
let nextWeekStart = new Date(currentWeekEnd.getTime());
nextWeekStart.setDate(nextWeekStart.getDate() + 1);
// Verwende das spätere Datum als Startdatum
let targetStartDate = (startDate > nextWeekStart) ? startDate : nextWeekStart;while (targetStartDate <= targetEndDate) {
// Überprüfen Sie, ob der aktuelle Tag dem Wochentag entspricht
if (targetStartDate.getDay() === dayOfWeek) {
let existingEvent = calendar.findFirst({
"Schüler": contract.field("Schüler"),
"Datum": targetStartDate,
"Uhrzeit": time
});if (existingEvent) {
existingEvent.update({
"Dauer": duration,
"Schüler": contract.field("Schüler"),
"Vertrag": contract.id
});
} else {
calendar.createRecord({
"Datum": targetStartDate,
"Uhrzeit": time,
"Dauer": duration,
"Schüler": contract.field("Schüler"),
"Vertrag": contract.id
});
}
}// Fügen Sie eine Woche zum Zielstartdatum hinzu
targetStartDate.setDate(targetStartDate.getDate() + 7);
}
} -
Hallo Manfred,
schau Dir einmal die Datenbank an, welche ich im Anhang beigefügt habe. Im Dashboard kannst Du die Termine über den "Sync" Button aktualisieren. Sollen die Termine automatisch synchronisiert werden, aktiviere die Auswahl "Automatische Synchronisation".
In der Tabelle "Schüler" trägst Du deine Schüler ein und in der Tabelle "Verträge", deine Verträge. Am einfachsten sollte es sein, die Verträge über einen Datensatz eines Schülers zu erstellen / zu verknüpfen.
Folgendes solltest Du beachten:
Zeitbasierte Automatisierungen gehen ohne fremde Anbindung nicht so einfach. Was jedoch funktioniert, ist ein Sync, sobald die Datenbank geöffnet wird. Das sollte ja passen. Möchte man die Termine sehen, muss man die Datenbank dafür öffnen ;-)
Wenn Du dann einen neuen Vertrag anlegst oder das Vertragsende anpasst, kannst Du den Sync-Button nutzen, um fehlende Termine nachzutragen. .....mir fällt gerade ein, den Fall, wenn ein Vertrag früher beendet wird habe ich nicht berücksichtigt. Derzeit müsste man die Termine, welche plötzlich über das Vertragsende hinaus gehen händisch in der Tabelle "Termine" löschen. Auch wenn ein Schüler seinen Aktiv-Status verliert, wird das derzeit nicht berücksichtigt...Kann ich aber die Tage gerne noch ändern.
Dann gäbe es noch das Problem der Zeitumstellung. In dem Script sind for-Schleifen drin. Diese verlangsamen das Script um einiges, weshalb ich hier die Funktion "do as server" aufrufe. Hierbei ist dann aber das Problem, dass alles auf dem Server durchgeführt wird. Die Sprache ist dort Englisch und die Uhrzeit ist dort um 1 Stunde verschoben. Dafür habe ich im Hintergrund zwei Felder angelegt, welche einmal die lokale Zeit (deines PCs/Browsers) und die Zeit des Servers festhält. Gibt es einen Zeitunterschied, werden die Zeiten entsprechend angepasst. Bitte halte da ein Auge drauf, ob das im Sommer noch richtig funktioniert.
Sonst hoffe ich erstmal, dass ich dein Problem richtig verstanden habe und die Datenbank das tut, was sie soll. Ansonsten kannst Du dich gerne nochmal melden.
Gruß
Patrick -
Noch als Hinweis zu Chat GPT - was das Tool dir da ausgespuckt hat, ist JavaScript. Ninox basiert zwar auf JavaScript, jedoch ist die NX-Scriptsprache für die Endnutzer abgewandelt. JavaScript funktioniert für uns daher nur bedingt mit etwas komplizierten Methoden.
-
Danke, werde es ausprobieren!
-
Ich habe die Datenbank nochmal angepasst.
- Wenn das Vertragsende geändert wurde, werden die Termine, welche darüber hinaus gehen gelöscht.
- Wenn ein Schüler inaktiv wird, werden dessen Termine gelöscht.
- Dafür dann entsprechend den Sync Button drücken oder die Datenbank neu öffnen, wenn automatischer Sync aktiv ist.
Zudem habe ich die Verknüpfung zwischen Verträge und Schüler getauscht. Ein Schüler kann jetzt mehrere Verträge haben, ein Vertrag kann nur einen Schüler haben.
Damit der Code nur einmal vorhanden ist, habe ich diesen in die globalen Funktionen gepackt. Dieser wird dann über das Öffnen der Datenbank oder durch drücken des Sync-Buttons ausgeführt. Das macht spätere Änderungen einfacher.
-
Hallo Patrick, da funktioniert bei mir leider nicht. Der Termin des Schülers wird nur blau im Kalender angezeigt, ohne Uhrzeit. Würde es Sinn machen, wenn ich meine Datenbank poste? Die ist allerdings ziemlich groß...
-
Der Dumme sitzt immer vor dem Computer... jetzt geht das. Wo finde ich den die globalen Funktionen? Du musst bedenken, ich bim Musiker und kann nur drag&drop...:-)
-
Hallo nochmal Patrick, ich glaube so wird das nichts. Ich weiß nicht wo ich Änderungen in meiner vorhandenen Datenbank einsetzten soll. Daher schicke ich mal eine abgespeckte Version von meinen Daten. Wenn das machbar ist, könntest Du mir vielleicht mitteilen, wo ich in der Original- Datenbank Änderungen vornehmen muss. Oder Du hast eine andere Idee...
-
Hallo Manfred,
versuchen wir es mal:
- Tabelle Dashboard erstellen
- Button Sync erstellen
- Ja/Nein Feld Automatische Synchronisation erstellen
- Uhrzeit-Feld localTime erstellen
- Uhrzeit-Feld serverTime erstellen
- Tabelle Termine erstellen
- Terminfeld Termin erstellen
- Verknüpfung ==> auf die Untertabelle Vertrag
- Anpassung Untertabelle Vertrag
- Neues Auswahlfeld (nicht Mehrfachauswahlfeld!) Unterrichtsdauer2 einfügen und die Parameter 0:30, 0:45, 1:00 hinzufügen
- Neues Zeitdauer Feld einfügen (Name bleibt gleich)
- Bei dem Feld das Zahlenformat auf 61:16 stellen
- Nun gehst Du nochmal auf das neue Feld Unterrichtsdauer2 und fügst bei Trigger nach Änderung folgenden Code ein:
switch Unterrichtsdauer2 do case 1: Zeitdauer := 30 * 60 * 1000 case 2: Zeitdauer := 45 * 60 * 1000 case 3: Zeitdauer := 60 * 60 * 1000 end
Ich arbeite nicht viel mit dem Kalender und mit dem Feld Zeitdauer. Das war in deinem Szenario das einfachste, die Dauer des Termins anzugeben. Wenn jemand von den anderen Kollegen hier im Forum weiß wie man die Dauer direkt über ein Auswahlfeld in den Termin bringen kann, hoffe ich auf Rückmeldung :-)
- Das Feld Unterrichtsdauer entfernen, wenn Du alle Unterrichtszeiten der Verträge auf das neue Feld übertragen hast (das ist ein Mehrfachauswahlfeld)
- Jetzt gehst Du nochmal zurück zur Tabelle Termine und fügst im Feld Termin unter Anzeigen als folgenden Code ein:
'Vertrag'.'Schüler'.Vorname + " " + 'Vertrag'.'Schüler'.Nachname + " Dauer: " + 'Vertrag'.Zeitdauer + " Vertragsbeginn: " + 'Vertrag'.Beginn + " Vertragsende: " + 'Vertrag'.Ende
Nun fügst Du die globale Funktion ein:
Klicke auf Musik Zone2 (oben Links - damit kommst Du in das Hauptmenü der Datenbank)
Dann oben in den Reitern auf Optionen und unten taucht ein Feld mit Globale Funktionen auf. Dort fügst Du folgenden Code ein:
function contractDeleteInactive() do do as server for i in select 'Schüler' where Aktiv != true do delete (select Termine where contains(text(number(Vertrag.'Schüler')), text(i.Nr))) end end end; function contractDeleteOverEnd() do do as server for i in select Vertrag do delete (select Termine where date(Termin) > i.Ende) end end end; function contractSync() do do as server record(Dashboard,1).(serverTime := now()) end; do as server let myDate := today(); let myDay := format(myDate, "dd"); let mySDay := 0; let myDays := 0; switch myDay do case "Mo": (mySDay := 1) case "Tu": (mySDay := 2) case "We": (mySDay := 3) case "Th": (mySDay := 4) case "Fr": (mySDay := 5) end; for i in select Vertrag where 'Schüler'.Aktiv and (Ende >= today() or Ende = null) do let myTermin := myDate; let myTDay := number(i.Wochentag); if myTDay = mySDay then myTermin := myDate else if myTDay > mySDay then myDays := myTDay - mySDay; myTermin := myTermin + myDays else if myTDay < mySDay then myDays := mySDay - myTDay; myTermin := myTermin - myDays + 7 end end end; let myUhrzeit := i.Uhrzeit; let myDauer := i.Zeitdauer; for n from 0 to 365 step 7 do let myUhrzeitStart := myUhrzeit; let myUhrzeitEnd := myUhrzeit + myDauer; if record(Dashboard,1).localTime > record(Dashboard,1).serverTime then myUhrzeitStart := myUhrzeit - timeinterval(60 * 60 * 1000); myUhrzeitEnd := myUhrzeit + myDauer - timeinterval(60 * 60 * 1000) end; let myCheck := true; for m in select Termine do if m.Termin = appointment(date(myTermin) + n + myUhrzeitStart, date(myTermin) + n + myUhrzeitEnd) and m.Vertrag = i then myCheck := false end end; if date(myTermin) + n > date(i.Ende) then myCheck := false end; if myCheck then let myRec := (create Termine); myRec.(Vertrag := i.Nr); myRec.(Termin := appointment(date(myTermin) + n + myUhrzeitStart, date(myTermin) + n + myUhrzeitEnd)) end end end end end; function syncTrigger() do record(Dashboard,1).(localTime := now()); contractDeleteInactive(); contractDeleteOverEnd(); contractSync() end
Als nächstes die Änderungen oben rechts speichern, damit die Funktionen geladen werden.
Nun gehst Du eins weiter runter auf Trigger anch Öffnen (unter den globalen Funktionen) und fügst folgenden Code ein:
let mySync := record(Dashboard,1).'Automatische Synchronisation'; if mySync then syncTrigger() end; openRecord(record(Dashboard,1))
Und zum Schluss noch in das Dashboard auf den Sync-Button mit folgendem Code:
syncTrigger()
Denke bitte daran, die entsprechenden Schüler noch auf Aktiv zu setzen.
Wenn gewünscht, kannst Du in der Tabelle Vertrag jetzt wieder das Feld Unterrichtsdauer2 in Unterrichtsdauer umbenennen. Der Code übernimmt die Änderung im Hintergrund mit.
Noch ein Tipp: Wenn Du ein Feld hast, was in der normalen Nutzerumgebung nicht sichtbar sein soll, wie im Dashboard z.B. localTime und serverTime oder unter Vertrag das neue Feld Zeitdauer, gehe in dem jeweiligen Feld auf Feld nur anzeigen, wenn: und füge folgendes ein:
isAdminMode()
Dann wird das Feld nur angezeigt, wenn Du den Admin-Modus aktiv hast.
Ich habe Dir die Anpassung in deine Datenbank nochmal im Anhang beigefügt, da kannst Du ggf. gegenprüfen. Wichtig ist, dass Du die Reihenfolge bezüglich des Codes oben einhälst, da der Code sonst noch nicht alle neuen Felder erkennt.
Ich hoffe es ist soweit verständlich. Viel Glück :-)
- Tabelle Dashboard erstellen
-
Nochmal vielen Dank! Ich melde mich ob es klappt :-)
-
Mit ein paar kleinen Anpassungen hat es denn geklappt! :-)
Ist es auch möglich, einen einzelnen Termin per drag&drop zu verschieben?
-
Das freut mich zu hören :-)
Ich habe gerade nur ein iPad vor mir. Da geht Drag & Drop wohl nicht. Ob das grundsätzlich an einem PC geht weiß ich nicht. Bei einer Gantt-Ansicht in der Tabelle "Termine" ginge das. Man müsste dann aber generell den Code anpassen, da er sonst den leer gewordenen Termin-Slot wieder befüllt. Ich werde am Montag mal schauen, welche Möglichkeiten es da gibt.
-
Das mit dem Drag& Drop wäre schon wichtig, wenn ich einen Schüler verschieben muss, der z.B krank ist. Notfalls sollte es auch möglich sein, den entsprechenden Termin per Tastatureingabe zu ändern.
Nach meinem bescheidenen Fachwissen sollte dann noch eine Abfrage, ob der Datensatz leer ist, gestellt werden, damit nur dann ein Jahr im Voraus automatisch Termine angelegt werden. (Es kommt vor, dass im Datensatz des Vertrags kein Endtermin vorgegeben ist!). Wenn schon Termine vorhanden sind, sollten dann jede Woche nach dem letzten Termin einer dran gehängt werden.
-
Es sollte auch möglich sein, einen Schüler grundsätzlich auf einen anderen Termin zu legen, wenn das im Vertrag geändert wird...bestehende künftige Termine müssten dann gelöscht werden.
-
Hallo Patrick, müssen die Anpassungen zusätzlich zu den bereits gemachten eingetragen werden, oder ersetzen sie die vorangegangenen komplett?
-
Also, ich bekomm es nicht hin, da im Code Fehlermeldungen erscheinen. Ich schick mal eine Mail mit der Datenbank.
Content aside
- vor 1 JahrZuletzt aktiv
- 19Antworten
- 330Ansichten
-
3
Folge bereits