PBToolboxAI v5 ← Site

gantt — u_pbt_gantt #

← Referencia de componentes · Índice de la guía

gantt planifica un proyecto: a la izquierda una cuadrícula de tareas (nombre, inicio, fin, duración, avance), a la derecha sus barras sobre una escala de tiempo — día, semana, mes o trimestre — con la línea de hoy (en el color de acento) y los días no laborables sombreados. Una tarea que contiene otras es una tarea resumen, cuyas fechas y avance se calculan; un hito es un rombo de un día; una flecha une una tarea con la que la espera, y la ruta crítica se dibuja en rojo. El usuario arrastra una barra para moverla, su borde final para cambiar su fin, el pequeño triángulo bajo ella para su avance; ue_task_moved, ue_task_resized y ue_progress_changed se lo dicen. El plan se llena a mano o desde un DataStore, que recibe los cambios.

▶ Verlo en vivo — Aplicación de demostración, mosaico Gantt chart: la vista previa, el código que lo genera y esta página, uno al lado del otro.


De un vistazo #

Userobjectu_pbt_gantt
Clase de elementosn_pbt_gantt_task (of_task(keys))
Sirve paraPlanificar y seguir un proyecto: fases, tareas, hitos, vínculos, retrasos
PrincipioUna tarea se designa por su dirección ("build/design"); una tarea resumen calcula sus fechas y su avance a partir de lo que contiene
Opciones opt-inib_veto_changes, ib_write_back, ib_link_by_mouse, ib_critical_path, ib_show_late, ib_read_only

Inicio rápido #

// 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;

Tareas, resúmenes e hitos #

Una tarea se designa por su dirección: su clave bajo su padre, los niveles unidos por / — "build" arriba, "build/design" dentro de la tarea "build", añadida antes. Una tarea que contiene otras se convierte en una tarea resumen: una barra fina, sus fechas van del primer inicio al último día de lo que contiene, su avance es su media ponderada por las duraciones. Ni el usuario ni su código escriben sus fechas o su avance: se calculan. Su cheurón, un doble clic en su fila o ib_collapsed la pliegan; sigue ue_task_toggled.

Las fechas son días enteros, aaaa-mm-dd, el fin incluido: una tarea del 6 al 10 dura cinco días, contados en el calendario. of_add_task y of_add_milestone aceptan también dos date de PowerBuilder. Un hito no tiene duración: un día, un rombo, ningún avance. Mediante el handle de una tarea (of_task(dirección)), escribir is_start la mueve (su duración se mantiene), is_end cambia su fin, id_progress su avance; un valor escrito por su código no lanza nada, como SetItem. El mismo handle lee lo que la tarea es ahora: sus fechas, su duración (of_duration), su lugar entre sus hermanas desde 1 (of_position), su nivel (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) + " %")

Vínculos y ruta crítica #

of_add_dependency une dos tareas con una flecha. El tipo por defecto es fin a inicio (DEP_FS: la siguiente empieza una vez terminada la anterior); DEP_SS (inicio a inicio), DEP_FF (fin a fin) y DEP_SF (inicio a fin) se dan como tercer argumento. Un vínculo que las fechas rompen — la siguiente empieza demasiado pronto — se dibuja discontinuo en el color de peligro. Un vínculo hacia sí misma, entre una tarea y lo que contiene, un vínculo ya existente o uno que cerraría un bucle se rechaza (-5). of_dependency_type lee el tipo de un vínculo, of_predecessors y of_successors del handle las tareas vinculadas.

Con ib_critical_path = true, la ruta crítica se dibuja en el color de peligro: las tareas y los vínculos sin holgura, los que retrasan el fin del proyecto si se desplazan un día. of_is_critical del handle la lee, esté dibujada o no. Con ib_link_by_mouse = true, aparecen dos puntos a cada lado de la barra bajo el puntero: el usuario arrastra uno sobre otra tarea, y ue_link_requested da el vínculo pedido — su tipo sigue el punto de partida y la mitad de la barra de destino. El diagrama no añade nada por sí mismo: of_add_dependency una vez que su aplicación esté de acuerdo. Un clic en una flecha lanza ue_dependency_clicked. La holgura se cuenta en días laborables (is_work_days): una tarea que termina un viernes seguida de otra que empieza el lunes no tiene ninguna. Un hito es un instante al final de su día: puesto el día en que termina la tarea a la que sigue, el vínculo se cumple, y la tarea que va detrás empieza al día siguiente. Un vínculo que toca una tarea resumen compromete las tareas que contiene; una tarea resumen nunca se marca, y una flecha solo es roja entre dos barras rojas. Una tarea terminada (100 %) nunca se marca: ya no dirige nada. is_project_end cuenta la holgura hasta un plazo en lugar del último fin.


Calendario: festivos, desfases, marcadores y retrasos #

Un proyecto sigue un calendario. is_work_days indica los días laborables de la semana; of_add_holiday añade un día festivo, uno a uno — sombreado como un fin de semana, nombrado en la información emergente de su día en la escala día, no cuenta ni en la holgura de la ruta crítica ni en un desfase. Un vínculo puede llevar un desfase en días laborables: of_add_dependency("design", "build", DEP_FS, 2) deja dos días laborables entre el fin de una y el inicio de la otra (un secado, una entrega); negativo, es un adelanto. La regla de la flecha y la ruta crítica lo cuentan, of_dependency_lag lo relee, un DataStore lo escribe tras el tipo ("12:fs+2"). of_add_marker traza un marcador vertical al final de un día — un plazo contractual, el fin de un sprint — con su etiqueta arriba. Por último, con ib_show_late = true, una tarea retrasada — su último día ha pasado (is_today) y no está terminada — se dibuja en ámbar rayado; of_is_late() de su handle y el campo {late} de las plantillas lo dicen en todo caso.

