PBToolboxAI v5 ← Site

gantt — u_pbt_gantt #

← Référence des composants · Sommaire du guide

gantt planifie un projet : à gauche une grille de tâches (nom, début, fin, durée, avancement), à droite leurs barres sur une échelle de temps — jour, semaine, mois ou trimestre — avec la ligne d'aujourd'hui (à l'accent du thème) et les jours chômés grisés. Une tâche qui en contient d'autres est un récapitulatif dont les dates et l'avancement se calculent ; un jalon est un losange d'un jour ; une flèche relie une tâche à celle qui l'attend, et le chemin critique se dessine en rouge. L'utilisateur glisse une barre pour la déplacer, son bord de fin pour changer sa fin, le petit triangle dessous pour son avancement ; ue_task_moved, ue_task_resized et ue_progress_changed vous le disent. Le plan se remplit à la main ou depuis un DataStore, qui reçoit les changements.

▶ Le voir en vrai — Application de démonstration, tuile Gantt chart : l'aperçu, le code qui le produit et cette page, côte à côte.


En bref #

Userobjectu_pbt_gantt
Classe d'itemsn_pbt_gantt_task (of_task(keys))
Sert àPlanifier et suivre un projet : phases, tâches, jalons, liens, retards
PrincipeUne tâche se désigne par son adresse ("build/design") ; un récapitulatif calcule ses dates et son avancement depuis ce qu'il contient
Options opt-inib_veto_changes, ib_write_back, ib_link_by_mouse, ib_critical_path, ib_show_late, ib_read_only

Démarrage rapide #

// A phase : the task that holds others becomes a summary
uo_plan.of_add_task(/*keys*/ "build", /*label*/ "Build", /*start*/ "2026-11-02", /*end*/ "2026-11-20")
uo_plan.of_add_task(/*keys*/ "build/design", /*label*/ "Design", /*start*/ "2026-11-02", /*end*/ "2026-11-06")
uo_plan.of_add_task(/*keys*/ "build/code", /*label*/ "Code", /*start*/ "2026-11-09", /*end*/ "2026-11-20")

// A milestone : an instant at the end of its day, here the day the code ends
uo_plan.of_add_milestone(/*keys*/ "golive", /*label*/ "Go-live", /*date*/ "2026-11-20")

// The links : a task starts once the one before it is finished
uo_plan.of_add_dependency(/*from_keys*/ "build/design", /*to_keys*/ "build/code")
uo_plan.of_add_dependency(/*from_keys*/ "build/code", /*to_keys*/ "golive")

// What is done already
uo_plan.of_task(/*keys*/ "build/design").id_progress = 100
// event ue_task_moved of uo_plan : (string as_keys, string as_start, string as_end, string as_old_start, string as_old_end)
// Local variables
string ls_code

// The code of the task : the LAST level of its address ("build/design" -> "design")
ls_code = this.of_task(/*keys*/ as_keys).of_key()

// Save the new dates of the task
UPDATE tasks SET start_date = :as_start, end_date = :as_end WHERE code = :ls_code;

Tâches, récapitulatifs et jalons #

Une tâche se désigne par son adresse : sa clé sous son parent, les niveaux joints par / — "build" en haut, "build/design" dans la tâche "build", ajoutée d'abord. Une tâche qui en contient d'autres devient un récapitulatif : une barre fine, ses dates vont du premier début au dernier jour de ce qu'elle contient, son avancement est leur moyenne pondérée par les durées. Ni l'utilisateur ni votre code n'écrivent ses dates ou son avancement : ils se calculent. Son chevron, un double-clic sur sa ligne ou ib_collapsed la replient ; ue_task_toggled suit.

Les dates sont des jours entiers, aaaa-mm-jj, la fin comprise : une tâche du 6 au 10 dure cinq jours, comptés au calendrier. of_add_task et of_add_milestone acceptent aussi deux date de PowerBuilder. Un jalon n'a pas de durée : un jour, un losange, aucun avancement. Par la poignée d'une tâche (of_task(adresse)), écrire is_start la déplace (sa durée reste), is_end change sa fin, id_progress son avancement ; une valeur écrite par votre code ne lève rien, comme SetItem. La même poignée lit ce que la tâche est maintenant : ses dates, sa durée (of_duration), sa place parmi ses sœurs à partir de 1 (of_position), son niveau (of_level).

// The test starts three days later : it moves, its length stays
uo_plan.of_task(/*keys*/ "test").is_start = "2026-11-26"

// Read back what the summary computed
MessageBox("Build", uo_plan.of_task(/*keys*/ "build").is_end + " - " + String(uo_plan.of_task(/*keys*/ "build").id_progress) + " %")

Liens et chemin critique #

of_add_dependency relie deux tâches par une flèche. Le type par défaut est fin à début (DEP_FS : la suivante commence une fois la précédente finie) ; DEP_SS (début à début), DEP_FF (fin à fin) et DEP_SF (début à fin) se donnent en troisième argument. Un lien que les dates cassent — la suivante commence trop tôt — est dessiné en pointillé dans la couleur du danger. Un lien vers soi-même, entre une tâche et ce qu'elle contient, un lien déjà là ou un lien qui fermerait une boucle est refusé (-5). of_dependency_type lit le type d'un lien, of_predecessors et of_successors de la poignée les tâches liées.

Avec ib_critical_path = true, le chemin critique se dessine dans la couleur du danger : les tâches et les liens sans marge, ceux qui repoussent la fin du projet s'ils glissent d'un jour. of_is_critical de la poignée le lit, que le chemin soit dessiné ou non. Avec ib_link_by_mouse = true, deux points apparaissent de part et d'autre de la barre sous le pointeur : l'utilisateur en glisse un sur une autre tâche, et ue_link_requested dit le lien demandé — son type suit le point de départ et la moitié de la barre visée. Le diagramme n'ajoute rien de lui-même : of_add_dependency une fois votre application d'accord. Un clic sur une flèche lève ue_dependency_clicked. La marge se compte en jours ouvrés (is_work_days) : une tâche qui finit un vendredi suivie d'une tâche qui commence le lundi n'en a aucune. Un jalon est un instant à la fin de son jour : posé le jour où finit la tâche qu'il suit, le lien est tenu, et la tâche qui le suit commence le lendemain. Un lien qui touche un récapitulatif engage les tâches qu'il contient ; un récapitulatif n'est jamais marqué, et une flèche n'est rouge qu'entre deux barres rouges. Une tâche terminée (100 %) n'est jamais marquée : elle ne pilote plus rien. is_project_end compte la marge jusqu'à une échéance au lieu de la dernière fin.


Calendrier : jours fériés, décalages, marqueurs et retards #

Un projet suit un calendrier. is_work_days dit les jours ouvrés de la semaine ; of_add_holiday ajoute un jour férié, un par un — grisé comme un week-end, nommé dans l'info-bulle de son jour à l'échelle jour, il ne compte ni dans la marge du chemin critique ni dans un décalage. Un lien peut porter un décalage en jours ouvrés : of_add_dependency("design", "build", DEP_FS, 2) laisse deux jours ouvrés entre la fin de l'une et le début de l'autre (un séchage, une livraison) ; négatif, c'est une avance. La règle de la flèche et le chemin critique le comptent, of_dependency_lag le relit, un DataStore l'écrit après le type ("12:fs+2"). of_add_marker trace un marqueur vertical à la fin d'un jour — une échéance contractuelle, une fin de sprint — avec son libellé en haut. Enfin, avec ib_show_late = true, une tâche en retard — son dernier jour est passé (is_today) et elle n'est pas finie — se dessine en ambre hachuré ; of_is_late() de sa poignée et le champ {late} des modèles le disent dans tous les cas.

// The public holidays of the year : days off, never float
uo_plan.of_add_holiday(/*date*/ "2026-11-11", /*label*/ "Armistice Day")
uo_plan.of_add_holiday(/*date*/ "2026-12-25", /*label*/ "Christmas")

// The paint dries two working days before the second coat
uo_plan.of_add_dependency(/*from_keys*/ "paint", /*to_keys*/ "second_coat", /*type*/ u_pbt_gantt.DEP_FS, /*lag*/ 2)

// The contractual deadline, in red
uo_plan.of_add_marker(/*key*/ "deadline", /*date*/ "2026-12-18", /*label*/ "Contract", /*color*/ RGB(/*red*/ 196, /*green*/ 43, /*blue*/ 28))

// The tasks behind schedule, in amber
uo_plan.ib_show_late = true

Ce que l'utilisateur change #

L'utilisateur glisse une barre pour déplacer la tâche, par jours entiers (ue_task_moved), son bord de fin pour changer sa fin (ue_task_resized), le petit triangle sous la barre pour son avancement (ue_progress_changed) ; une bulle dit les dates ou le pourcentage pendant le glisser, Échap annule. Au clavier, Ctrl + Gauche / Droite déplace la tâche sélectionnée d'un jour et Ctrl + Maj + Gauche / Droite change sa fin. Les événements arrivent la tâche déjà en place. Seul un geste les lève : une date écrite par votre code est muette, comme SetItem. Un récapitulatif ne se glisse pas, une tâche ou un diagramme ib_read_only non plus.

Avec ib_veto_changes = true, ue_task_changing est posé avant chacun de ces trois changements, avec les dates et l'avancement que la tâche prendrait : renvoyer FALSE la laisse comme elle était. Suppr sur la tâche sélectionnée lève ue_delete_requested : le diagramme ne retire rien, of_remove_task une fois votre application d'accord.


Échelle, grille et disposition #

L'échelle (is_scale) se choisit dans la barre d'outils (ib_toolbar, avec le bouton Aujourd'hui), par Ctrl + molette — le jour sous le pointeur reste sous le pointeur — ou par votre code ; ue_scale_changed suit. Aux échelles jour et semaine, les jours chômés (is_work_days) sont grisés. La grille montre les colonnes de is_columns, dans leur ordre, ses dates écrites par is_date_format ; l'utilisateur glisse la ligne entre grille et diagramme (ii_grid_width) et le bord d'un en-tête de colonne pour sa largeur. Ce qu'il a arrangé — l'échelle, les largeurs, les récapitulatifs repliés — se lit par of_get_layout, se rend par of_set_layout, et chaque changement lève ue_layout_changed avec la disposition entière : enregistrez-la, rendez-la au prochain lancement.


Le texte des barres et des info-bulles #

Le texte à côté de chaque barre s'écrit par un modèle, is_bar_template ("{label}" par défaut, vide pour aucun), et l'info-bulle d'une barre par is_tooltip_title_template et is_tooltip_template : du balisage riche où {owner} est un champ de la tâche — un des vôtres (of_set_field), une colonne du DataStore d'où elle vient, ou un champ intégré (label, key, keys, start, end, duration, days, progress, percent, milestone, summary, critical, late, level, parent). {end:d mmm} écrit une date avec les jetons d dd ddd dddd m mm mmm mmmm yy yyyy, {?owner}…{/owner} garde un morceau quand le champ dit quelque chose, {!owner}…{/owner} quand il ne dit rien, {x:raw} garde une valeur comme balisage, {{ }} sont des accolades. {label} et {parent} sont du balisage, comme dans la grille ; toute autre valeur est affichée telle quelle, jamais lue comme balisage. Un nom de champ intégré n'est jamais le vôtre : of_set_field le refuse, et une colonne du DataStore qui porte ce nom est masquée par lui. Une tâche qui a sa propre info-bulle (is_tooltip de sa poignée) montre celle-là.

// Who does what : a field of our own on a task
uo_plan.of_set_field(/*keys*/ "build/design", /*field*/ "owner", /*value*/ "Ada")

// Beside each bar : the label, the owner when there is one, the end day
uo_plan.is_bar_template = "{label}{?owner} - [b]{owner}[/b]{/owner} [symbol=calendar] {end:d mmm}"

Depuis un DataStore #

of_from_datastore fait une tâche de chaque ligne. Sa clé est la valeur de la colonne ROLE_KEY — un identifiant — ou, sans elle, le RowID de la ligne ; la colonne ROLE_PARENT nomme la clé de la tâche qui la contient (vide : en haut ; un parent introuvable ou une boucle met la ligne en haut). Une colonne joue un rôle quand elle en porte le nom (key, parent, label, start, end, progress, milestone, color, predecessors) ou quand of_map le dit. ROLE_MILESTONE fait un jalon de toute valeur qui dit oui ; ROLE_COLOR colore la barre (un RGB() de PowerBuilder ou #rrggbb) ; ROLE_PREDECESSORS liste les tâches attendues, leurs clés séparées par des virgules, le type après : quand ce n'est pas fin à début : "12, 14:ss". Les dates sont lues dans l'ordre régional du poste. Toutes les colonnes sont des champs des modèles. Les tâches d'un chargement précédent partent (leurs poignées sont libérées), celles ajoutées à la main restent. Deux lignes de même clé : la seconde devient key~RowID ; une clé qui contient un / ou un | prend le RowID, et ses enfants la retrouvent par sa valeur ; une clé qu'une tâche ajoutée à la main porte déjà devient key~RowID, sous le même parent — aucune ligne n'est jamais écartée. Une ligne dont le début est vide est une tâche non planifiée : la grille le dit, elle n'a pas de barre et aucun geste ne la déplace. Dates et décimaux sont lus quels que soient les réglages régionaux (12,5 vaut 12.5). of_from_datastore prend aussi un DataWindow ou un DataWindowChild : les lignes que l'utilisateur voit à côté du diagramme, réécrites là. Après un Reset ou un Retrieve du DataStore, redonnez-le : ses RowID repartent de zéro.

Avec ib_write_back = true, un geste écrit dans la ligne avant son événement : les dates de début et de fin pour un déplacement ou une nouvelle fin, l'avancement pour le triangle — chaque valeur dans le type de sa colonne. L'événement lit le DataStore à jour, l'Update reste à vous. Une valeur que le DataStore refuse remet la tâche comme elle était, ce qui était déjà écrit aussi, et lève ue_write_back_failed à la place de l'événement du geste. Après avoir changé une ligne vous-même, of_reload_row la renvoie au diagramme ; une ligne insérée depuis arrive aussi. Une tâche que vous retirez (of_remove_task) reste dehors jusqu'au prochain of_from_datastore : of_map et le rechargement d'une autre ligne ne la ramènent pas, of_reload_row de sa propre ligne la ramène. Après of_clear, of_reload_row refuse (-5) jusqu'à un nouveau chargement.

// Which column of the DataStore plays which role
uo_plan.of_map(/*role*/ u_pbt_gantt.ROLE_KEY, /*column*/ "id")
uo_plan.of_map(/*role*/ u_pbt_gantt.ROLE_PARENT, /*column*/ "parent_id")
uo_plan.of_map(/*role*/ u_pbt_gantt.ROLE_START, /*column*/ "start_date")
uo_plan.of_map(/*role*/ u_pbt_gantt.ROLE_END, /*column*/ "end_date")
uo_plan.of_map(/*role*/ u_pbt_gantt.ROLE_PREDECESSORS, /*column*/ "after")

// A change goes into the DataStore, then the rows become tasks
uo_plan.ib_write_back = true
uo_plan.of_from_datastore(/*ads*/ ids_tasks)

Propriétés #

PropriétéTypeDéfautRôle
is_scalestring"week"L'échelle du temps : SCALE_DAY, SCALE_WEEK, SCALE_MONTH, SCALE_QUARTER. Une valeur inconnue est refusée : l'ancienne reste, of_get_last_error dit pourquoi. La barre d'outils et Ctrl + molette la changent aussi : lue en direct
is_todaystring""Le jour de la ligne aujourd'hui, à l'accent du thème, aaaa-mm-jj ; vide : la date du poste. Une date qui n'en est pas une est refusée : l'ancienne reste, of_get_last_error dit pourquoi
is_work_daysstring"1|2|3|4|5"Les jours ouvrés, numéros ISO joints par | (1 = lundi … 7 = dimanche, 0 accepté pour dimanche) ; les autres sont grisés aux échelles jour et semaine, et la marge du chemin critique ne compte qu'eux. Ce ne sont pas les numéros de DayNumber(), où 1 = dimanche. Une liste qui ne nomme aucun jour est refusée (of_get_last_error)
is_columnsstring"name|start|end|duration|progress"Les colonnes de la grille, dans leur ordre, jointes par | : COLUMN_NAME, COLUMN_START, COLUMN_END, COLUMN_DURATION, COLUMN_PROGRESS. Une colonne inconnue, ou aucune, est refusée : l'ancienne liste reste, of_get_last_error dit pourquoi
is_date_formatstring""Comment la grille écrit une date, avec les jetons d dd ddd dddd m mm mmm mmmm yy yyyy ; vide : la date courte de la langue d'affichage
is_bar_templatestring"{label}"Le texte à côté de chaque barre, écrit par un modèle (voir plus haut) ; vide : aucun texte
is_tooltip_title_templatestring"{label}"Le titre de l'info-bulle d'une barre, écrit par un modèle ; vide avec is_tooltip_template vide : aucune info-bulle
is_tooltip_templatestring"{start} – {end} ({duration}){!milestone}{!summary}[br]{percent}{/summary}{/milestone}"Le texte de l'info-bulle d'une barre, écrit par un modèle : par défaut les dates, la durée et, sauf pour un jalon ou un récapitulatif, l'avancement ; {percent} écrit l'avancement en pourcentage, comme la langue d'affichage l'écrit (50% en anglais)
ib_toolbarbooleantrueLa barre d'outils au-dessus du diagramme : le bouton Aujourd'hui et les quatre échelles
ib_read_onlybooleanfalseL'utilisateur ne change rien : ni glisser, ni redimensionner, ni avancement, ni Ctrl + flèches, ni Suppr, ni lien. Il sélectionne, replie, ouvre et change d'échelle ; votre code change toujours les tâches
ib_veto_changesbooleanfalseOpt-in : demander ue_task_changing avant chaque déplacement, nouvelle fin ou avancement de l'utilisateur. Désactivé par défaut, comme tout événement annulable de la bibliothèque
ib_write_backbooleanfalseUn diagramme alimenté par of_from_datastore : un geste écrit les nouvelles dates ou le nouvel avancement dans le DataStore avant son événement. Une tâche ajoutée à la main n'est jamais écrite. Une colonne datetime garde son heure : le diagramme déplace des jours. Une tâche d'un DataStore sans colonne de fin (ROLE_END) n'a pas de poignée de fin : sa nouvelle fin ne pourrait pas s'écrire
ib_link_by_mousebooleanfalseDeux points de part et d'autre de la barre sous le pointeur : en glisser un sur une autre tâche demande un lien (ue_link_requested)
ib_critical_pathbooleanfalseDessine le chemin critique dans la couleur du danger : les tâches et les liens sans marge, comptée en jours ouvrés (is_work_days) ; un lien qui touche un récapitulatif engage les tâches qu'il contient ; une tâche terminée (100 %) n'est jamais marquée
is_project_endstring""L'échéance du projet, yyyy-mm-dd : la marge du chemin critique se compte jusqu'à la fin de ce jour au lieu de la dernière fin du plan. Plus tard, chaque tâche a du jeu ; plus tôt, celles qui finissent trop tard sont critiques. Vide : la dernière fin. Une date qui n'en est pas une est refusée (of_get_last_error)
ib_show_latebooleanfalseDessine les tâches en retard en ambre hachuré : une tâche — ni récapitulatif ni jalon — dont le dernier jour est avant is_today et dont l'avancement est sous 100. of_is_late() et le champ {late} répondent qu'elle soit dessinée ou non
ii_grid_widthinteger-1 (auto)La largeur de la grille en pixels. Par défaut automatique (-1) : aussi large que les colonnes qu'elle montre, et relue comme cette largeur (544 avec les cinq colonnes). 0 la cache, 2000 au plus ; une autre valeur est refusée (of_get_last_error). L'utilisateur glisse la ligne entre grille et diagramme, ou la déplace aux flèches : lue en direct
ii_row_heightinteger30La hauteur d'une ligne en pixels, de 22 à 60 ; une autre valeur est refusée (of_get_last_error)
is_theme_stylestring""Style visuel du composant (constantes THEME_STYLE_*) ; vide = celui de l'application, suivi à chaque changement
is_theme_modestring""Variante claire ou sombre (constantes THEME_MODE_*) ; vide = celle de l'application, suivie à chaque changement
il_theme_accentlong-1Couleur d'accent de ce composant (-1 = l'accent de l'application, ou celui du thème)
is_tooltipstring""Info-bulle simple affichée au survol du composant
is_super_tooltip_titlestring""Titre de l'info-bulle enrichie (prend le pas sur is_tooltip)
is_super_tooltip_textstring""Texte de l'info-bulle enrichie (balisage riche accepté)
is_super_tooltip_imagestring""Image de l'info-bulle enrichie

Propriétés d'une tâche — n_pbt_gantt_task #

Sa poignée, par of_task(adresse). Une lecture demande au diagramme ce qu'est la tâche maintenant ; une valeur écrite est muette, comme SetItem ; ib_collapsed est un ordre et lève ue_task_toggled. Son of_count() compte les tâches qu'elle contient et son of_keys_at(n) rend l'adresse de la n-ième.

PropriétéTypeDéfautRôle
is_labelstring""Le nom de la tâche, dans la grille, à côté de sa barre et dans son info-bulle : du balisage riche partout ([[1]] pour un crochet). Vide, la tâche montre sa clé
is_startstring—Le premier jour, aaaa-mm-jj. L'écrire déplace la tâche : sa durée reste (écrivez is_end ensuite pour la changer). Refusé pour un récapitulatif, qui tient ses dates de ce qu'il contient, et pour une date qui n'en est pas une : of_get_last_error dit pourquoi
is_endstring—Le dernier jour, compris, aaaa-mm-jj : une tâche du 6 au 10 dure cinq jours. Refusé avant is_start, pour un jalon (il n'a pas de fin à lui) et pour un récapitulatif
id_progressdouble0L'avancement, en pour cent (0 à 100), dessiné dans la barre. Un récapitulatif lit la moyenne de ce qu'il contient, pondérée par les durées ; l'écrire est refusé, pour un jalon aussi
ib_milestonebooleanfalsetrue : un jalon, un jour dessiné en losange, sans durée ni avancement. C'est un instant à la fin de son jour : lié après une tâche qui finit ce jour-là, la règle est tenue ; une tâche liée après lui commence le lendemain
ib_collapsedbooleanfalsetrue replie un récapitulatif : les tâches qu'il contient quittent la grille. ue_task_toggled suit, comme pour un clic sur son chevron. Seul un récapitulatif se replie : true sur une tâche qui ne contient rien est refusé (of_get_last_error). Lu en direct
ib_read_onlybooleanfalseL'utilisateur ne peut ni glisser cette tâche, ni la redimensionner, ni changer son avancement, ni demander sa suppression ; votre code la change toujours
il_accentlong-1La couleur de la barre et de son avancement, en RGB(r,v,b) ; elle passe avant une colonne ROLE_COLOR. -1 = l'accent du composant. Une tâche du chemin critique dessiné reste dans la couleur du danger
il_back_colorlong-1Le fond de la tâche : sa ligne dans la grille et, en lavis pâle, la ligne de sa barre dans le diagramme, en RGB(r,v,b). -1 = celui du composant
il_text_colorlong-1La couleur du texte de la tâche : dans la grille et à côté de sa barre. -1 = celle du composant
il_back_color_hoverlong-1Le fond de la ligne de la tâche dans la grille quand le pointeur la survole. -1 = celui du composant
il_text_color_hoverlong-1La couleur du texte de la ligne de la tâche dans la grille quand le pointeur la survole. -1 = celle du composant
of_duration ( ) → long——Rend sa durée en jours au calendrier, le dernier jour compris ; 0 pour un jalon
of_is_summary ( ) → boolean——TRUE quand la tâche en contient d'autres : ses dates et son avancement se calculent
of_is_critical ( ) → boolean——TRUE quand la tâche est sur le chemin critique : sans marge, un jour de retard et le projet finit un jour plus tard. Répond que ib_critical_path le dessine ou non. La marge se compte en jours ouvrés (is_work_days) ; un récapitulatif n'est jamais critique, les tâches qu'il contient peuvent l'être ; une tâche terminée (100 %) ne l'est jamais
of_position ( ) → long——Rend sa place parmi les tâches de son parent, à partir de 1 ; 0 quand le diagramme ne la contient pas
of_level ( ) → long——Rend sa profondeur : 1 pour une tâche en haut, 2 pour une tâche qu'elle contient…
of_predecessors ( ) → string——Les adresses des tâches dont elle dépend, jointes par | ; vide s'il n'y en a pas
of_successors ( ) → string——Les adresses des tâches qui dépendent d'elle, jointes par | ; vide s'il n'y en a pas
of_is_late ( ) → boolean——En retard : son dernier jour est avant is_today et elle n'est pas finie (avancement sous 100). Un récapitulatif et un jalon ne le sont jamais ; répond que ib_show_late le dessine ou non
of_row ( ) → long——Rend le numéro de ligne aujourd'hui, dans le DataStore de of_from_datastore, de la ligne d'où vient la tâche — quelle que soit la clé qu'elle a dû prendre, et après un tri ou un filtre. 0 pour une tâche posée à la main ou dont la ligne a disparu
is_tooltipstring""Info-bulle simple affichée au survol de l'item
is_super_tooltip_titlestring""Titre de l'info-bulle enrichie de l'item (prend le pas sur is_tooltip)
is_super_tooltip_textstring""Texte de l'info-bulle enrichie de l'item (balisage riche accepté)
is_super_tooltip_imagestring""Image de l'info-bulle enrichie de l'item

Constantes #

ConstanteValeurSens
SCALE_DAY"day"Une colonne par jour
SCALE_WEEK"week"Une colonne par semaine — l'échelle par défaut
SCALE_MONTH"month"Une colonne par mois
SCALE_QUARTER"quarter"Une colonne par trimestre
COLUMN_NAME"name"Le nom de la tâche, en arbre
COLUMN_START"start"Le premier jour
COLUMN_END"end"Le dernier jour
COLUMN_DURATION"duration"La durée en jours
COLUMN_PROGRESS"progress"L'avancement en pour cent
DEP_FS"fs"Fin à début : la suivante commence une fois la précédente finie (le lien habituel)
DEP_SS"ss"Début à début : elles commencent ensemble
DEP_FF"ff"Fin à fin : elles finissent ensemble
DEP_SF"sf"Début à fin : la suivante finit quand la précédente commence
CHANGE_MOVE"move"Un déplacement : les deux dates
CHANGE_RESIZE"resize"Une nouvelle fin
CHANGE_PROGRESS"progress"Un nouvel avancement
ROLE_KEY"key"La clé de la tâche (un identifiant) ; sans elle, le RowID
ROLE_PARENT"parent"La clé de la tâche qui la contient
ROLE_LABEL"label"Son nom
ROLE_START"start"Son premier jour
ROLE_END"end"Son dernier jour (vide : le premier)
ROLE_PROGRESS"progress"Son avancement, de 0 à 100
ROLE_MILESTONE"milestone"Un jalon quand la valeur dit oui
ROLE_COLOR"color"La couleur de sa barre
ROLE_PREDECESSORS"predecessors"Les tâches qu'elle attend : "12, 14:ss, 15:fs+2" (un décalage en jours ouvrés s'écrit après le type)

Méthodes #

MéthodeRôle
of_add_dependency (string as_from_keys, string as_to_keys)Ajoute un lien fin à début : as_to_keys commence une fois as_from_keys finie. Rend 0 une fois ajouté, -5 ou -2 comme la forme à trois arguments
of_add_dependency (string as_from_keys, string as_to_keys, string as_type)Ajoute un lien d'un type DEP_FS, DEP_SS, DEP_FF ou DEP_SF, dessiné en flèche. Rend 0 une fois ajouté, -5 pour une tâche inconnue, un lien vers soi-même ou entre une tâche et ce qu'elle contient, un lien déjà là (quel que soit son type), un lien qui fermerait une boucle ou un type inconnu, -2 quand le composant n'est pas créé
of_add_dependency (string as_from_keys, string as_to_keys, string as_type, long al_lag)Le même lien avec un décalage en jours ouvrés (is_work_days, moins les jours fériés) : 2 laisse deux jours ouvrés entre la fin de l'une et le début de l'autre, un nombre négatif est une avance. La règle de la flèche et le chemin critique le comptent. Rend 0 une fois ajouté, -5 comme la forme à trois arguments ou pour un décalage au-delà de 999 jours, -2 quand le composant n'est pas créé
of_add_holiday (string as_date)Ajoute un jour férié sans nom. Rend 0 une fois ajouté, -5 ou -2 comme la forme à deux arguments
of_add_holiday (string as_date, string as_label)Ajoute un jour férié, aaaa-mm-jj : un jour chômé quoi que dise is_work_days, grisé comme un week-end, nommé par as_label dans l'info-bulle de son jour à l'échelle jour ; la marge du chemin critique et le décalage d'un lien ne le comptent pas. Un par un ; of_clear le garde, of_reset l'efface. Rend 0 une fois ajouté, -5 pour une date qui n'en est pas une ou un jour déjà férié, -2 quand le composant n'est pas créé
of_add_holiday (date ad_date, string as_label)La même chose depuis une date de PowerBuilder. Rend 0 une fois ajouté, -5 aussi pour une date nulle
of_add_marker (string as_key, string as_date, string as_label)Ajoute un marqueur vertical dans la couleur du texte atténué. Rend 0 une fois ajouté, -5 ou -2 comme la forme à quatre arguments
of_add_marker (string as_key, string as_date, string as_label, long al_color)Ajoute un marqueur vertical : un trait pointillé à la fin de son jour (une échéance tient jusqu'au bout de son jour, comme un jalon), son libellé — texte riche à balises — en haut du diagramme : une échéance contractuelle, une fin de sprint, un gel. al_color est une couleur RGB(), -1 pour celle du texte atténué. Rend 0 une fois ajouté, -5 pour une clé qui ne peut pas en être une (vide, avec / ou |), une clé déjà prise ou une date qui n'en est pas une, -2 quand le composant n'est pas créé
of_add_milestone (string as_keys, string as_label, string as_date)Ajoute un jalon à son adresse : un jour, un losange, sans durée. Rend 0 une fois ajouté, -5 comme of_add_task, -2 quand le composant n'est pas créé
of_add_milestone (string as_keys, string as_label, date ad_date)La même chose depuis une date de PowerBuilder. Rend 0 une fois ajouté, -5 aussi pour une date nulle
of_add_task (string as_keys, string as_label, string as_start, string as_end)Ajoute une tâche à son adresse : "phase1" en haut, "phase1/design" dans la tâche "phase1", ajoutée d'abord (elle devient un récapitulatif). Dates aaaa-mm-jj, la fin comprise ("" : un jour). Rend 0 une fois ajoutée, -5 pour une adresse à niveau vide ou dont une clé contient |, une adresse déjà prise, un parent inconnu, une date qui n'en est pas une ou une fin avant le début, -2 quand le composant n'est pas créé
of_add_task (string as_keys, string as_label, date ad_start, date ad_end)La même chose depuis deux date de PowerBuilder, la fin étant le dernier jour, compris. Rend 0 une fois ajoutée, -5 aussi pour un début nul (une fin nulle : un jour)
of_clear ( )Vide le diagramme : tâches, liens, leurs poignées et les lignes du DataStore (il reste lié, pour un nouvel of_from_datastore ; of_reload_row refuse d'ici là) ; les options restent. Rend 0 une fois appliqué, -2 quand le composant n'est pas créé
of_clear_dependencies ( )Retire tous les liens ; les tâches restent. Rend 0 une fois appliqué, -2 quand le composant n'est pas créé
of_clear_holidays ( )Retire tous les jours fériés : seul is_work_days dit les jours ouvrés. Rend 0 une fois appliqué, -2 quand le composant n'est pas créé
of_clear_markers ( )Retire tous les marqueurs ; of_clear les garde, comme les jours fériés. Rend 0 une fois appliqué, -2 quand le composant n'est pas créé
of_clear_selection ( )Ne laisse aucune tâche sélectionnée : ue_selection_changed suit avec une adresse vide ; rien de sélectionné, rien n'est levé. Rend 0 une fois appliqué, -2 quand le composant n'est pas créé
of_collapse_all ( )Replie tous les récapitulatifs : ue_task_toggled suit pour chacun de ceux qui étaient ouverts, puis ue_layout_changed une fois. Rend 0 une fois appliqué, -2 quand le composant n'est pas créé
of_dependency_lag (string as_from_keys, string as_to_keys)Rend le décalage du lien d'une tâche vers une autre, en jours ouvrés, lu en direct : négatif pour une avance, 0 sans décalage ou sans lien
of_dependency_type (string as_from_keys, string as_to_keys)Le type du lien d'une tâche vers une autre (DEP_FS…), vide s'il n'y en a pas. Lu en direct
of_expand_all ( )Ouvre tous les récapitulatifs : ue_task_toggled suit pour chacun de ceux qui étaient repliés, puis ue_layout_changed une fois. Rend 0 une fois appliqué, -2 quand le composant n'est pas créé
of_from_datastore (datastore ads)Fait une tâche de chaque ligne du DataStore (voir plus haut). Les tâches d'un chargement précédent partent, celles ajoutées à la main restent, leurs poignées aussi. Rend 0 une fois chargé, -5 quand le DataStore n'est pas valide ou n'a pas de colonne, -2 quand le composant n'est pas créé
of_from_datastore (datawindow adw)La même chose depuis les lignes d'un DataWindow — celui que l'utilisateur voit à côté : ib_write_back écrit dans ce DataWindow. Un DataWindow qui ne peut pas partager ses données est refusé. Rend 0 une fois chargé, -5 quand le DataWindow n'est pas valide, n'a pas de colonne ou ne se partage pas, -2 quand le composant n'est pas créé
of_from_datastore (datawindowchild adwc)La même chose depuis les lignes d'un DataWindowChild (une liste déroulante DataWindow, un état imbriqué), écrit en retour par ib_write_back. Rend 0 une fois chargé, -5 quand il n'est pas valide, n'a pas de colonne ou ne se partage pas, -2 quand le composant n'est pas créé
of_get_field (string as_keys, string as_field)Lit un champ d'une tâche, en direct : un des vôtres, une colonne de son DataStore ou un champ intégré (duration, critical…) — qui rend le texte affiché et masque une colonne du même nom. Une chaîne vide quand elle n'en a pas
of_get_last_error ( )Pourquoi la dernière écriture d'une propriété a été refusée (une date qui n'en est pas une, les dates d'un récapitulatif, une échelle ou une colonne inconnue) ; sinon la dernière erreur de la bibliothèque
of_get_layout ( )Ce que l'utilisateur a arrangé, en JSON : {"scale":"week","gridWidth":-1,"columns":[{"key":"name","width":200},...],"collapsed":["phase2"]} — l'échelle, la largeur de la grille et de chaque colonne, les récapitulatifs repliés. gridWidth vaut -1 tant que la grille est automatique. À enregistrer puis à rendre à of_set_layout. Lu en direct
of_holidays ( )Les jours fériés, lus en direct : aaaa-mm-jj joints par |, dans l'ordre des dates ; vide s'il n'y en a pas
of_map (string as_role, string as_column)Donne un rôle à une colonne du DataStore (ROLE_KEY, ROLE_PARENT, ROLE_LABEL, ROLE_START, ROLE_END, ROLE_PROGRESS, ROLE_MILESTONE, ROLE_COLOR, ROLE_PREDECESSORS), avant ou après of_from_datastore : après, les lignes sont relues. Une colonne vide rend le rôle à la colonne qui porte son nom. Ce qui a été posé sur les tâches reste (repli, lecture seule, champs, couleurs, liens ajoutés par le code). Un nouveau ROLE_KEY ou ROLE_PARENT donne de nouvelles adresses aux tâches des lignes : leurs poignées sont libérées, celles des tâches ajoutées à la main restent. Rend 0 une fois posé, -5 pour un rôle inconnu ou une colonne que le DataStore n'a pas, -2 quand le composant n'est pas créé
of_markers ( )Les clés des marqueurs, lues en direct, dans leur ordre, jointes par | ; vide s'il n'y en a pas
of_reload_row (long al_row)Renvoie au diagramme une ligne du DataStore d'of_from_datastore, relue maintenant, après que votre code l'a changée (SetItem, une fenêtre d'édition) ; al_row est son numéro de ligne aujourd'hui. La tâche suit sa ligne sur place : ce qui a été posé sur elle (repli, lecture seule, champs, couleurs, liens ajoutés par le code) reste, un glisser en cours continue, rien n'est levé. Une ligne dont la clé ou le parent a changé déplace sa tâche, avec ce qui a été posé sur elle ; une ligne insérée depuis arrive aussi. Rend 0 une fois envoyée, -5 quand aucun DataStore n'est lié, que le diagramme n'a plus de lignes depuis of_clear ou que la ligne n'existe pas (of_get_last_error dit lequel), -2 quand le composant n'est pas créé
of_remove_dependency (string as_from_keys, string as_to_keys)Retire le lien d'une tâche vers une autre. Rend 0 une fois retiré, -5 pour un lien que le diagramme n'a pas, -2 quand le composant n'est pas créé
of_remove_holiday (string as_date)Le jour redevient ouvré. Rend 0 une fois retiré, -5 pour un jour qui n'est pas un jour férié de ce diagramme, -2 quand le composant n'est pas créé
of_remove_marker (string as_key)Retire un marqueur. Rend 0 une fois retiré, -5 pour une clé que ce diagramme ne tient pas, -2 quand le composant n'est pas créé
of_remove_task (string as_keys)Retire une tâche, tout ce qu'elle contient et chaque lien qui les touche, et libère leurs poignées ; retirer la tâche sélectionnée vide la sélection. La tâche d'une ligne de DataStore reste dehors jusqu'au prochain of_from_datastore ; of_reload_row de sa ligne la ramène. Rend 0 une fois retirée, -5 pour une adresse que le diagramme n'a pas, -2 quand le composant n'est pas créé
of_reset ( )Vide le diagramme, oublie le DataStore et remet chaque propriété à sa valeur par défaut, chaque colonne à sa largeur. Rend 0 une fois appliqué, -2 quand le composant n'est pas créé
of_scroll_to_date (string as_date)Fait défiler l'axe du temps jusqu'à ce jour (aaaa-mm-jj), placé au premier tiers de la vue. Rend 0 une fois appliqué, -5 pour une date qui n'en est pas une, -2 quand le composant n'est pas créé
of_scroll_to_task (string as_keys)Montre une tâche : les récapitulatifs qui la contiennent s'ouvrent (ue_task_toggled pour chacun), puis le diagramme défile jusqu'à sa ligne et sa barre. Rend 0 une fois appliqué, -5 pour une tâche que le diagramme n'a pas, -2 quand le composant n'est pas créé
of_select_task (string as_keys)Sélectionne une tâche comme un clic, sans déplacer la vue (comme SelectRow d'un DataWindow), et ue_selection_changed suit. Rend 0 une fois sélectionnée (ou déjà sélectionnée : rien n'est levé), -5 pour une tâche inconnue ou non dessinée (dans un récapitulatif replié, au-delà du plafond de démonstration), -2 quand le composant n'est pas créé
of_selected_key ( )L'adresse de la tâche sélectionnée, quel que soit qui l'a sélectionnée ; vide si aucune. Lue en direct
of_set_field (string as_keys, string as_field, string as_value)Donne à une tâche un champ à vous, pour les modèles ; il passe avant une colonne du DataStore du même nom. Un nom de champ : lettres, chiffres et _, sans chiffre en tête. Rend 0 une fois posé, -5 pour une tâche inconnue, un nom qui n'en est pas un ou le nom d'un champ intégré (label, start…), -2 quand le composant n'est pas créé
of_set_layout (string as_layout_json)Rend une disposition lue par of_get_layout ou reçue par ue_layout_changed : l'échelle, les largeurs, et quels récapitulatifs sont repliés (ceux qu'elle ne nomme pas s'ouvrent) ; une colonne ou une tâche inconnue du diagramme est ignorée. ue_layout_changed est levé une fois si quelque chose a changé (ni ue_task_toggled ni ue_scale_changed : elle remet un état). Rend 0 une fois appliquée, -5 quand le texte est vide ou n'est pas un objet JSON, -2 quand le composant n'est pas créé
of_task (string as_keys)Rend la poignée d'une tâche, par son adresse (créée au premier accès, libérée quand la tâche est retirée)

Événements #

ÉvénementDéclenché quand
ue_task_moved (string as_keys, string as_start, string as_end, string as_old_start, string as_old_end)L'utilisateur a déplacé une tâche : sa barre glissée, ou Ctrl + Gauche / Droite. as_start et as_end sont ses nouveaux jours, as_old_start et as_old_end ceux qu'elle avait, aaaa-mm-jj — de quoi tenir un journal ou annuler. La tâche est déjà en place ; avec ib_write_back, le DataStore est déjà écrit. Une date écrite par votre code ne lève rien
ue_task_resized (string as_keys, string as_start, string as_end, string as_old_start, string as_old_end)L'utilisateur a changé la fin d'une tâche : le bord de fin de sa barre glissé, ou Ctrl + Maj + Gauche / Droite. Les anciens jours viennent avec les nouveaux
ue_progress_changed (string as_keys, double ad_progress, double ad_old_progress)L'utilisateur a changé l'avancement d'une tâche : le petit triangle sous sa barre glissé, ou Ctrl + Haut / Bas (10 points). ad_progress est le nouveau, en pour cent, ad_old_progress celui qu'elle avait
ue_task_changing (string as_keys, string as_kind, string as_start, string as_end, double ad_progress) → booleanAnnulable, posé avant un déplacement, une nouvelle fin ou un avancement de l'utilisateur, seulement quand ib_veto_changes = true. as_kind dit lequel : CHANGE_MOVE, CHANGE_RESIZE ou CHANGE_PROGRESS ; les valeurs sont celles que la tâche prendrait. Renvoyer FALSE la laisse comme elle était
ue_task_clicked (string as_keys)Une tâche a été cliquée (et sélectionnée) : sa ligne dans la grille ou sa barre. Pas à la fin d'un glisser
ue_task_opened (string as_keys)Double-clic sur une tâche, ou Entrée : ouvrez votre éditeur. Un double-clic sur la ligne d'un récapitulatif le replie ou l'ouvre à la place
ue_task_rclicked (string as_keys, long al_x, long al_y)Clic droit sur une tâche (sélectionnée d'abord), ou la touche Menu (Maj + F10) sur la tâche sélectionnée. al_x, al_y sont des pixels d'écran ; pour un menu PowerBuilder, PopMenu(PointerX(), PointerY()) de votre fenêtre
ue_selection_changed (string as_from_keys, string as_keys)La tâche sélectionnée a changé : clic, clavier, votre code (of_select_task, of_clear_selection), ou la tâche sélectionnée a quitté la grille (retirée, dans un récapitulatif replié : as_keys est alors vide)
ue_task_toggled (string as_keys, boolean ab_collapsed)Un récapitulatif s'est replié (ab_collapsed = TRUE) ou ouvert : son chevron, un double-clic sur sa ligne, le clavier, son ib_collapsed posé par votre code, of_expand_all, of_collapse_all, of_scroll_to_task
ue_delete_requested (string as_keys)Suppr a été pressée sur la tâche sélectionnée. Le diagramme ne retire rien : of_remove_task une fois votre application d'accord. Jamais sur une tâche ou un diagramme en lecture seule
ue_link_requested (string as_from_keys, string as_to_keys, string as_type)L'utilisateur a tracé un lien d'une tâche vers une autre (ib_link_by_mouse) ; as_type est une constante DEP_. Le diagramme n'ajoute rien : of_add_dependency une fois votre application d'accord
ue_dependency_clicked (string as_from_keys, string as_to_keys, string as_type)Une flèche entre deux tâches a été cliquée
ue_scale_changed (string as_scale)L'échelle a changé : la barre d'outils, Ctrl + molette, ou is_scale posé par votre code
ue_layout_changed (string as_layout_json)La disposition a changé : l'échelle, la largeur de la grille ou d'une colonne, un récapitulatif replié ou ouvert (par l'utilisateur ou par votre code), ou of_set_layout. as_layout_json est la disposition entière, telle que la rend of_get_layout : enregistrez-la
ue_write_back_failed (string as_keys, string as_col, string as_value, string as_reason)ib_write_back : le DataStore a refusé une nouvelle valeur d'une tâche (un type que sa colonne ne tient pas, une ligne supprimée depuis le chargement). La tâche est revenue comme elle était, et l'événement du geste n'est pas levé
ue_ready ( )Le composant a fini de charger ; tout ce qui a été envoyé avant a été rejoué
ue_runtime_missing ( )Le runtime WebView2 est absent : le composant reste vide
ue_bg_color (long al_color)Le composant a calculé sa couleur de fond de thème ; l'userobject l'a déjà adoptée (backcolor)

Clavier et souris #


Exemples #

Des règles de planning #

// Once, after the plan is built : ask before each change of the user
uo_plan.ib_veto_changes = true

// event ue_task_changing of uo_plan : nothing ends after the go-live
if as_keys <> "golive" and as_end > this.of_task(/*keys*/ "golive").is_start then return false

// and nothing moves into the past : a task already started keeps its start
if as_start < String(Today(), "yyyy-mm-dd") and as_start < this.of_task(/*keys*/ as_keys).is_start then return false
return true

Des liens tracés à la souris #

// Once : two dots beside the bar under the pointer, the critical path in red
uo_plan.ib_link_by_mouse = true
uo_plan.ib_critical_path = true

// event ue_link_requested of uo_plan : the chart adds nothing by itself
if this.of_add_dependency(/*from_keys*/ as_from_keys, /*to_keys*/ as_to_keys, /*type*/ as_type) = -5 then
	MessageBox("Plan", "This link cannot be added.")
end if

// event ue_dependency_clicked of uo_plan : a click on an arrow removes it
this.of_remove_dependency(/*from_keys*/ as_from_keys, /*to_keys*/ as_to_keys)

Retrouver sa disposition au prochain lancement #

// The layout stored at the last start, if any
uo_plan.of_set_layout(/*layout_json*/ ProfileString(gs_ini, "plan", "layout", ""))

// event ue_layout_changed of uo_plan : store every change
SetProfileString(gs_ini, "plan", "layout", as_layout_json)

Ouvrir une tâche dans votre fenêtre #

// event ue_task_opened of uo_plan
// Local variables
long ll_row

// The row of the task in the DataStore, whatever key the task had to take
ll_row = this.of_task(/*keys*/ as_keys).of_row()

// A task added by hand has no row
if ll_row = 0 then return

// Edited in your window, then the task follows its row
OpenWithParm(w_task_edit, ll_row)
this.of_reload_row(/*row*/ ll_row)

Bonnes pratiques #

Hérité du socle commun #

Ces membres existent sur tous les composants visuels — ils ne sont pas propres à celui-ci. Ils sont détaillés une seule fois, dans les chapitres transverses ; cette table dit seulement où les lire.

MembresRôleDétaillé dans
of_count · of_keys_at · of_hasParcourir ce que le composant contient3.2 Les items
of_resetRemettre le composant à zéro3.6 Remettre un composant à zéro : of_reset()
of_register_shortcut · of_clear_shortcutsRaccourcis clavier du composant3.5 Les raccourcis clavier
of_is_created · of_is_ready · of_get_last_errorS'il est né, s'il est prêt, ce qui a échoué3.7 Diagnostic
of_save_as_png · of_save_as_jpgExporter le rendu en image3.8 Exporter le rendu en image
of_set_redrawGrouper les modifications en un seul repaint3.10 Bonnes pratiques
of_preload_iconsIcônes affichées sans délaiAffichage instantané : of_icon
of_set_translationTraduire un libellé du composant5.2 Adapter un libellé : of_set_translation
of_focus_webviewDonner le focus au composant6.4 Clavier et focus
of_print · of_print_to_pdfImprimer, ou écrire un PDF6.9 Imprimer
of_set_property · of_get_property · of_component_namePiloter une propriété par son nom3.1 Le moteur de propriétés
is_accessible_name · is_accessible_descriptionLe nom et la description que dit un lecteur d'écran3.4 Propriétés et events optionnels

Deux aides ne sont pas héritées : of_icon et of_escape_markup vivent sur n_pbt_utils. Déclarez-en une — n_pbt_utils lnv_utils, rien à créer — et appelez-les dessus.

← Référence des composants · Sommaire du guide