Datawindows con Treeviews dinámicos en PowerBuilder

A veces tenemos una DataWindow en forma de TreeView, y nos gustaría que el usuario pudiera elegir a su antojo el orden de la agrupación. Si tenemos una DataWindow de 4 grupos, se podría hacer una ristra de 24 DataWindows para que el usuario, elija lo que elija, se lo pintemos en la DataWindow agrupado. Pero esto es una locura.

Os voy a enseñar cómo se puede hacer que con una sola DataWindow se pueda cambiar dinámicamente la agrupación. Acompáñame tras el salto.

Lo primero que tenemos que hacer es crear la DataWindow con los grupos, y crear 4 computes (el ejemplo lo voy a hacer con 4, pero se pueden poner 2, 3, 5 o los que se necesiten. Hay que hacer tantos computes como grupos queramos). A cada compute lo he llamado campo_1, campo_2, etc.

La agrupación de cada grupo irá por estos computes. Es decir, el grupo 1 agrupado por campo_1 y así sucesivamente:
Ahora que tenemos la DataWindow, hay que dar al usuario la forma de que elija su agrupación personalizada. Yo lo he hecho insertando un simple ListBox en la ventana, en la que el usuario va añadiendo su ordenación. Puede elegir 1, 2, 3 o 4 elementos para agrupar:
Cuando ya tenemos la selección escogida, lo único que hay que hacer es montar y configurar el DataWindow para que agrupe dinámicamente. Hay que hacer una función que coja este orden, y ponga la columna que corresponde en cada compute de los insertados. Yo me he creado una función en la ventana en la que le paso 2 strings por referencia. Uno para decirle qué "grupo" ha seleccionado, y devolverá en esa variable la columna de la DataWindow por la que debe agrupar, y el orden por el que se basa esa columna.

// wfSetNivelYOrden(ref string srNivel, ref string srOrden)
String sCampoGerencia, sCampoDependencia, sCampoTipoAccion, sCampoAccion, sSort

sCampoGerencia    = "adn"
sCampoDependencia = "dependencia"
sCampoTipoAccion  = "descripcion_tipoaccion"
sCampoAccion      = "descripcion_accion"

CHOOSE CASE srNivel
 CASE "Gerencia"
  srNivel = sCampoGerencia
 CASE "Dependencia"
  srNivel = sCampoDependencia
 CASE "Tipo de acción"
  srNivel = sCampoTipoAccion
 CASE "Acción"
  srNivel = sCampoAccion
  srOrden = "acciones_id A"
 CASE ELSE
  srNivel = ""
  srOrden = ""
  Return
END CHOOSE

IF srOrden = "" THEN srOrden = srNivel + " A"
Return

Además, hay que expandir/contraer cada grupo para que todo quede correcto. Un ejemplo, es la función siguiente:

String sNivel1, sNivel2, sNivel3, sNivel4
String sOrden1, sOrden2, sOrden3, sOrden4
Integer iNiveles
String sSort
dw_datos.SetRedraw(FALSE)

// Datawindow de árbol
sNivel1 = lb_1.text(1)
sNivel2 = lb_1.text(2)
sNivel3 = lb_1.text(3)
sNivel4 = lb_1.text(4)
iNiveles = lb_1.TotalItems()

IF iNiveles = 0 THEN
 sNivel1 = "Gerencia"
 sNivel2 = "Dependencia"
 sNivel3 = "Tipo de Acción"
 sNivel4 = "Acción"
END IF

// Coge qué columna y cómo se ordenará cada nivel.
wfSetNivelYOrden(sNivel1,sOrden1)
wfSetNivelYOrden(sNivel2,sOrden2)
wfSetNivelYOrden(sNivel3,sOrden3)
wfSetNivelYOrden(sNivel4,sOrden4)