// 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

Lo que el usuario cambia #

El usuario arrastra una barra para mover la tarea, por días enteros (ue_task_moved), su borde final para cambiar su fin (ue_task_resized), el pequeño triángulo bajo la barra para su avance (ue_progress_changed); una burbuja muestra las fechas o el porcentaje durante el arrastre, Esc cancela. Con el teclado, Ctrl + Izquierda / Derecha mueve la tarea seleccionada un día y Ctrl + Mayús + Izquierda / Derecha cambia su fin. Los eventos llegan con la tarea ya en su sitio. Solo un gesto los lanza: una fecha escrita por su código es muda, como SetItem. Una tarea resumen no se arrastra, ni una tarea o un diagrama ib_read_only.

Con ib_veto_changes = true, ue_task_changing se plantea antes de cada uno de estos tres cambios, con las fechas y el avance que la tarea tomaría: devolver FALSE la deja como estaba. Supr en la tarea seleccionada lanza ue_delete_requested: el diagrama no quita nada, of_remove_task una vez que su aplicación esté de acuerdo.


Escala, cuadrícula y disposición #

La escala (is_scale) se elige en la barra de herramientas (ib_toolbar, con el botón Hoy), con Ctrl + rueda — el día bajo el puntero se queda bajo el puntero — o desde su código; sigue ue_scale_changed. En las escalas día y semana, los días no laborables (is_work_days) se sombrean. La cuadrícula muestra las columnas de is_columns, en su orden, con sus fechas escritas según is_date_format; el usuario arrastra la línea entre cuadrícula y diagrama (ii_grid_width) y el borde de un encabezado de columna para su anchura. Lo que ha organizado — la escala, las anchuras, los resúmenes plegados — se lee con of_get_layout, se devuelve con of_set_layout, y cada cambio lanza ue_layout_changed con la disposición entera: guárdela y devuélvala en el próximo inicio.


El texto de las barras y de la información emergente #

El texto junto a cada barra se escribe con una plantilla, is_bar_template ("{label}" por defecto, vacía para ninguno), y la información emergente de una barra con is_tooltip_title_template e is_tooltip_template: texto enriquecido con etiquetas donde {owner} es un campo de la tarea — uno de los suyos (of_set_field), una columna del DataStore del que procede, o un campo integrado (label, key, keys, start, end, duration, days, progress, percent, milestone, summary, critical, late, level, parent). {end:d mmm} escribe una fecha con los símbolos d dd ddd dddd m mm mmm mmmm yy yyyy, {?owner}…{/owner} conserva un fragmento cuando el campo dice algo, {!owner}…{/owner} cuando no dice nada, {x:raw} conserva un valor como etiquetas, {{ }} son llaves. {label} y {parent} son etiquetas, como en la cuadrícula; cualquier otro valor se muestra tal cual, nunca se lee como etiquetas. Un nombre de campo integrado nunca es suyo: of_set_field lo rechaza, y una columna del DataStore con ese nombre queda oculta por él. Una tarea con su propia información emergente (is_tooltip de su handle) muestra esa.

// 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}"

Desde un DataStore #

