scheduler — u_pbt_scheduler #
← Komponentenreferenz · Inhalt des Handbuchs
Ein Kalender nach Art von Outlook: Ansichten Tag, Arbeitswoche, Woche, Monat und Agenda, ein Ganztagsband, Ziehen und Ablegen zum Verschieben und Größenändern, Ressourcen nebeneinander, Farb-Kategorien, und Karten und Tooltips, die von Vorlagen geschrieben werden. Er wird Termin für Termin gefüllt oder mit einem einzigen Aufruf aus einem DataStore — und jede Geste des Benutzers gibt Ihnen die zu aktualisierende Zeile zurück.
▶ Live ansehen — Demoanwendung, Kachel Scheduler: die Vorschau, der zugehörige Code und diese Seite, nebeneinander.
Auf einen Blick #
| Userobject | u_pbt_scheduler |
| Item-Klassen | n_pbt_scheduler_appointment (ein Termin, of_appointment) · n_pbt_scheduler_resource (eine Ressource, of_resource) · n_pbt_scheduler_category (eine Kategorie, of_category) |
| Wofür | Dienstplan eines Teams, Buchung von Räumen oder Maschinen, Terminkalender eines Vertreters, Patiententermine — alles, was auf Tagen und Stunden liegt |
| Grenze im Demomodus | Die ersten 12 Termine des sichtbaren Bereichs, nach Beginn; die übrigen bleiben im Speicher, ohne angezeigt zu werden — siehe Der Demomodus |
Schnellstart #
// open event of the window : a few appointments of the week, in one repaint
uo_sched.of_set_redraw(/*on*/ false)
uo_sched.is_date = "2026-09-21"
// A colour category, then the appointments : a key, a subject, a start and an end
uo_sched.of_add_category(/*key*/ "customer", /*label*/ "Customer", /*color*/ RGB(216, 90, 48))
uo_sched.of_add_appointment(/*key*/ "a1", /*subject*/ "Weekly meeting", /*start*/ "2026-09-21 09:00", /*end*/ "2026-09-21 10:00")
uo_sched.of_appointment(/*key*/ "a1").is_location = "Room 3"
uo_sched.of_add_appointment(/*key*/ "a2", /*subject*/ "ACME visit", /*start*/ "2026-09-23 14:00", /*end*/ "2026-09-23 16:30")
uo_sched.of_appointment(/*key*/ "a2").is_category = "customer"
// Dates only : an all-day appointment, both days included
uo_sched.of_add_appointment(/*key*/ "a3", /*subject*/ "Trade fair", /*start*/ "2026-09-24", /*end*/ "2026-09-25")
uo_sched.of_appointment(/*key*/ "a3").ib_all_day = true
uo_sched.of_set_redraw(/*on*/ true)
// ue_appointment_opened event of uo_sched : (string as_key)
// A double-click, or Enter on the selected appointment : open YOUR editor
wf_edit_appointment(as_key)
Den Kalender verstehen #
Die Ansichten #
is_view wählt die Ansicht, is_date den Tag, um den sie aufgebaut wird: seine Woche, sein Monat. Der Benutzer ändert beides über die Symbolleiste der Komponente (Heute, zurück, weiter, Ansichtsmenü) — beide Eigenschaften werden live zurückgelesen, und ue_view_changed / ue_date_changed melden es, ob die Änderung vom Benutzer oder von Ihrem Code kommt.
| Ansicht | Was sie zeigt |
|---|---|
VIEW_DAY | Ein Tag auf einem Stundenraster |
VIEW_WORK_WEEK | Die Arbeitstage der Woche (is_work_days) — die Standardansicht |
VIEW_WEEK | Die sieben Tage, ab ii_first_day_of_week |
VIEW_MONTH | Sechs Wochen; ein mehrtägiger Termin erstreckt sich als Balken über seine Tage |
VIEW_AGENDA | Eine Liste, Tag für Tag, über ii_agenda_days Tage |
Datumsangaben #
Ein Datum reist als Text, "yyyy-mm-dd hh:mm" — in Methoden, Eigenschaften und Events. Es ist eine schwebende Ortszeit: keine Zeitzone, keine Sommerzeit; "2026-09-22 09:00" wird auf jedem Arbeitsplatz um 09:00 angezeigt.
- Das Ende ist exklusiv. Ein Termin von 09:00 bis 10:00 endet um 10:00: Der nächste, der um 10:00 beginnt, überschneidet sich nicht damit. Ohne Ende dauert ein Termin 30 Minuten.
- Ein Datum ohne Uhrzeit schließt seine beiden Tage ein.
"2026-09-24"→"2026-09-25"mitib_all_day = trueist der 24. und der 25. Bei einem Ganztagstermin wird die Uhrzeit ignoriert: Eine datetime-Spalte eines DataWindows, die00:00:00trägt, ergibt Tage, der letzte eingeschlossen. - Was der Kalender ebenfalls annimmt:
"2026-09-22T09:30", Sekunden und den Text einer datetime-Spalte eines DataWindows.of_add_appointmenthat eine Überladung mit zweidatetime-Werten. - Was die Events zurückgeben: die Daten in der Form, in der Sie sie geschrieben haben —
"yyyy-mm-dd hh:mm", Ende exklusiv, für einen Termin mit Uhrzeit; nur Daten, beide Tage eingeschlossen, für einen Ganztagstermin. Genau das lesen auchis_startundis_endauf dem Handle.
// Local variables
datetime ldt_start
// A "yyyy-mm-dd hh:mm" text back into a PowerBuilder datetime
ldt_start = DateTime(Date(Left(as_start, 10)), Time(Mid(as_start, 12)))
Das Ganztagsband #
Über dem Stundenraster der Tages- und Wochenansichten nimmt ein Band die Termine mit ib_all_day und die von 24 Stunden oder mehr auf: Ein dreitägiges Seminar passt dort als ein Balken, statt drei Spalten zu erdrücken. ib_all_day_band = false entfernt es. In der Monatsansicht sind diese Termine Balken über ihre Tage; die anderen eine Zeile, geschrieben von is_month_template.
Termine aus einem DataStore #
of_from_datastore(ids) lädt den Kalender mit einem Aufruf: eine Zeile = ein Termin, und sein Schlüssel ist seine Zeilennummer — ihn gibt Ihnen jedes Event zurück, bereit für SetItem. Eine Spalte spielt eine Rolle, wenn sie deren Namen trägt oder wenn of_map sie ihr gibt:
| Rolle | Ohne of_map erkannte Namen |
|---|---|
ROLE_SUBJECT | subject, title |
ROLE_START · ROLE_END | start, start_date, starts · end, end_date, ends |
ROLE_ALL_DAY · ROLE_READ_ONLY | all_day, allday · read_only, readonly |
ROLE_KEY · ROLE_LOCATION · ROLE_ORGANIZER · ROLE_DESCRIPTION · ROLE_RESOURCE · ROLE_CATEGORY · ROLE_STATUS · ROLE_RECURRING · ROLE_PRIVATE · ROLE_REMINDER · ROLE_CANCELLED | der Name der Rolle: key, location, organizer, description, resource, category, status, recurring, private, reminder, cancelled |
- Eine boolesche Spalte ist wahr bei
1,true,Yoderyes. Eine Spaltestatusträgt die Werte vonSTATUS_*(busy,tentative,free,oof,elsewhere). Jeder Name wird auch mit dem Präfixis_erkannt: is_private, daprivateein reserviertes Wort von PowerScript ist. - Jede Spalte, ob mit Rolle oder nicht, ist ein Feld der Vorlagen: Eine Spalte
customerwird als{customer}auf die Karte geschrieben und mitof_get_fieldgelesen. - Eine Spalte mit
ROLE_KEYersetzt die Zeilennummer als Schlüssel: Behalten Sie sie Daten vor, die Sie nicht aus diesem DataStore neu laden. Ihre Werte müssen eindeutig und nicht leer sein: Eine Zeile, die das nicht einhält (oder deren Wert/oder|enthält), behält ihre Zeilennummer als Schlüssel, undue_script_errormeldet es einmal. - Der Kalender ändert den DataStore nie: Er sagt Ihnen, was der Benutzer getan hat (
ue_appointment_moved,ue_appointment_resized), Sie rufenSetItemauf, dannUpdate(), wenn Ihre Anwendung es entscheidet. - Nach einem
InsertRow,DeleteRow,SortoderFilterändern sich die Zeilennummern: Rufen Sieof_from_datastoreerneut auf.
Ressourcen und Gruppierung #
Eine Ressource ist das, was gebucht wird: eine Person, ein Raum, eine Maschine (of_add_resource). Ein Termin nennt sie über is_resource. Mit is_group_by = GROUP_RESOURCE teilt sich jeder Tag der Tages- und Wochenansichten in eine Spalte je Ressource, und das Ziehen einer Karte in eine andere Spalte ändert ihre Ressource — ue_appointment_moved gibt sie in as_resource zurück. ib_visible = false auf einer Ressource blendet ihre Spalte und ihre Termine aus, wie das Abwählen eines Kalenders in Outlook.
Farben, Kategorien und Status #
Die Farbe einer Karte wird in dieser Reihenfolge bestimmt: das auf diesem Termin gesetzte il_accent, dann die Farbe seiner Kategorie (of_add_category, is_category), dann die seiner Ressource, dann der Akzent des Designs. Der Streifen links zeigt den Status (is_status, Outlooks „Anzeigen als“: gebucht, mit Vorbehalt, frei, abwesend, woanders); ein Termin mit ib_cancelled wird hohl gezeichnet, und ib_recurring, ib_private, ib_reminder setzen ein kleines Zeichen auf die Karte.
Eigenschaften #
| Eigenschaft | Typ | Standard | Rolle |
|---|---|---|---|
is_view | string | VIEW_WORK_WEEK | Die angezeigte Ansicht (VIEW_*). Live zurückgelesen: Der Benutzer ändert sie über die Symbolleiste. Sie zu setzen löst ue_view_changed aus, wie das Ansichtsmenü (nichts, wenn sich die Ansicht nicht ändert) |
is_date | string | heute | Der angezeigte Tag, "yyyy-mm-dd": Die Ansicht wird um ihn herum aufgebaut (seine Woche, sein Monat). Live zurückgelesen: Die Pfeile verschieben ihn. Einmal gesetzt, verschiebt is_now ihn nicht mehr; "" gibt die Ansicht an heute zurück |
is_now | string | "" | „Jetzt“, für die Linie der aktuellen Uhrzeit und die Schaltfläche Heute: "" = die Uhr des Arbeitsplatzes; "yyyy-mm-dd hh:mm" fixiert sie (Vorführung, Test, Wiedergabe). Solange is_date nie gesetzt wurde, geht die Ansicht zu ihrem Tag |
ii_first_day_of_week | integer | 1 | Erster Tag der Woche, in ISO-Nummern wie is_work_days: 1 = Montag … 7 = Sonntag; 0 wird für Sonntag akzeptiert |
is_work_days | string | "1|2|3|4|5" | Die Arbeitstage, ISO-Nummern mit | verbunden (1 = Montag … 7 = Sonntag, 0 für Sonntag akzeptiert): Sie bilden die Arbeitswoche, die anderen werden schattiert |
is_work_start · is_work_end | string | "08:00" · "17:00" | Die Arbeitszeit, "hh:mm": Der Rest des Tages wird schattiert |
is_day_start · is_day_end | string | "00:00" · "24:00" | Die Stunden, die das Stundenraster zeigt; was außerhalb liegt, wird am Rand seiner Spalte gezählt („▲ 1 früher“, „▼ 1 später“), zusammen mit dem, was der Bildlauf über oder unter der Ansicht verbirgt; ein Klick auf die Markierung holt den nächsten verborgenen Termin in die Ansicht |
ii_slot_minutes | integer | 30 | Der Rasterschritt in Minuten: 5, 10, 15, 20, 30 oder 60. Ein Ziehen rastet darauf ein |
ii_hour_height | integer | 48 | Die Höhe einer Stunde, in Pixeln |
is_scroll_time | string | "08:00" | Die Uhrzeit, zu der das Raster beim Öffnen einer Ansicht scrollt |
ib_show_now | boolean | true | Die rote Linie der aktuellen Uhrzeit |
ib_toolbar | boolean | true | Die Symbolleiste: Heute, zurück, weiter, der Titel, das Ansichtsmenü |
ib_week_numbers | boolean | false | ISO-Wochennummern, in der Ecke des Stundenrasters und vor jeder Monatszeile |
ib_read_only | boolean | false | Nichts lässt sich mit der Maus verschieben, in der Größe ändern oder erstellen; Entf fragt nichts mehr an |
ib_all_day_band | boolean | true | Das Ganztagsband über dem Stundenraster |
ib_tooltips | boolean | true | Der Tooltip jedes Termins, geschrieben von den Tooltip-Vorlagen |
ib_veto_changes | boolean | false | Fragt nach, bevor ein Verschieben oder eine Größenänderung angewendet wird: löst ue_appointment_changing aus, das ablehnen kann |
is_card_template | string | "[b]{subject}[/b]{?location}; {location}{/location}" | Die Vorlage der Karte: Tages- und Wochenansichten, Agenda, Monatsbalken — siehe Die Vorlagen |
is_month_template | string | "{!all_day}{start} {/all_day}{subject}" | Eine Zeile der Monatsansicht, für einen Termin innerhalb eines Tages |
is_tooltip_title_template | string | "{subject}" | Der Titel des Tooltips eines Termins |
is_tooltip_template | string | Zeit, Ort, Organisator | Der Text des Tooltips eines Termins — siehe Die Vorlagen |
is_group_by | string | GROUP_NONE | GROUP_RESOURCE: eine Spalte je Ressource unter jedem Tag, dazu eine Spalte (keine) am Ende, wenn ein Termin keine dem Kalender bekannte Ressource hat |
is_filter | string | "" | Zeigt nur die Termine, die diesen Text enthalten (Betreff, Ort, Organisator, Beschreibung, Felder); "" zeigt alle |
is_time_format | string | "hh:mm" | Wie eine Uhrzeit geschrieben wird: "hh:mm", "h:mm AM/PM"… (Kürzel aus Die Vorlagen) |
ii_agenda_days | integer | 7 | Wie viele Tage die Agendaansicht auflistet |
is_theme_style | string | "" | Visueller Stil der Komponente (Konstanten THEME_STYLE_*); leer = der der Anwendung, bei jeder Änderung übernommen |
is_theme_mode | string | "" | Helle oder dunkle Variante (Konstanten THEME_MODE_*); leer = die der Anwendung, bei jeder Änderung übernommen |
il_theme_accent | long | -1 | Akzentfarbe dieser Komponente (-1 = Akzent der Anwendung, sonst der des Designs) |
is_tooltip | string | "" | Einfacher Tooltip der Komponente (ein Termin hat seinen eigenen, von den Vorlagen geschrieben) |
is_super_tooltip_title | string | "" | Titel des erweiterten Tooltips (hat Vorrang vor is_tooltip) |
is_super_tooltip_text | string | "" | Text des erweiterten Tooltips (Rich-Text-Auszeichnung erlaubt) |
is_super_tooltip_image | string | "" | Bild des erweiterten Tooltips |
Eigenschaften eines Termins #
Ein Termin wird über sein Handle gesteuert, of_appointment("schlüssel") — beim ersten Zugriff erstellt, bleibt es danach gültig. Eine gelesene Eigenschaft fragt die Komponente, was sie jetzt wert ist: Nach einem Ziehen sagen is_start und is_end bereits, wo der Benutzer ihn abgelegt hat.
// A handle used once fits on one line
uo_sched.of_appointment(/*key*/ "a1").is_status = n_pbt_scheduler_appointment.STATUS_TENTATIVE
| Eigenschaft | Typ | Standard | Rolle |
|---|---|---|---|
is_subject | string | der von of_add_appointment | Der Betreff, was die Karte zuerst zeigt ({subject}) |
is_start · is_end | string | die von of_add_appointment | Beginn und Ende, "yyyy-mm-dd hh:mm", Ende exklusiv; bei einem Ganztagstermin Daten "yyyy-mm-dd", beide Tage eingeschlossen. Jede andere Schreibweise (22/09/2026 09:00) wird gespeichert, aber nie gezeichnet |
ib_all_day | boolean | false | Belegt ganze Tage: im Ganztagsband gezeichnet |
is_location · is_organizer · is_description | string | "" | Der Ort ({location}), der Organisator ({organizer}), ein längerer Text ({description}) |
is_resource | string | "" | Der Schlüssel seiner Ressource: seine Spalte, wenn der Kalender nach Ressource gruppiert, seine Farbe, wenn er keine Kategorie hat |
is_category | string | "" | Der Schlüssel seiner Kategorie: die Farbe der Karte |
is_status | string | STATUS_BUSY | Outlooks „Anzeigen als“ (STATUS_*), durch den Streifen links gezeichnet |
ib_recurring · ib_private · ib_reminder | boolean | false | Kleine Zeichen auf der Karte: eine Serie, ein privater Termin, eine Erinnerung |
ib_cancelled | boolean | false | Ein abgesagter Termin wird hohl gezeichnet |
ib_read_only | boolean | false | Der Benutzer kann ihn weder verschieben noch in der Größe ändern noch seine Löschung anfordern |
ib_visible | boolean | true | Blendet ihn aus, ohne ihn zu entfernen |
Wie jedes Item trägt ein Termin auch den gemeinsamen Tooltip (is_tooltip, is_super_tooltip_title, is_super_tooltip_text, is_super_tooltip_image) — der dann den der Vorlagen ersetzt — und die Item-Farben: il_accent färbt die Karte und ihren Streifen um, il_back_color, il_text_color, il_back_color_hover und il_text_color_hover malen sie in Ruhe und beim Überfahren.
Eigenschaften einer Ressource und einer Kategorie #
| Eigenschaft | Handle | Rolle |
|---|---|---|
is_label | n_pbt_scheduler_resource | Der Name über seiner Spalte, wenn der Kalender nach Ressource gruppiert ({resource_label}) |
il_color | n_pbt_scheduler_resource | Die Farbe seiner Termine ohne Kategorie; -1 = der Akzent |
ib_visible | n_pbt_scheduler_resource | false blendet seine Spalte und seine Termine aus |
is_label | n_pbt_scheduler_category | Ihr Name ({category_label}) |
il_color | n_pbt_scheduler_category | Die Farbe ihrer Termine; -1 = der Akzent. Eine Kategorie wird nicht selbst gezeichnet: der Tooltip und die fünf geerbten Elementfarben werden gespeichert und zurückgelesen, ohne sichtbare Wirkung |
Konstanten #
| Familie | Konstanten | Getragen von |
|---|---|---|
| Ansicht | VIEW_DAY, VIEW_WORK_WEEK, VIEW_WEEK, VIEW_MONTH, VIEW_AGENDA | die Komponente (is_view) |
| Gruppierung | GROUP_NONE, GROUP_RESOURCE | die Komponente (is_group_by) |
| Rolle einer Spalte | ROLE_KEY, ROLE_SUBJECT, ROLE_START, ROLE_END, ROLE_ALL_DAY, ROLE_LOCATION, ROLE_ORGANIZER, ROLE_DESCRIPTION, ROLE_RESOURCE, ROLE_CATEGORY, ROLE_STATUS, ROLE_RECURRING, ROLE_PRIVATE, ROLE_REMINDER, ROLE_CANCELLED, ROLE_READ_ONLY | die Komponente (of_map) |
| Status | STATUS_BUSY, STATUS_TENTATIVE, STATUS_FREE, STATUS_OOF, STATUS_ELSEWHERE | das Termin-Handle (is_status) |
Konstanten werden auf dem Objekt gelesen, das sie trägt:
u_pbt_scheduler.VIEW_MONTHfür eine Eigenschaft der Komponente,n_pbt_scheduler_appointment.STATUS_OOFfür eine Eigenschaft eines Termins.
Methoden #
Termine #
| Methode | Rolle | |
|---|---|---|
of_add_appointment (string as_key, string as_subject, string as_start, string as_end) | Fügt einen Termin hinzu: seinen Schlüssel (eindeutig), seinen Betreff, Beginn und Ende "yyyy-mm-dd hh:mm". Alles Weitere läuft über sein Handle. Liefert 0, sobald hinzugefügt, -5, wenn der Schlüssel leer ist, / oder ` | enthält oder **schon vergeben** ist (ein Termin wird so nicht aktualisiert: das macht sein Handle), oder wenn der Beginn — oder ein angegebenes Ende — nicht als yyyy-mm-dd oder yyyy-mm-dd hh:mm geschrieben ist (String(ldt) schreibt auf einem französischen Arbeitsplatz 22/09/2026: nehmen Sie die datetime-Überladung), -2`, wenn die Komponente nicht erstellt ist |
of_add_appointment (string as_key, string as_subject, datetime adt_start, datetime adt_end) | Dasselbe, aus zwei datetime-Werten; ein Null-Ende entspricht dem Beginn. Für einen ganzen Tag ist das Ende der letzte Tag selbst, eingeschlossen: zweimal dasselbe Datum = ein Tag. Liefert 0, sobald hinzugefügt, -5, wenn der Schlüssel leer ist, / oder ` | enthält oder schon vergeben ist, oder wenn der Beginn null ist, -2`, wenn die Komponente nicht erstellt ist |
of_appointment (string as_key) | Das Handle eines Termins (n_pbt_scheduler_appointment), beim ersten Zugriff erstellt — siehe Eigenschaften eines Termins | |
of_remove_appointment (string as_key) | Entfernt einen Termin. Liefert 0, sobald entfernt, -5, wenn der Kalender keinen Termin mit diesem Schlüssel hat, -2, wenn die Komponente nicht erstellt ist | |
of_clear_appointments ( ) | Entfernt alle Termine; Ressourcen, Kategorien und Optionen bleiben. Liefert 0, sobald gesendet, -2, wenn die Komponente nicht erstellt ist | |
of_set_field (string as_key, string as_field, string as_value) | Gibt einem Termin ein eigenes Feld für die Vorlagen: Nach of_set_field("a1", "customer", "ACME") schreibt {customer} ACME auf seine Karte. Liefert 0, sobald gesetzt, -5, wenn das Feld leer ist oder der Kalender keinen Termin mit diesem Schlüssel hat, -2, wenn die Komponente nicht erstellt ist | |
of_get_field (string as_key, string as_field) | Liest ein Feld eines Termins live: eines Ihrer eigenen (of_set_field) oder eine Spalte des DataStores, aus dem er stammt; "", wenn es keines gibt |
DataStore #
| Methode | Rolle |
|---|---|
of_from_datastore (datastore ads) | Die DataStore-Brücke: eine Zeile = ein Termin, sein Schlüssel = seine Zeilennummer, jede Spalte = ein Feld der Vorlagen. Ersetzt die angezeigten Termine. Liefert 0, sobald geladen, -5, wenn der DataStore ungültig ist oder keine Spalte hat, -2, wenn die Komponente nicht erstellt ist |
of_map (string as_role, string as_column) | Gibt einer Spalte, deren Name es nicht sagt, eine Rolle (ROLE_*): of_map(ROLE_SUBJECT, "title_text"). Vor oder nach of_from_datastore: danach wird jede Zeile so neu gelesen, wie sie jetzt ist — ein entfernter Termin bleibt entfernt, ein gezogener bleibt, wo er losgelassen wurde, die Felder von of_set_field und die von Hand hinzugefügten Termine bleiben. Liefert 0, sobald gesetzt, -5, wenn die Rolle keine der Konstanten ROLE_* ist oder die Spalte nicht zum DataStore des letzten of_from_datastore gehört; ein neues ROLE_KEY gibt jeder Zeile einen neuen Schlüssel, und die Handles der alten werden freigegeben, -2, wenn die Komponente nicht erstellt ist |
Ressourcen und Kategorien #
| Methode | Rolle | |
|---|---|---|
of_add_resource (string as_key, string as_label) | Fügt eine Ressource hinzu — eine Person, einen Raum, eine Maschine; Farbe und Sichtbarkeit laufen über of_resource. Liefert 0, sobald hinzugefügt, -5, wenn der Schlüssel leer ist, / oder ` | enthält oder schon vergeben ist, -2`, wenn die Komponente nicht erstellt ist |
of_resource (string as_key) | Das Handle einer Ressource (n_pbt_scheduler_resource), beim ersten Zugriff erstellt | |
of_remove_resource (string as_key) | Entfernt eine Ressource; ihre Termine bleiben — nach Ressource gruppiert, in der Spalte (keine). Liefert 0, sobald entfernt, -5, wenn der Kalender keine Ressource mit diesem Schlüssel hat, -2, wenn die Komponente nicht erstellt ist | |
of_clear_resources ( ) | Entfernt alle Ressourcen. Liefert 0, sobald gesendet, -2, wenn die Komponente nicht erstellt ist | |
of_add_category (string as_key, string as_label, long al_color) | Fügt eine Farbkategorie hinzu: Die Termine, deren is_category sie nennt, nehmen ihre Farbe an (-1 = der Akzent). Liefert 0, sobald hinzugefügt, -5, wenn der Schlüssel leer ist, / oder ` | enthält oder schon vergeben ist, -2`, wenn die Komponente nicht erstellt ist |
of_category (string as_key) | Das Handle einer Kategorie (n_pbt_scheduler_category), beim ersten Zugriff erstellt | |
of_remove_category (string as_key) | Entfernt eine Kategorie; ihre Termine kehren zum Akzent zurück. Liefert 0, sobald entfernt, -5, wenn der Kalender keine Kategorie mit diesem Schlüssel hat, -2, wenn die Komponente nicht erstellt ist | |
of_clear_categories ( ) | Entfernt alle Kategorien. Liefert 0, sobald gesendet, -2, wenn die Komponente nicht erstellt ist |
Navigation und Auswahl #
| Methode | Rolle |
|---|---|
of_next ( ) | Der nächste Tag, die nächste Woche oder der nächste Monat — der Pfeil der Symbolleiste. Liefert 0, sobald gesendet, -2, wenn die Komponente nicht erstellt ist |
of_previous ( ) | Der vorige Tag, die vorige Woche oder der vorige Monat. Liefert 0, sobald gesendet, -2, wenn die Komponente nicht erstellt ist |
of_go_to_today ( ) | Zurück zu heute — die Schaltfläche Heute. Liefert 0, sobald gesendet, -2, wenn die Komponente nicht erstellt ist |
of_select_appointment (string as_key) | Wählt einen Termin aus ("" = keinen), wie ein Klick: löst ue_selection_changed aus (nichts, wenn er schon die Auswahl ist). Liefert 0, sobald ausgewählt, -5, wenn der Kalender keinen Termin mit diesem Schlüssel hat, -2, wenn die Komponente nicht erstellt ist |
of_selected_key ( ) | Der Schlüssel des ausgewählten Termins, "", wenn keiner — live gelesen |
of_show_appointment (string as_key) | Holt einen Termin ins Bild: geht zu seinem Tag, scrollt zu seiner Uhrzeit und wählt ihn aus, wie ein Klick: löst ue_selection_changed aus. Ein Tag, den die Arbeitswoche nicht zeigt (ein Samstag), schaltet die Ansicht auf die ganze Woche, und ue_view_changed meldet es. Liefert 0, sobald angezeigt, -5, wenn der Kalender keinen Termin mit diesem Schlüssel hat, -2, wenn die Komponente nicht erstellt ist |
of_scroll_to_time (string as_time) | Scrollt das Stundenraster zu einer Uhrzeit, "hh:mm". Liefert 0, sobald gesendet, -5, wenn die Uhrzeit leer ist, -2, wenn die Komponente nicht erstellt ist |
of_first_visible_date ( ) · of_last_visible_date ( ) | Der erste und der letzte Tag, den die Ansicht zeigt, "yyyy-mm-dd" — live gelesen |
of_shown_count ( ) | Liefert die Anzahl der im sichtbaren Bereich angezeigten Termine: nach is_filter, den ausgeblendeten, den ausgeblendeten Ressourcen und der Obergrenze des Demomodus (die ersten 12 dieses Bereichs); of_count zählt den ganzen Kalender |
Events #
| Event | Ausgelöst, wenn |
|---|---|
ue_appointment_clicked (string as_key) | Ein Termin wurde angeklickt (und ausgewählt) |
ue_appointment_opened (string as_key) | Doppelklick auf einen Termin oder Eingabe auf dem ausgewählten: Öffnen Sie Ihren Editor |
ue_appointment_rclicked (string as_key, long al_x, long al_y) | Rechtsklick auf einen Termin. al_x / al_y sind Bildschirm-Pixel |
ue_appointment_changing (string as_key, string as_start, string as_end, string as_resource) | Bevor ein Verschieben oder eine Größenänderung angewendet wird, nur wenn ib_veto_changes wahr ist. Geben Sie false zurück, um den Termin an seinen Platz zurückzusetzen; standardmäßig true |
ue_appointment_moved (string as_key, string as_start, string as_end, string as_resource) | Der Benutzer hat einen Termin gezogen: sein neuer Beginn, sein neues Ende und seine Ressource. Der Kalender zeigt ihn bereits dort; speichern Sie ihn (eine DataStore-Zeile: SetItem auf Zeile Long(as_key)) |
ue_appointment_resized (string as_key, string as_start, string as_end) | Der Benutzer hat einen Rand eines Termins gezogen: sein neuer Beginn und sein neues Ende |
ue_range_selected (string as_start, string as_end, boolean ab_all_day, string as_resource) | Der Benutzer hat leere Felder mit der Maus überstrichen: der Bereich, um darauf einen Termin anzulegen. Im Ganztagesband oder in der Monatsansicht überstrichen, sind es ganze Tage: ab_all_day ist true, nur Daten, der letzte eingeschlossen |
ue_new_requested (string as_start, string as_end, boolean ab_all_day, string as_resource) | Der Benutzer fordert einen neuen Termin an: Doppelklick auf ein leeres Feld oder einen leeren Tag, oder das + eines Tageskopfs (nach Ressource gruppiert: eines Ressourcenkopfs). Ein ganzer Tag kommt als reine Daten, das Ende eingeschlossen: zweimal dasselbe Datum = ein Tag |
ue_delete_requested (string as_key) | Entf wurde auf dem ausgewählten Termin gedrückt. Entfernen Sie ihn (of_remove_appointment), sobald Ihre Anwendung zustimmt |
ue_slot_rclicked (string as_start, boolean ab_all_day, string as_resource, long al_x, long al_y) | Rechtsklick auf ein leeres Feld oder einen leeren Tag; bei einem Tag ist as_start sein Datum allein. al_x / al_y sind Bildschirm-Pixel |
ue_selection_changed (string as_key) | Der ausgewählte Termin hat sich geändert ("" = keiner): ein Klick, oder of_select_appointment / of_show_appointment aus Ihrem Code |
ue_view_changed (string as_view) | Die Ansicht hat sich geändert: Der Benutzer hat in der Symbolleiste eine andere gewählt oder einen Tag über sein „+N“ geöffnet, Ihr Code hat is_view gesetzt, oder of_show_appointment hat die Arbeitswoche auf die ganze Woche umgestellt, um einen freien Tag zu zeigen |
ue_date_changed (string as_first, string as_last) | Der sichtbare Bereich hat sich geändert (Navigation, Ansicht, Datum): sein erster und letzter Tag, "yyyy-mm-dd", eingeschlossen. Auch bei der ersten Anzeige ausgelöst (für den heutigen Bereich), dann erneut, wenn Ihr Code is_date oder is_view setzt: Ein Fenster, das sie beim Öffnen setzt, erhält zwei; und nach jedem of_reset, das den Kalender leert: eine Anfrage nach Daten, keine Geste. Hier werden die Termine des Bereichs geladen |
ue_ready ( ) | Die Komponente ist fertig geladen; alles zuvor Gesendete wurde nachgespielt |
ue_runtime_missing ( ) | Die WebView2-Laufzeit fehlt: Die Komponente bleibt leer |
ue_bg_color (long al_color) | Die Komponente hat ihre Hintergrundfarbe des Designs berechnet; das Userobject hat sie bereits übernommen (backcolor) |
Die Vorlagen #
Was eine Karte, eine Monatszeile und ein Tooltip sagen, ist nicht festgelegt: Es ist eine Vorlage, die Sie schreiben, in Rich Text ([b], [br], [color=…], [symbol=…]…) mit Feldern in geschweiften Klammern. Vier Eigenschaften tragen sie: is_card_template (Karten der Tages- und Wochenansichten, Agenda, Monatsbalken), is_month_template (eine Zeile der Monatsansicht), is_tooltip_title_template und is_tooltip_template (der Tooltip). Die Standardvorlage des Tooltips lautet:
[symbol=clock] {when}{?location}[br][symbol=location] {location}{/location}{?organizer}[br][symbol=person] {organizer}{/organizer}
Die Syntax #
| Schreibweise | Wirkung |
|---|---|
{subject} | Der Wert des Felds, maskiert: Ein [ im Betreff wird angezeigt, es öffnet kein Tag |
{start:dddd d mmmm} | Ein Datumsfeld in einem Format (Kürzel unten) |
{?location}…{/location} | Schreibt den Block nur, wenn das Feld etwas sagt, das kein NEIN ist: nicht leer und nicht 0, N, no oder false |
{!all_day}…{/all_day} | Schreibt den Block nur, wenn das Feld leer (oder falsch) ist |
{description:raw} | Fügt den Wert als Auszeichnung ein, ohne ihn zu maskieren — für ein Feld, das bereits Tags enthält |
{{ · }} | Eine wörtliche geschweifte Klammer |
Die Datumsformate #
Die Kürzel sind die von PowerBuilder; Tages- und Monatsnamen folgen der Anzeigesprache. Ein Text in Anführungszeichen wird unverändert geschrieben. Dieselben Kürzel dienen is_time_format.
| Kürzel | Schreibt |
|---|---|
yyyy · yy | Das Jahr, 2026 · 26 |
mmmm · mmm | Der Monatsname, lang · kurz |
mm · m | Der Monat, 09 · 9 — oder die Minuten direkt nach einer Stunde, wie in PowerBuilder |
dddd · ddd | Der Tagesname, lang · kurz |
dd · d | Der Tag des Monats, 05 · 5 |
hh · h | Die Stunde, 09 · 9 (12-Stunden-Format mit AM/PM) |
nn · n | Die Minuten, 05 · 5 |
AM/PM · am/pm | Die Vormittags- oder Nachmittagsangabe |
Die Felder #
| Feld | Wert |
|---|---|
key · subject · location · organizer · description | Der Schlüssel und die Texte des Termins |
resource · resource_label | Der Schlüssel seiner Ressource · ihr Name |
category · category_label | Der Schlüssel seiner Kategorie · ihr Name |
status · status_label | Der Status (busy…) · seine Bezeichnung, in die Anzeigesprache übersetzt |
all_day · recurring · private · reminder · cancelled | true oder leer: gemacht für {?…} und {!…} |
start · end | Die Anfangs- · Endzeit im Format is_time_format (leer bei einem Ganztagstermin); mit einem Format Datum und Uhrzeit — bei einem Ganztagstermin ist {end:…} der letzte Tag, wie is_end ihn liest |
date | Der erste Tag, ausgeschrieben; mit einem Format der formatierte Beginn |
time | 09:00-10:30 oder „Ganztägig“ |
when | Der vollständige Satz: Tag, Uhrzeiten und der Endtag, wenn er abweicht |
duration | 45 min, 1 h 30, 2 days (übersetzt) |
| Ihre eigenen | Jedes durch of_set_field gesetzte Feld und jede Spalte des DataStores von of_from_datastore, unter ihrem Namen. Ein Wert, der ein Datum ist, nimmt ein Format an: {due_date:dd/mm} |
Ein unbekanntes Feld schreibt eine leere Zeichenkette.
Die Symbole #
Das Rich-Text-Tag [symbol=name] setzt ein eingebautes Symbol, einfarbig, in der Farbe des umgebenden Texts gezeichnet — es folgt dem Design, dem Überfahren und der Farbe der Karte, ohne mitzuliefernde Datei: clock, location, person, people, calendar, repeat, lock, bell, phone, mail, video, note, tag, link, check, star, info, warning. Ein unbekannter Name wird unverändert angezeigt.
Was der Benutzer ohne eine Zeile Code tun kann #
- navigieren: Heute, zurück, weiter und das Ansichtsmenü der Symbolleiste;
- einen Termin verschieben, auf eine andere Uhrzeit, einen anderen Tag oder eine andere Ressource, durch Ziehen — der Schritt folgt
ii_slot_minutes; - einen Termin durch Ziehen seines Rands in der Größe ändern;
- leere Felder überstreichen, um einen Bereich zu wählen →
ue_range_selected— im Ganztagesband oder in der Monatsansicht ganze Tage; - einen Termin anfordern durch Doppelklick auf ein leeres Feld oder über das + eines Tageskopfs (eines Ressourcenkopfs, wenn der Kalender gruppiert ist) →
ue_new_requested; - einen Termin durch Doppelklick öffnen →
ue_appointment_opened, und auf einen Termin oder ein leeres Feld rechtsklicken für Ihr Menü.
Der Kalender erstellt, ändert und löscht nichts von selbst über das Ziehen hinaus: Er fragt, Ihre Anwendung entscheidet. ib_read_only schaltet alle diese Gesten auf einmal ab, ib_read_only auf einem Termin nur für diesen.
Mit der Tastatur, sobald der Kalender den Fokus hat:
| Taste | Wirkung |
|---|---|
| Eingabe | Öffnet den ausgewählten Termin → ue_appointment_opened |
| Entf | Fordert das Löschen des ausgewählten Termins an → ue_delete_requested (nichts, wenn Kalender oder Termin schreibgeschützt ist) |
| Pfeil oben / Pfeil unten | Wählt den vorigen / nächsten Termin der Ansicht, in der Reihenfolge ihres Beginns → ue_selection_changed |
| Bild auf / Bild ab | Der vorige / nächste Tag, Woche oder Monat |
| Alt+Pos1 | Zurück zu heute |
| Esc | Bricht ein laufendes Ziehen ab |
Beispiele #
Termine aus einem DataStore und was der Benutzer damit macht #
Der DataStore ids_appts (Instanzvariable) hat die Spalten subject, start_date, end_date, location, room, category und customer. Die ersten vier spielen ihre Rolle über ihren Namen; room erhält sie von of_map.
// open event of the window : the appointments, retrieved the way your application already does
ids_appts = create datastore
ids_appts.dataobject = "d_appointments"
ids_appts.SetTransObject(SQLCA)
ids_appts.Retrieve()
// "room" is not a role name : say which role it plays, then load every row
uo_sched.of_map(/*role*/ u_pbt_scheduler.ROLE_RESOURCE, /*column*/ "room")
uo_sched.of_from_datastore(/*ads*/ ids_appts)
// ue_appointment_moved event of uo_sched : (string as_key, string as_start, string as_end, string as_resource)
// Local variables
long ll_row
// The key of a row loaded by of_from_datastore is its row number
ll_row = Long(as_key)
ids_appts.SetItem(ll_row, "start_date", DateTime(Date(Left(as_start, 10)), Time(Mid(as_start, 12))))
ids_appts.SetItem(ll_row, "end_date", DateTime(Date(Left(as_end, 10)), Time(Mid(as_end, 12))))
ids_appts.SetItem(ll_row, "room", as_resource)
// Save when YOUR application decides : here, at once
ids_appts.Update()
// ue_appointment_resized event of uo_sched : (string as_key, string as_start, string as_end)
// Local variables
long ll_row
// Only the times change : same row, same two columns
ll_row = Long(as_key)
ids_appts.SetItem(ll_row, "start_date", DateTime(Date(Left(as_start, 10)), Time(Mid(as_start, 12))))
ids_appts.SetItem(ll_row, "end_date", DateTime(Date(Left(as_end, 10)), Time(Mid(as_end, 12))))
ids_appts.Update()
Anlegen und löschen #
// ue_new_requested event of uo_sched : (string as_start, string as_end, boolean ab_all_day, string as_resource)
// Local variables
long ll_row
// A new row, prefilled with the slot the user chose
ll_row = ids_appts.InsertRow(0)
ids_appts.SetItem(ll_row, "subject", "New appointment")
ids_appts.SetItem(ll_row, "start_date", DateTime(Date(Left(as_start, 10)), Time(Mid(as_start, 12))))
ids_appts.SetItem(ll_row, "end_date", DateTime(Date(Left(as_end, 10)), Time(Mid(as_end, 12))))
ids_appts.SetItem(ll_row, "room", as_resource)
// Reload (the row numbers are the keys), then bring the new one into view
uo_sched.of_from_datastore(/*ads*/ ids_appts)
uo_sched.of_show_appointment(/*key*/ String(ll_row))
// ue_delete_requested event of uo_sched : (string as_key)
// Ask first : the calendar never deletes by itself
if MessageBox("Delete", "Delete this appointment?", Question!, YesNo!) = 2 then return
ids_appts.DeleteRow(Long(as_key))
ids_appts.Update()
// The rows after it changed number : reload
uo_sched.of_from_datastore(/*ads*/ ids_appts)
Eine Spalte je Raum #
// The rooms, each with its own colour, side by side under each day
uo_sched.of_set_redraw(/*on*/ false)
uo_sched.of_add_resource(/*key*/ "r1", /*label*/ "Room A")
uo_sched.of_add_resource(/*key*/ "r2", /*label*/ "Room B")
uo_sched.of_resource(/*key*/ "r1").il_color = RGB(15, 108, 189)
uo_sched.of_resource(/*key*/ "r2").il_color = RGB(31, 158, 117)
uo_sched.is_group_by = u_pbt_scheduler.GROUP_RESOURCE
uo_sched.is_view = u_pbt_scheduler.VIEW_DAY
// Each appointment names its room
uo_sched.of_add_appointment(/*key*/ "k1", /*subject*/ "Kickoff", /*start*/ "2026-09-22 09:00", /*end*/ "2026-09-22 10:00")
uo_sched.of_appointment(/*key*/ "k1").is_resource = "r1"
uo_sched.of_add_appointment(/*key*/ "k2", /*subject*/ "Interview", /*start*/ "2026-09-22 10:30", /*end*/ "2026-09-22 11:30")
uo_sched.of_appointment(/*key*/ "k2").is_resource = "r2"
uo_sched.of_set_redraw(/*on*/ true)
// A checkbox of the window hides Room B and its appointments, like unticking a calendar in Outlook
uo_sched.of_resource(/*key*/ "r2").ib_visible = cbx_room_b.checked
Eigene Karten und Tooltips #
// The card : the time, the subject in bold, the customer (a DataStore column) when there is one
uo_sched.is_card_template = "{start} [b]{subject}[/b]{?customer}[br][symbol=people] {customer}{/customer}"
// The month line : a small lock on the private ones
uo_sched.is_month_template = "{?private}[symbol=lock] {/private}{subject}"
// The tooltip : the date written out, the duration, the status
uo_sched.is_tooltip_title_template = "{subject}"
uo_sched.is_tooltip_template = "[symbol=calendar] {start:dddd d mmmm}, {time} ({duration})[br][symbol=info] {status_label}"
Ein Verschieben ablehnen #
// Ask before any move or resize is applied
uo_sched.ib_veto_changes = true
// ue_appointment_changing event of uo_sched : (string as_key, string as_start, string as_end, string as_resource) returns boolean
// Nothing on a Saturday or a Sunday : returning false puts the appointment back
if DayNumber(Date(Left(as_start, 10))) = 1 or DayNumber(Date(Left(as_start, 10))) = 7 then return false
return true
Nur laden, was sichtbar ist #
Bei jahrelanger Historie muss nicht alles gelesen werden: ue_date_changed liefert bei jeder Navigation und bei der ersten Anzeige den sichtbaren Bereich. Hier nimmt d_appointments zwei datetime-Argumente, Beginn und Ende des Bereichs.
// ue_date_changed event of uo_sched : (string as_first, string as_last)
// The last day is INCLUDED : read up to the start of the day after
ids_appts.Retrieve(DateTime(Date(as_first)), DateTime(RelativeDate(Date(as_last), 1)))
uo_sched.of_from_datastore(/*ads*/ ids_appts)
Ihr Menü auf einem Termin #
// ue_appointment_rclicked event of uo_sched : (string as_key, long al_x, long al_y)
// Local variables
m_appointment lm_menu
// Remember which appointment the menu is about, then open YOUR menu under the pointer
is_menu_key = as_key
lm_menu = create m_appointment
lm_menu.m_popup.PopMenu(parent.PointerX(), parent.PointerY())
destroy lm_menu
Best Practices #
- Rahmen Sie eine Reihe von Hinzufügungen mit
of_set_redraw(/*on*/ false)/of_set_redraw(/*on*/ true)ein: Die Termine erscheinen auf einen Schlag. - Für Daten aus der Datenbank ziehen Sie
of_from_datastoreeiner Schleife vonof_add_appointmentvor: eine einzige Übertragung, und jedes Event gibt Ihnen die Zeile zurück. - Laden Sie nach jedem
InsertRow,DeleteRow,SortoderFilterdes DataStores neu (of_from_datastore): Der Schlüssel eines Termins ist eine Zeilennummer. - Schreiben Sie Daten als
"yyyy-mm-dd hh:mm", nie im Regionalformat des Arbeitsplatzes: Nur dieses liest der Kalender überall. - Umgeben Sie in einer Vorlage ein optionales Feld mit
{?feld}…{/feld}: Eine Karte ohne Ort zeigt kein verwaistes „;“. - Laden Sie bei langer Historie den sichtbaren Bereich in
ue_date_changedstatt des ganzen DataStores. - Für eine Geschäftsregel (kein Termin am Wochenende, keine Überschneidung in einem Raum) lehnen
ib_veto_changesundue_appointment_changingab, bevor sich die Karte bewegt.
Grenzen der 4.0 #
Was der Kalender nicht kann — gut zu wissen, bevor Sie ihn wählen:
- Serien: keine Terminserien (RRULE-Regeln), keine Ausnahmen, keine Bearbeitung „dieses Vorkommen / die ganze Serie“.
ib_recurringsetzt nur ein Zeichen auf die Karte: Jedes Vorkommen ist ein Termin (eine Zeile des DataStores), den Ihre Anwendung selbst erzeugt. Eine Serien-Engine ist für eine spätere Version geplant. - Zeitzonen: Die Uhrzeit ist schwebende Ortszeit (siehe Datumsangaben); keine zweite Zeitskala, keine Umrechnung.
- Zeitachsenansicht (Ressourcen als Zeilen, Zeit als Spalten) und Mini-Kalender zur Navigation: nicht vorhanden; gruppieren Sie in der Tages- und Wochenansicht nach Ressource (
GROUP_RESOURCE). - iCalendar: weder Import noch Export von
.ics-Dateien. - Drucken: nicht vorhanden; der Kalender wird nur am Bildschirm gezeichnet.
- Tastatur: Auswählen, Öffnen, Löschen und Navigieren gehen per Tastatur, aber ein Termin lässt sich ohne Maus weder anlegen noch verschieben.
- Datum und Uhrzeit in zwei Spalten: Ein Beginn in zwei Spalten des DataStores lässt sich nicht zuordnen; fügen Sie ihn in der Abfrage zu einer
datetime-Spalte zusammen.
Vom gemeinsamen Sockel geerbt #
Diese Mitglieder gibt es bei jeder visuellen Komponente — sie sind nicht dieser eigen. Sie werden einmal in den übergreifenden Kapiteln beschrieben; diese Tabelle sagt nur, wo man sie liest.
| Mitglieder | Rolle | Beschrieben in |
|---|---|---|
of_count · of_keys_at · of_has | Durchlaufen, was die Komponente enthält | 3.2 Die Items |
of_reset | Die Komponente zurücksetzen | 3.6 Eine Komponente zurücksetzen: of_reset() |
of_register_shortcut · of_clear_shortcuts | Tastenkürzel der Komponente | 3.5 Tastenkombinationen |
of_is_created · of_is_ready · of_get_last_error | Ob sie entstanden ist, ob sie bereit ist, was fehlschlug | 3.7 Diagnose |
of_save_as_png · of_save_as_jpg | Die Darstellung als Bild exportieren | 3.8 Die Darstellung als Bild exportieren |
of_set_redraw | Änderungen zu einem einzigen Neuzeichnen bündeln | 3.10 Best Practices |
of_preload_icons | Symbole ohne Verzögerung | Sofortige Anzeige: of_icon |
of_set_translation | Eine Beschriftung der Komponente übersetzen | 5.2 Eine Beschriftung anpassen: of_set_translation |
of_focus_webview | Der Komponente den Fokus geben | 6.4 Tastatur und Fokus |
of_print · of_print_to_pdf | Drucken oder ein PDF schreiben | 6.9 Drucken |
of_set_property · of_get_property · of_component_name | Eine Eigenschaft über ihren Namen steuern | 3.1 Die Eigenschaften-Engine |
Zwei Helfer werden nicht geerbt: of_icon und of_escape_markup liegen auf n_pbt_utils. Deklarieren Sie eines — n_pbt_utils lnv_utils, nichts zu erzeugen — und rufen Sie sie darauf auf.