// Se reorganiza el TreeView con la configuración.
dw_datos.modify("campo_1.expression='" + sNivel1 + "'")
dw_datos.modify("campo_2.expression='" + sNivel2 + "'")
dw_datos.modify("campo_3.expression='" + sNivel3 + "'")
dw_datos.modify("campo_4.expression='" + sNivel4 + "'")
sSort = sOrden1 + ", " + sOrden2 + ", " + sOrden3 + ", " + sOrden4 + ", ps_acciones_mes_id A"
// Se ocultan los niveles que no se usarán. (1, 2 o 3)
CHOOSE CASE iNiveles
 CASE 1
  dw_datos.Modify("DataWindow.tree.level.2.Height=0")
  dw_datos.Modify("DataWindow.tree.level.3.Height=0")
  dw_datos.Modify("DataWindow.tree.level.4.Height=0")
  dw_datos.Modify("DataWindow.tree.level.2.Height.AutoSize='false'")
  dw_datos.Modify("DataWindow.tree.level.3.Height.AutoSize='false'")
  dw_datos.Modify("DataWindow.tree.level.4.Height.AutoSize='false'")
  dw_datos.Modify("DataWindow.Detail.Height=0")
 CASE 2
  dw_datos.Modify("DataWindow.tree.level.2.Height=68")
  dw_datos.Modify("DataWindow.tree.level.3.Height=0")
  dw_datos.Modify("DataWindow.tree.level.4.Height=0")
  dw_datos.Modify("DataWindow.tree.level.2.Height.AutoSize='true'")
  dw_datos.Modify("DataWindow.tree.level.3.Height.AutoSize='false'")
  dw_datos.Modify("DataWindow.tree.level.4.Height.AutoSize='false'")
  dw_datos.Modify("DataWindow.Detail.Height=0")
 CASE 3
  dw_datos.Modify("DataWindow.tree.level.2.Height=68")
  dw_datos.Modify("DataWindow.tree.level.3.Height=68")
  dw_datos.Modify("DataWindow.tree.level.4.Height=0")
  dw_datos.Modify("DataWindow.tree.level.2.Height.AutoSize='true'")
  dw_datos.Modify("DataWindow.tree.level.3.Height.AutoSize='true'")
  dw_datos.Modify("DataWindow.tree.level.4.Height.AutoSize='false'")
  dw_datos.Modify("DataWindow.Detail.Height=0")
 CASE 4, 0
  dw_datos.Modify("DataWindow.tree.level.2.Height=68")
  dw_datos.Modify("DataWindow.tree.level.3.Height=68")
  dw_datos.Modify("DataWindow.tree.level.4.Height=68")
  dw_datos.Modify("DataWindow.tree.level.2.Height.AutoSize='true'")
  dw_datos.Modify("DataWindow.tree.level.3.Height.AutoSize='true'")
  dw_datos.Modify("DataWindow.tree.level.4.Height.AutoSize='true'")
  dw_datos.Modify("DataWindow.Detail.Height=68")
END CHOOSE

sSort = Left(sSort,Len(sSort)-1)
dw_datos.SetSort(sSort)
dw_datos.Sort()
dw_datos.GroupCalc()
dw_datos.ExpandAll()
dw_datos.SetRedraw(TRUE)

// Todo bien.
Return

Nótese, que da igual cuándo hagamos el Retrieve() de la DataWindow. Esta agrupación funciona tanto si los datos están ya en la DataWindow como si los vamos a traer a continuación. A mi me gusta que los datos ya estén en la DataWindow, para que esta agrupación se vea más dinámica y directa (ya que la agrupación tarda sólo unas milésimas de segundo en realizarse a los ojos del usuario).


Espero que les sirva de ayuda. Para cualquier duda o sugerencia, los comentarios están abiertos ;)

4 comentarios:

  1. hola:
    Muy buena explicacion, ahora ya podemos ver power para web

    ResponderEliminar
  2. Buenas, esta muy buena la solucion a la agrupacion, pero tengo una situacion q creo no tiene solucion sucede que en una dw la agrupacion es a 4 niveles pero tambien debe hacerse a 3er nivel y este 3 debe contener las columnas asi como el 4to, lo q estoy pensando es q trabaje como 4to el 3ro y se repita en un registro para su agrupador y registro, otra salvedad seria usar una tree view, pero como mostraria las columnas en una tree view, gracias por su rpta.

    Saludos Cordiales

    ResponderEliminar
  3. Y COMO PUEDO HACER MI TREE VIEW DINÁMICO PERO DE LA FORMA QUE MIS RAMIFICACIONES CREZCAN "N" NUMERO DE VECES (SI EL USUARIO QUIERE CREAR OTRA RAMIFICAICON)

    ResponderEliminar
  4. Como ordenar ahora estas columnas?

    ResponderEliminar

Mi foto
Geek y Friki de amplio espectro pero de baja intensidad. Bloguero, forero y jugón online. Y Papá. Cada vez con menos tiempo para los hobbies.
Experto en PowerBuilder.
¿Te ha gustado? Haz un +1 en Google!

También te puede interesar...