of_from_datastore hace una tarea de cada fila. Su clave es el valor de la columna ROLE_KEY — un identificador — o, sin ella, el RowID de la fila; la columna ROLE_PARENT nombra la clave de la tarea que la contiene (vacía: arriba; un padre no encontrado o un bucle pone la fila arriba). Una columna desempeña un rol cuando se llama como él (key, parent, label, start, end, progress, milestone, color, predecessors) o cuando of_map lo dice. ROLE_MILESTONE hace un hito de todo valor que dice sí; ROLE_COLOR colorea la barra (un RGB() de PowerBuilder o #rrggbb); ROLE_PREDECESSORS lista las tareas esperadas, sus claves separadas por comas, el tipo tras : cuando no es fin a inicio: "12, 14:ss". Las fechas se leen en el orden regional del puesto. Todas las columnas son campos de las plantillas. Las tareas de una carga anterior se van (sus handles se liberan), las añadidas a mano se quedan. Dos filas con la misma clave: la segunda pasa a key~RowID; una clave que contiene / o | toma el RowID, y sus hijos la encuentran por su valor; una clave que ya lleva una tarea añadida a mano pasa a key~RowID, bajo el mismo padre — nunca se descarta ninguna fila. Una fila con el inicio vacío es una tarea sin planificar: la cuadrícula lo dice, no tiene barra y ningún gesto la mueve. Fechas y decimales se leen sean cuales sean los ajustes regionales (12,5 vale 12.5). of_from_datastore también acepta un DataWindow o un DataWindowChild: las filas que el usuario ve junto al diagrama, reescritas allí. Tras un Reset o un Retrieve del DataStore, vuelva a darlo: sus RowID empiezan de nuevo.

Con ib_write_back = true, un gesto escribe en la fila antes de su evento: las fechas de inicio y de fin para un movimiento o un nuevo fin, el avance para el triángulo — cada valor en el tipo de su columna. El evento lee el DataStore actualizado, el Update sigue siendo cosa suya. Un valor que el DataStore rechaza devuelve la tarea a como estaba, y también lo que ya estaba escrito, y lanza ue_write_back_failed en lugar del evento del gesto. Tras cambiar usted mismo una fila, of_reload_row la vuelve a enviar al diagrama; una fila insertada desde entonces también llega. Una tarea que usted quita (of_remove_task) queda fuera hasta el próximo of_from_datastore: of_map y la recarga de otra fila no la devuelven, of_reload_row de su propia fila sí. Tras of_clear, of_reload_row rechaza (-5) hasta una nueva carga.

// 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)

Propiedades #

PropiedadTipoPredeterminadoFunción
is_scalestring"week"La escala del tiempo: SCALE_DAY, SCALE_WEEK, SCALE_MONTH, SCALE_QUARTER. Un valor desconocido se rechaza: el anterior se queda, of_get_last_error dice por qué. La barra de herramientas y Ctrl + rueda también la cambian: leída en directo
is_todaystring""El día de la línea de hoy, en el color de acento, aaaa-mm-dd; vacío: la fecha del puesto. Una fecha no válida se rechaza: la anterior se queda, of_get_last_error dice por qué
is_work_daysstring"1|2|3|4|5"Los días laborables, números ISO unidos por | (1 = lunes … 7 = domingo, 0 aceptado para domingo); los demás se sombrean en las escalas día y semana, y la holgura de la ruta crítica solo cuenta estos. No son los números de DayNumber(), donde 1 = domingo. Una lista que no nombra ningún día se rechaza (of_get_last_error)
is_columnsstring"name|start|end|duration|progress"Las columnas de la cuadrícula, en su orden, unidas por |: COLUMN_NAME, COLUMN_START, COLUMN_END, COLUMN_DURATION, COLUMN_PROGRESS. Una columna desconocida, o ninguna, se rechaza: la lista anterior se queda, of_get_last_error dice por qué
is_date_formatstring""Cómo escribe la cuadrícula una fecha, con los símbolos d dd ddd dddd m mm mmm mmmm yy yyyy; vacío: la fecha corta del idioma de visualización
is_bar_templatestring"{label}"El texto junto a cada barra, escrito por una plantilla (ver más arriba); vacío: ningún texto
is_tooltip_title_templatestring"{label}"El título de la información emergente de una barra, escrito por una plantilla; vacío con is_tooltip_template vacío: ninguna información emergente
is_tooltip_templatestring"{start} – {end} ({duration}){!milestone}{!summary}[br]{percent}{/summary}{/milestone}"El texto de la información emergente de una barra, escrito por una plantilla: por defecto las fechas, la duración y, salvo para un hito o una tarea resumen, el avance; {percent} escribe el avance en porcentaje, como lo escribe el idioma de visualización (50% en inglés)
ib_toolbarbooleantrueLa barra de herramientas sobre el diagrama: el botón Hoy y las cuatro escalas
ib_read_onlybooleanfalseEl usuario no cambia nada: ni arrastrar, ni redimensionar, ni avance, ni Ctrl + flechas, ni Supr, ni vínculo. Sigue seleccionando, plegando, abriendo y cambiando de escala; su código sigue cambiando las tareas
ib_veto_changesbooleanfalseOpt-in: preguntar ue_task_changing antes de cada movimiento, nuevo fin o avance del usuario. Desactivado por defecto, como todo evento cancelable de la biblioteca
ib_write_backbooleanfalseUn diagrama alimentado por of_from_datastore: un gesto escribe las nuevas fechas o el nuevo avance en el DataStore antes de su evento. Una tarea añadida a mano nunca se escribe. Una columna datetime conserva su hora: el diagrama mueve días. Una tarea de un DataStore sin columna de fin (ROLE_END) no tiene asa de fin: su nuevo fin no podría escribirse
ib_link_by_mousebooleanfalseDos puntos a cada lado de la barra bajo el puntero: arrastrar uno sobre otra tarea pide un vínculo (ue_link_requested)
ib_critical_pathbooleanfalseDibuja la ruta crítica en el color de peligro: las tareas y los vínculos sin holgura, contada en días laborables (is_work_days); un vínculo que toca una tarea resumen compromete las tareas que contiene; una tarea terminada (100 %) nunca se marca
is_project_endstring""El plazo del proyecto, yyyy-mm-dd: la holgura de la ruta crítica se cuenta hasta el final de ese día en lugar del último fin del plan. Más tarde, cada tarea tiene juego; antes, las que terminan demasiado tarde son críticas. Vacío: el último fin. Una fecha que no lo es se rechaza (of_get_last_error)
ib_show_latebooleanfalseDibuja las tareas retrasadas en ámbar rayado: una tarea — ni resumen ni hito — cuyo último día es anterior a is_today y cuyo avance está por debajo de 100. of_is_late() y el campo {late} responden se dibuje o no
ii_grid_widthinteger-1 (auto)La anchura de la cuadrícula en píxeles. Automática por defecto (-1): tan ancha como las columnas que muestra, y leída como esa anchura (544 con las cinco columnas). 0 la oculta, 2000 como máximo; otro valor se rechaza (of_get_last_error). El usuario arrastra la línea entre cuadrícula y diagrama, o la mueve con las flechas: leída en directo
ii_row_heightinteger30La altura de una fila en píxeles, de 22 a 60; otro valor se rechaza (of_get_last_error)
is_theme_stylestring""Estilo visual del componente (constantes THEME_STYLE_*); vacío = el de la aplicación, seguido en cada cambio
is_theme_modestring""Variante clara u oscura (constantes THEME_MODE_*); vacío = la de la aplicación, seguida en cada cambio
il_theme_accentlong-1Color de acento de este componente (-1 = acento de la aplicación, o el del tema)
is_tooltipstring""Tooltip simple mostrado al pasar el ratón por el componente
is_super_tooltip_titlestring""Título del tooltip enriquecido (prevalece sobre is_tooltip)
is_super_tooltip_textstring""Texto del tooltip enriquecido (se acepta el marcado enriquecido)
is_super_tooltip_imagestring""Imagen del tooltip enriquecido

Propiedades de una tarea — n_pbt_gantt_task #

Su handle, mediante of_task(dirección). Una lectura pregunta al diagrama qué es la tarea ahora; un valor escrito es mudo, como SetItem; ib_collapsed es una orden y lanza ue_task_toggled. Su of_count() cuenta las tareas que contiene y su of_keys_at(n) devuelve la dirección de la n-ésima.

PropiedadTipoPredeterminadoFunción
is_labelstring""El nombre de la tarea, en la cuadrícula, junto a su barra y en su información emergente: texto enriquecido con etiquetas en todas partes ([[1]] para un corchete). Vacío, la tarea muestra su clave
is_startstring—El primer día, aaaa-mm-dd. Escribirlo mueve la tarea: su duración se mantiene (escriba is_end después para cambiarla). Rechazado para una tarea resumen, que toma sus fechas de lo que contiene, y para una fecha no válida: of_get_last_error dice por qué
is_endstring—El último día, incluido, aaaa-mm-dd: una tarea del 6 al 10 dura cinco días. Rechazado antes de is_start, para un hito (no tiene fin propio) y para una tarea resumen
id_progressdouble0El avance, en porcentaje (de 0 a 100), dibujado en la barra. Una tarea resumen lee la media de lo que contiene, ponderada por las duraciones; escribirlo se rechaza, también para un hito
ib_milestonebooleanfalsetrue: un hito, un día dibujado como un rombo, sin duración ni avance. Es un instante al final de su día: vinculado tras una tarea que termina ese día, la regla se cumple; una tarea vinculada tras él empieza al día siguiente
ib_collapsedbooleanfalsetrue pliega una tarea resumen: las tareas que contiene salen de la cuadrícula. Sigue ue_task_toggled, como con un clic en su cheurón. Solo una tarea resumen se pliega: true en una tarea que no contiene nada se rechaza (of_get_last_error). Leída en directo
ib_read_onlybooleanfalseEl usuario no puede ni arrastrar esta tarea, ni redimensionarla, ni cambiar su avance, ni pedir su eliminación; su código sigue cambiándola
il_accentlong-1El color de la barra y de su avance, en RGB(r,g,b); prevalece sobre una columna ROLE_COLOR. -1 = el acento del componente. Una tarea de la ruta crítica dibujada conserva el color de peligro
il_back_colorlong-1El fondo de la tarea: su fila en la cuadrícula y, como veladura pálida, la línea de su barra en el diagrama, en RGB(r,g,b). -1 = el del componente
il_text_colorlong-1El color del texto de la tarea: en la cuadrícula y junto a su barra. -1 = el del componente
il_back_color_hoverlong-1El fondo de la fila de la tarea en la cuadrícula mientras el puntero está encima. -1 = el del componente
il_text_color_hoverlong-1El color del texto de la fila de la tarea en la cuadrícula mientras el puntero está encima. -1 = el del componente
of_duration ( ) → long——Devuelve su duración en días naturales, el último día incluido; 0 para un hito
of_is_summary ( ) → boolean——TRUE cuando la tarea contiene otras: sus fechas y su avance se calculan
of_is_critical ( ) → boolean——TRUE cuando la tarea está en la ruta crítica: sin holgura, un día de retraso y el proyecto termina un día después. Responde tanto si ib_critical_path la dibuja como si no. La holgura se cuenta en días laborables (is_work_days); una tarea resumen nunca es crítica, las tareas que contiene pueden serlo; una tarea terminada (100 %) nunca
of_position ( ) → long——Devuelve su lugar entre las tareas de su padre, contado desde 1; 0 cuando el diagrama no la contiene
of_level ( ) → long——Devuelve su profundidad: 1 para una tarea arriba, 2 para una tarea dentro de ella…
of_predecessors ( ) → string——Las direcciones de las tareas de las que depende, unidas por |; vacío si no hay ninguna
of_successors ( ) → string——Las direcciones de las tareas que dependen de ella, unidas por |; vacío si no hay ninguna
of_is_late ( ) → boolean——Retrasada: su último día es anterior a is_today y no está terminada (avance por debajo de 100). Una tarea resumen y un hito nunca lo están; responde se dibuje o no con ib_show_late
of_row ( ) → long——Devuelve el número de fila de hoy, en el DataStore de of_from_datastore, de la fila de la que procede la tarea — sea cual sea la clave que tuvo que tomar, y tras una ordenación o un filtro. 0 para una tarea añadida a mano o cuya fila ha desaparecido
is_tooltipstring""Tooltip simple mostrado al pasar el ratón por el item
is_super_tooltip_titlestring""Título del tooltip enriquecido del item (prevalece sobre is_tooltip)
is_super_tooltip_textstring""Texto del tooltip enriquecido del item (se acepta el marcado enriquecido)
is_super_tooltip_imagestring""Imagen del tooltip enriquecido del item

Constantes #

ConstanteValorSignificado
SCALE_DAY"day"Una columna por día
SCALE_WEEK"week"Una columna por semana — la escala por defecto
SCALE_MONTH"month"Una columna por mes
SCALE_QUARTER"quarter"Una columna por trimestre
COLUMN_NAME"name"El nombre de la tarea, en árbol
COLUMN_START"start"El primer día
COLUMN_END"end"El último día
COLUMN_DURATION"duration"La duración en días
COLUMN_PROGRESS"progress"El avance en porcentaje
DEP_FS"fs"Fin a inicio: la siguiente empieza una vez terminada la anterior (el vínculo habitual)
DEP_SS"ss"Inicio a inicio: empiezan juntas
DEP_FF"ff"Fin a fin: terminan juntas
DEP_SF"sf"Inicio a fin: la siguiente termina cuando la anterior empieza
CHANGE_MOVE"move"Un movimiento: las dos fechas
CHANGE_RESIZE"resize"Un nuevo fin
CHANGE_PROGRESS"progress"Un nuevo avance
ROLE_KEY"key"La clave de la tarea (un identificador); sin ella, el RowID
ROLE_PARENT"parent"La clave de la tarea que la contiene
ROLE_LABEL"label"Su nombre
ROLE_START"start"Su primer día
ROLE_END"end"Su último día (vacío: el primero)
ROLE_PROGRESS"progress"Su avance, de 0 a 100
ROLE_MILESTONE"milestone"Un hito cuando el valor dice sí
ROLE_COLOR"color"El color de su barra
ROLE_PREDECESSORS"predecessors"Las tareas que espera: "12, 14:ss, 15:fs+2" (un desfase en días laborables se escribe tras el tipo)

Métodos #

MétodoFunción
of_add_dependency (string as_from_keys, string as_to_keys)Añade un vínculo fin a inicio: as_to_keys empieza una vez terminada as_from_keys. Devuelve 0 una vez añadido, -5 o -2 como la forma de tres argumentos
of_add_dependency (string as_from_keys, string as_to_keys, string as_type)Añade un vínculo de tipo DEP_FS, DEP_SS, DEP_FF o DEP_SF, dibujado como flecha. Devuelve 0 una vez añadido, -5 para una tarea desconocida, un vínculo hacia sí misma o entre una tarea y lo que contiene, un vínculo ya existente (sea cual sea su tipo), uno que cerraría un bucle o un tipo desconocido, -2 cuando el componente no está creado
of_add_dependency (string as_from_keys, string as_to_keys, string as_type, long al_lag)El mismo vínculo con un desfase en días laborables (is_work_days, menos los festivos): 2 deja dos días laborables entre el fin de una y el inicio de la otra, un número negativo es un adelanto. La regla de la flecha y la ruta crítica lo cuentan. Devuelve 0 una vez añadido, -5 como la forma de tres argumentos o para un desfase de más de 999 días, -2 cuando el componente no está creado
of_add_holiday (string as_date)Añade un día festivo sin nombre. Devuelve 0 una vez añadido, -5 o -2 como la forma de dos argumentos
of_add_holiday (string as_date, string as_label)Añade un día festivo, aaaa-mm-dd: un día no laborable diga lo que diga is_work_days, sombreado como un fin de semana, nombrado por as_label en la información emergente de su día en la escala día; la holgura de la ruta crítica y el desfase de un vínculo no lo cuentan. Uno a uno; of_clear lo conserva, of_reset lo borra. Devuelve 0 una vez añadido, -5 para una fecha no válida o un día ya festivo, -2 cuando el componente no está creado
of_add_holiday (date ad_date, string as_label)Lo mismo desde una date de PowerBuilder. Devuelve 0 una vez añadido, -5 también para una fecha nula
of_add_marker (string as_key, string as_date, string as_label)Añade un marcador vertical en el color del texto atenuado. Devuelve 0 una vez añadido, -5 o -2 como la forma de cuatro argumentos
of_add_marker (string as_key, string as_date, string as_label, long al_color)Añade un marcador vertical: una línea discontinua al final de su día (un plazo vale hasta el final de su día, como un hito), su etiqueta — texto enriquecido con etiquetas — arriba del diagrama: un plazo contractual, el fin de un sprint, una congelación. al_color es un color RGB(), -1 para el color del texto atenuado. Devuelve 0 una vez añadido, -5 para una clave que no puede serlo (vacía, con / o |), una clave ya tomada o una fecha no válida, -2 cuando el componente no está creado
of_add_milestone (string as_keys, string as_label, string as_date)Añade un hito en su dirección: un día, un rombo, sin duración. Devuelve 0 una vez añadido, -5 como of_add_task, -2 cuando el componente no está creado
of_add_milestone (string as_keys, string as_label, date ad_date)Lo mismo desde una date de PowerBuilder. Devuelve 0 una vez añadido, -5 también para una fecha nula
of_add_task (string as_keys, string as_label, string as_start, string as_end)Añade una tarea en su dirección: "phase1" arriba, "phase1/design" dentro de la tarea "phase1", añadida antes (se convierte en tarea resumen). Fechas aaaa-mm-dd, el fin incluido ("": un día). Devuelve 0 una vez añadida, -5 para una dirección con un nivel vacío o una clave con |, una dirección ya ocupada, un padre desconocido, una fecha no válida o un fin anterior al inicio, -2 cuando el componente no está creado
of_add_task (string as_keys, string as_label, date ad_start, date ad_end)Lo mismo desde dos date de PowerBuilder, siendo el fin el último día, incluido. Devuelve 0 una vez añadida, -5 también para un inicio nulo (un fin nulo: un día)
of_clear ( )Vacía el diagrama: tareas, vínculos, sus handles y las filas del DataStore (sigue vinculado, para un nuevo of_from_datastore; of_reload_row rechaza hasta entonces); las opciones se quedan. Devuelve 0 una vez aplicado, -2 cuando el componente no está creado
of_clear_dependencies ( )Quita todos los vínculos; las tareas se quedan. Devuelve 0 una vez aplicado, -2 cuando el componente no está creado
of_clear_holidays ( )Quita todos los días festivos: solo is_work_days dice qué días son laborables. Devuelve 0 una vez aplicado, -2 cuando el componente no está creado
of_clear_markers ( )Quita todos los marcadores; of_clear los conserva, como los festivos. Devuelve 0 una vez aplicado, -2 cuando el componente no está creado
of_clear_selection ( )No deja ninguna tarea seleccionada: sigue ue_selection_changed con una dirección vacía; nada seleccionado, no se lanza nada. Devuelve 0 una vez aplicado, -2 cuando el componente no está creado
of_collapse_all ( )Pliega todas las tareas resumen: sigue ue_task_toggled para cada una de las que estaban abiertas, y luego ue_layout_changed una vez. Devuelve 0 una vez aplicado, -2 cuando el componente no está creado
of_dependency_lag (string as_from_keys, string as_to_keys)Devuelve el desfase del vínculo de una tarea a otra, en días laborables, leído en directo: negativo para un adelanto, 0 sin desfase o sin vínculo
of_dependency_type (string as_from_keys, string as_to_keys)El tipo del vínculo de una tarea a otra (DEP_FS…), vacío si no hay ninguno. Leído en directo
of_expand_all ( )Abre todas las tareas resumen: sigue ue_task_toggled para cada una de las que estaban plegadas, y luego ue_layout_changed una vez. Devuelve 0 una vez aplicado, -2 cuando el componente no está creado
of_from_datastore (datastore ads)Hace una tarea de cada fila del DataStore (ver más arriba). Las tareas de una carga anterior se van, las añadidas a mano se quedan, y sus handles también. Devuelve 0 una vez cargado, -5 cuando el DataStore no es válido o no tiene columnas, -2 cuando el componente no está creado
of_from_datastore (datawindow adw)Lo mismo desde las filas de un DataWindow — el que el usuario ve al lado: ib_write_back escribe en este DataWindow. Un DataWindow que no puede compartir sus datos se rechaza. Devuelve 0 una vez cargado, -5 cuando el DataWindow no es válido, no tiene columnas o no se comparte, -2 cuando el componente no está creado
of_from_datastore (datawindowchild adwc)Lo mismo desde las filas de un DataWindowChild (una lista desplegable DataWindow, un informe anidado), reescrito por ib_write_back. Devuelve 0 una vez cargado, -5 cuando no es válido, no tiene columnas o no se comparte, -2 cuando el componente no está creado
of_get_field (string as_keys, string as_field)Lee un campo de una tarea, en directo: uno de los suyos, una columna de su DataStore o un campo integrado (duration, critical…) — que devuelve el texto mostrado y oculta una columna del mismo nombre. Una cadena vacía cuando no lo tiene
of_get_last_error ( )Por qué se rechazó la última escritura de una propiedad (una fecha no válida, las fechas de una tarea resumen, una escala o una columna desconocida); si no, el último error de la biblioteca
of_get_layout ( )Lo que el usuario ha organizado, en JSON: {"scale":"week","gridWidth":-1,"columns":[{"key":"name","width":200},...],"collapsed":["phase2"]} — la escala, la anchura de la cuadrícula y de cada columna, los resúmenes plegados. Para guardar y devolver luego a of_set_layout. Leído en directo
of_holidays ( )Los días festivos, leídos en directo: aaaa-mm-dd unidos por |, en orden de fecha; vacío si no hay ninguno
of_map (string as_role, string as_column)Da un rol a una columna del DataStore (ROLE_KEY, ROLE_PARENT, ROLE_LABEL, ROLE_START, ROLE_END, ROLE_PROGRESS, ROLE_MILESTONE, ROLE_COLOR, ROLE_PREDECESSORS), antes o después de of_from_datastore: después, las filas se vuelven a leer. Una columna vacía devuelve el rol a la columna que lleva su nombre. Lo que se fijó en las tareas se queda (plegado, solo lectura, campos, colores, vínculos añadidos por el código). Un nuevo ROLE_KEY o ROLE_PARENT da nuevas direcciones a las tareas de las filas: sus handles se liberan, los de las tareas añadidas a mano se quedan. Devuelve 0 una vez fijado, -5 para un rol desconocido o una columna que el DataStore no tiene, -2 cuando el componente no está creado
of_markers ( )Las claves de los marcadores, leídas en directo, en su orden, unidas por |; vacío si no hay ninguno
of_reload_row (long al_row)Vuelve a enviar al diagrama una fila del DataStore de of_from_datastore, leída ahora, después de que su código la haya cambiado (SetItem, una ventana de edición); al_row es su número de fila hoy. La tarea sigue su fila en su sitio: lo que se fijó en ella (plegado, solo lectura, campos, colores, vínculos añadidos por el código) se queda, un arrastre en curso continúa, no se lanza nada. Una fila cuya clave o cuyo padre ha cambiado mueve su tarea, con lo que se fijó en ella; una fila insertada desde entonces también llega. Devuelve 0 una vez enviada, -5 cuando no hay ningún DataStore vinculado, el diagrama no tiene filas desde of_clear o la fila no existe (of_get_last_error dice cuál), -2 cuando el componente no está creado
of_remove_dependency (string as_from_keys, string as_to_keys)Quita el vínculo de una tarea a otra. Devuelve 0 una vez quitado, -5 para un vínculo que el diagrama no tiene, -2 cuando el componente no está creado
of_remove_holiday (string as_date)El día vuelve a ser laborable. Devuelve 0 una vez quitado, -5 para un día que no es festivo de este diagrama, -2 cuando el componente no está creado
of_remove_marker (string as_key)Quita un marcador. Devuelve 0 una vez quitado, -5 para una clave que este diagrama no tiene, -2 cuando el componente no está creado
of_remove_task (string as_keys)Quita una tarea, todo lo que contiene y cada vínculo que las toca, y libera sus handles; quitar la tarea seleccionada vacía la selección. La tarea de una fila de DataStore queda fuera hasta el próximo of_from_datastore; of_reload_row de su fila la devuelve. Devuelve 0 una vez quitada, -5 para una dirección que el diagrama no tiene, -2 cuando el componente no está creado
of_reset ( )Vacía el diagrama, olvida el DataStore y devuelve cada propiedad a su valor por defecto, cada columna a su anchura. Devuelve 0 una vez aplicado, -2 cuando el componente no está creado
of_scroll_to_date (string as_date)Desplaza el eje del tiempo hasta ese día (aaaa-mm-dd), situado en el primer tercio de la vista. Devuelve 0 una vez aplicado, -5 para una fecha no válida, -2 cuando el componente no está creado
of_scroll_to_task (string as_keys)Muestra una tarea: las tareas resumen que la contienen se abren (ue_task_toggled para cada una), luego el diagrama se desplaza hasta su fila y su barra. Devuelve 0 una vez aplicado, -5 para una tarea que el diagrama no tiene, -2 cuando el componente no está creado
of_select_task (string as_keys)Selecciona una tarea como un clic, sin mover la vista (como SelectRow de un DataWindow), y sigue ue_selection_changed. Devuelve 0 una vez seleccionada (o ya seleccionada: no se lanza nada), -5 para una tarea desconocida o no dibujada (dentro de una tarea resumen plegada, más allá del límite de demostración), -2 cuando el componente no está creado
of_selected_key ( )La dirección de la tarea seleccionada, la haya seleccionado quien la haya seleccionado; vacía si ninguna. Leída en directo
of_set_field (string as_keys, string as_field, string as_value)Da a una tarea un campo propio, para las plantillas; prevalece sobre una columna del DataStore del mismo nombre. Un nombre de campo: letras, cifras y _, sin cifra inicial. Devuelve 0 una vez fijado, -5 para una tarea desconocida, un nombre no válido o el nombre de un campo integrado (label, start…), -2 cuando el componente no está creado
of_set_layout (string as_layout_json)Devuelve una disposición leída con of_get_layout o recibida por ue_layout_changed: la escala, las anchuras y qué resúmenes están plegados (los que no nombra se abren); una columna o una tarea desconocida para el diagrama se ignora. ue_layout_changed se lanza una vez si algo ha cambiado (ni ue_task_toggled ni ue_scale_changed: restablece un estado). Devuelve 0 una vez aplicada, -5 cuando el texto está vacío o no es un objeto JSON, -2 cuando el componente no está creado
of_task (string as_keys)Devuelve el handle de una tarea, por su dirección (creado en el primer acceso, liberado cuando se quita la tarea)

Eventos #

EventoSe activa cuando
ue_task_moved (string as_keys, string as_start, string as_end, string as_old_start, string as_old_end)El usuario ha movido una tarea: su barra arrastrada, o Ctrl + Izquierda / Derecha. as_start y as_end son sus nuevos días, as_old_start y as_old_end los que tenía, aaaa-mm-dd — lo que necesita un registro o una anulación. La tarea ya está en su sitio; con ib_write_back, el DataStore ya está escrito. Una fecha escrita por su código no lanza nada
ue_task_resized (string as_keys, string as_start, string as_end, string as_old_start, string as_old_end)El usuario ha cambiado el fin de una tarea: el borde final de su barra arrastrado, o Ctrl + Mayús + Izquierda / Derecha. Los días anteriores llegan con los nuevos
ue_progress_changed (string as_keys, double ad_progress, double ad_old_progress)El usuario ha cambiado el avance de una tarea: el pequeño triángulo bajo su barra arrastrado, o Ctrl + Arriba / Abajo (10 puntos). ad_progress es el nuevo, en porcentaje, ad_old_progress el que tenía
ue_task_changing (string as_keys, string as_kind, string as_start, string as_end, double ad_progress) → booleanCancelable, planteado antes de un movimiento, un nuevo fin o un avance del usuario, solo cuando ib_veto_changes = true. as_kind dice cuál: CHANGE_MOVE, CHANGE_RESIZE o CHANGE_PROGRESS; los valores son los que la tarea tomaría. Devolver FALSE la deja como estaba
ue_task_clicked (string as_keys)Se ha hecho clic en una tarea (y se ha seleccionado): su fila en la cuadrícula o su barra. No al final de un arrastre
ue_task_opened (string as_keys)Doble clic en una tarea, o Intro: abra su editor. Un doble clic en la fila de una tarea resumen la pliega o la abre en su lugar
ue_task_rclicked (string as_keys, long al_x, long al_y)Clic derecho en una tarea (seleccionada antes), o la tecla Menú (Mayús + F10) en la tarea seleccionada. al_x, al_y son píxeles de pantalla; para un menú de PowerBuilder, PopMenu(PointerX(), PointerY()) de su ventana
ue_selection_changed (string as_from_keys, string as_keys)La tarea seleccionada ha cambiado: clic, teclado, su código (of_select_task, of_clear_selection), o la tarea seleccionada ha salido de la cuadrícula (quitada, dentro de una tarea resumen plegada: as_keys está entonces vacío)
ue_task_toggled (string as_keys, boolean ab_collapsed)Una tarea resumen se ha plegado (ab_collapsed = TRUE) o abierto: su cheurón, un doble clic en su fila, el teclado, su ib_collapsed fijado por su código, of_expand_all, of_collapse_all, of_scroll_to_task
ue_delete_requested (string as_keys)Se ha pulsado Supr en la tarea seleccionada. El diagrama no quita nada: of_remove_task una vez que su aplicación esté de acuerdo. Nunca en una tarea o un diagrama de solo lectura
ue_link_requested (string as_from_keys, string as_to_keys, string as_type)El usuario ha trazado un vínculo de una tarea a otra (ib_link_by_mouse); as_type es una de las constantes DEP_. El diagrama no añade nada: of_add_dependency una vez que su aplicación esté de acuerdo
ue_dependency_clicked (string as_from_keys, string as_to_keys, string as_type)Se ha hecho clic en una flecha entre dos tareas
ue_scale_changed (string as_scale)La escala ha cambiado: la barra de herramientas, Ctrl + rueda, o is_scale fijado por su código
ue_layout_changed (string as_layout_json)La disposición ha cambiado: la escala, la anchura de la cuadrícula o de una columna, un resumen plegado o abierto (por el usuario o por su código), o of_set_layout. as_layout_json es la disposición entera, tal como la devuelve of_get_layout: guárdela
ue_write_back_failed (string as_keys, string as_col, string as_value, string as_reason)ib_write_back: el DataStore ha rechazado un nuevo valor de una tarea (un tipo que su columna no admite, una fila eliminada desde la carga). La tarea ha vuelto a como estaba, y no se lanza el evento del gesto
ue_ready ( )El componente ha terminado de cargarse; todo lo enviado antes se ha reproducido
ue_runtime_missing ( )El runtime WebView2 está ausente: el componente permanece vacío
ue_bg_color (long al_color)El componente ha calculado el color de fondo de su tema; el userobject ya lo ha adoptado (backcolor)

Teclado y ratón #


Ejemplos #

Reglas de planificación #

// 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

Vínculos trazados con el ratón #

// 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)

Recuperar la disposición en el próximo inicio #

// 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)

Abrir una tarea en su ventana #

// 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)

Buenas prácticas #

Heredado de la base común #

Estos miembros existen en todos los componentes visuales — no son propios de este. Se detallan una sola vez, en los capítulos transversales; esta tabla solo dice dónde leerlos.

MiembrosFunciónDetallado en
of_count · of_keys_at · of_hasRecorrer lo que el componente contiene3.2 Los items
of_resetPoner el componente a cero3.6 Poner un componente a cero: of_reset()
of_register_shortcut · of_clear_shortcutsAtajos de teclado del componente3.5 Los atajos de teclado
of_is_created · of_is_ready · of_get_last_errorSi ha nacido, si está listo, qué ha fallado3.7 Diagnóstico
of_save_as_png · of_save_as_jpgExportar el render como imagen3.8 Exportar la representación como imagen
of_set_redrawAgrupar los cambios en un solo repintado3.10 Buenas prácticas
of_preload_iconsIconos mostrados sin retardoVisualización instantánea: of_icon
of_set_translationTraducir una etiqueta del componente5.2 Adaptar una etiqueta: of_set_translation
of_focus_webviewDar el foco al componente6.4 Teclado y foco
of_print · of_print_to_pdfImprimir, o escribir un PDF6.9 Imprimir
of_set_property · of_get_property · of_component_nameControlar una propiedad por su nombre3.1 El motor de propiedades
is_accessible_name · is_accessible_descriptionEl nombre y la descripción que dice un lector de pantalla3.4 Propiedades y eventos opcionales

Dos ayudas no se heredan: of_icon y of_escape_markup viven en n_pbt_utils. Declare uno — n_pbt_utils lnv_utils, nada que crear — y llámelas sobre él.

← Referencia de componentes · Índice de la guía