# Plan de Cuentas con Treeview

**URL:** <https://foros.velneo.com/t/plan-de-cuentas-con-treeview/9259>\
**Category:** Velneo\
**Created:** [27 Diciembre, 2016 00:13 UTC](https://foros.velneo.com/t/plan-de-cuentas-con-treeview/9259 "2016-12-27T00:13:12Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![arojas.consultora](https://avatars.discourse-cdn.com/v4/letter/a/8c91f0/32.png) [@arojas.consultora](https://foros.velneo.com/u/arojas.consultora)\
**Post date:** [27 Diciembre, 2016 00:13 UTC](https://foros.velneo.com/t/plan-de-cuentas-con-treeview/9259/1 "2016-12-27T00:13:12Z")

</div>

Hola!

Pido la ayuda al foro para el siguiente caso.

Una Tabla CTAS\_CO, en la cual están todos los registros del Plan de Cuentas, esta tabla contiene un Maestro de Empresas, a fin de diferenciar por cada Empresa.

Necesito presentar el listado de las cuentas en un Treeview, sé que puedo utilizar el objeto visor de árbol, de hecho así lo tengo montado en una aplicación anterior en la V6x, solamente que atendiendo la potencia que representa poder utilizar javascript me gustaría utilizarlo.

Ya tengo montado la estructura de las columnas, las cabeceras del objeto, TopLevelItem, etc., pero tropiezo con la complejidad que representa crear cada uno de los nodos hijo que se desprende y sus siguientes items en forma recursiva, por ejemplo

1 ACTIVO  
11 ACTIVO CORRIENTE  
111 DISPONIBILIDADES  
11101 CAJA  
1110101 Recaudaciones a Depositar  
1110102 Caja Moneda extranjera

De acuerdo a la representación anterior puede incrementarse la cantidad de nodos de acuerdo a la complejidad del Plan de cuentas y sus respectivos auxiliares.

He buscado en varios artículos anteriores y no puedo encontrar la solución a este planteamiento.

Desde ya muy agradecido a todos por su ayuda de siempre.

---

<div class="post-metadata">

**Author:** ![ramiro](https://yyz1.discourse-cdn.com/flex035/user_avatar/foros.velneo.com/ramiro/32/5505_2.png) [@ramiro](https://foros.velneo.com/u/ramiro)\
**Post date:** [27 Diciembre, 2016 07:46 UTC](https://foros.velneo.com/t/plan-de-cuentas-con-treeview/9259/2 "2016-12-27T07:46:16Z")

</div>

Buenos dias:

Seguramente se puede hacer con ese objeto pero no será precisamente sencillo.

En cambio hacerlo con una tabla arbolada y un árbol visor de tablas es un juego de niños…

¿Porqué no pruebas esa opción?

Saludos. Ramiro

---

<div class="post-metadata">

**Author:** ![pacosatu](https://yyz1.discourse-cdn.com/flex035/user_avatar/foros.velneo.com/pacosatu/32/5131_2.png) [@pacosatu](https://foros.velneo.com/u/pacosatu)\
**Post date:** [27 Diciembre, 2016 17:34 UTC](https://foros.velneo.com/t/plan-de-cuentas-con-treeview/9259/3 "2016-12-27T17:34:14Z")

</div>

Hola AROJAS.

Como dice Ramiro con el árbol visor de tablas es coser y cantar.

Sin embargo, si eres un intrépido puedes probar con el TreeView.  
Prueba el siguiente ejemplo:

- La tabla arbolada tiene la siguiente estructura: CUENTAS(ID alfa40(8), NAME alfa256(100), PADRE alfa40(8))
- El campo PADRE contiene el ID de la rama Padre de cada registro. Si isEmpty(PADRE) entonces el registro es un TopLevel

```auto
var oArbol = theRoot.dataView().control("CTR_ARBOL")
// Columnas del árbol
var nColID = 0
var nColName = 1
var nColPadre = 2
oArbol.clear()
// El doble click se reserva para editar la Rama
oArbol.expandsOnDoubleClick = false
oArbol.wordWrap = true
oArbol.textElideMode = VTreeWidget.ElideRight
oArbol.indentation = 10
oArbol.animated = true
oArbol.rootIsDecorated = true
oArbol.uniformRowHeights = true
oArbol.alternatingRowColors = true
var cTabla = "MiProyecto_dat/CUENTAS"
// Fuentes para decorar
var oFuenteNegrita = new VFont("courier")
oFuenteNegrita.setPixelSize(12)
oFuenteNegrita.setBold(true)
var oFuenteNormal = new VFont("consolas")
var oFuenteCourier = new VFont("courier")
// Cabeceras
oArbol.headerHidden = false
oArbol.setHeaderLabel("Cuentas contables") // No aparece cuando usamos setHeaderLabels()
oArbol.setHeaderLabels(["Cuenta", "Nombre", "Padre"])

// Cargamos la lista de Cuentas ordenada por el ID para ir rellenando desde arriba hacia abajo
var oLisCuentas = new VRegisterList(theRoot)
oLisCuentas.setTable(cTabla)
oLisCuentas.load("ID",[])

var oItemPadre = null, oItemHija = null, oItemPadreScroll = null
// Recorremos la Lista y vamos insertando las Ramas en su Padre correspondiente
for (var i = 0 ; i < oLisCuentas.size(); ++i) {
	var oItem = oLisCuentas.readAt(i)
	var cID = oItem.fieldToString("ID") // ID único de cada rama
	var cNombre = oItem.fieldToString("NAME")	// Nombre de la Rama
	var cIdPadre = oItem.fieldToString("PADRE")	// ID del Padre de la rama
	// Añadimos un Item
	if (cIdPadre === "") {
		// El Item es TopLevel
		var oItemPadre = oArbol.addTopLevelItem()
		oItemPadre.setText(nColID, cID)
		oItemPadre.setText(nColName, cNombre)
		oItemPadre.setText(nColPadre, cIdPadre)
		oItemPadre.setFont(nColID, oFuenteNegrita)
		oItemPadre.setForegroundColor(nColName,139,0,0,255)
		oItemPadre.setBackgroundColor(nColName,240,230,140,255)
		// CID_PADRE_SCROLL guarda el ID de la rama TopLevel selecionada al inicio
		if (theRoot.varToString("CID_PADRE_SCROLL") == cID) {
			oItemPadreScroll = oItemPadre
		}
	}
	else {
		// La Opción es hija.
		// Comprobamos si la rama padre actual oItemPadre es la correcta, de lo contrario
		// tenemos que buscar la Rama padre de forma recursiva
		if (oItemPadre && (oItemPadre.text(nColID) != cIdPadre)) {
			// No podemos buscar un Item directamente en el árbol TreeWidget por su ID
			// Tenemos que buscar el Item Padre de forma recursiva recorriendo las ramas
			oItemPadre = buscarPadre_Arbol(cIdPadre, oArbol)
		}
		// Mostramos solo los Valores asignados si lSoloConValor = true
		if (oItemPadre) {
			oItemHija = oItemPadre.addChild()
			oItemHija.setText(nColID, cID)
			oItemHija.setText(nColName, cNombre)
			oItemHija.setText(nColPadre, cIdPadre)
			oItemHija.setFont(nColID, oFuenteCourier)
			oItemHija.setFont(nColName, oFuenteNormal)
			oItemHija.setForegroundColor(nColName,105,105,105,255)
			oItemHija.setBackgroundColor(nColName,255,248,220,255)
		}
	}
}

function buscarPadre_Arbol(cIdPadre, oArbol) {
	// Recorremos cada rama de los topLevelItem
	var oItemPadre = null
	for(var t = 0 ; t < oArbol.topLevelItemCount; ++t) {
		oItemPadre = buscarPadre_Rama(cIdPadre, oArbol.topLevelItem(t))
		if (oItemPadre) break
	}
	return oItemPadre
}

function buscarPadre_Rama(cIdPadre, oItemRama) {
	var oItemPadre = null
	// Recorremos las subramas para buscar el ID del padre
	for(var x = 0 ; x < oItemRama.childCount(); ++x) {
		// Comprobamos la columna del ID
		var oItem = oItemRama.child(x)
		if (oItem.text(nColID) == cIdPadre) {
			// Se ha encontrado el Padre, lo retorna y termina el bucle
			return oItem
		}
		else {
			// Buscamos de forma recursiva
			oItemPadre = buscarPadre_Rama(cIdPadre, oItem)
		}
	}
	return oItemPadre
}

// Ocultamos la columna con el ID del Padre
oArbol.hideColumn(nColPadre)
// Expandimos las ramas
oArbol.expandToDepth(3)
// Damos ancho fijo a la 1ª columna
oArbol.setColumnWidth(nColID, 150)
// oArbol.resizeColumnToContents(nColID)

// Activamos y mostramos el Item escogido
if (oItemPadreScroll){
	oArbol.scrollToItem(oItemPadreScroll, VTreeWidget.PositionAtCenter)
	oArbol.setCurrentItem(oItemPadreScroll, 0)
}

```

Como muchos objetos en Velneo, el Widget TreeView no es una excepción y está bastante incompleto, con algún que otro bug (por ejemplo el menú contextual) que por alguna oscura razón lleva años sin solución.

De todas formas lo que hay funciona bastante bien.  
Adjunto imagen con el resultado del ejemplo.

Saludos  
Paco Satué

 ![image](https://canada1.discourse-cdn.com/flex035/uploads/velneo/original/2X/e/e77957fdc530c733d45fc6a6975054570749e145.png)

---

<div class="post-metadata">

**Author:** ![arojas.consultora](https://avatars.discourse-cdn.com/v4/letter/a/8c91f0/32.png) [@arojas.consultora](https://foros.velneo.com/u/arojas.consultora)\
**Post date:** [27 Diciembre, 2016 19:15 UTC](https://foros.velneo.com/t/plan-de-cuentas-con-treeview/9259/4 "2016-12-27T19:15:25Z")

</div>

Paco, muchas gracias por este aporte.

Estoy iniciando con esto de javascript, asi que es necesario ir paso a paso para ganar conocimiento y sin duda el codigo que amablemente facilitas de gran ayuda.

Saludos

---

<div class="post-metadata">

**Author:** ![tony-diana](https://avatars.discourse-cdn.com/v4/letter/t/edb3f5/32.png) [@tony-diana](https://foros.velneo.com/u/tony-diana)\
**Post date:** [28 Diciembre, 2016 16:50 UTC](https://foros.velneo.com/t/plan-de-cuentas-con-treeview/9259/5 "2016-12-28T16:50:08Z")

</div>

Muy amable por el aporte, me parece muy interesante

---

<div class="post-metadata">

**Author:** ![ciberideas](https://avatars.discourse-cdn.com/v4/letter/c/43a26b/32.png) [@ciberideas](https://foros.velneo.com/u/ciberideas)\
**Post date:** [3 Enero, 2017 09:25 UTC](https://foros.velneo.com/t/plan-de-cuentas-con-treeview/9259/6 "2017-01-03T09:25:22Z")

</div>

Hola  
Hice algo parecido a lo que tu quieres  
problema: en servidor local va muy bien, pero en cloud va muy lento

salu2  
miguel  
ciberideas

 ![image](https://canada1.discourse-cdn.com/flex035/uploads/velneo/original/2X/4/4feb6823d5fcb66717283fd68e6bc5d7c5f42aa5.png)

---

<div class="post-metadata">

**Author:** ![pacosatu](https://yyz1.discourse-cdn.com/flex035/user_avatar/foros.velneo.com/pacosatu/32/5131_2.png) [@pacosatu](https://foros.velneo.com/u/pacosatu)\
**Post date:** [3 Enero, 2017 22:26 UTC](https://foros.velneo.com/t/plan-de-cuentas-con-treeview/9259/7 "2017-01-03T22:26:27Z")

</div>

Hola Miguel.

¿Por qué va lento en Cloud?  
¿No cacheas previamente la tabla de Cuentas antes de abrir el árbol?

Saludos  
Paco Satué

---

<div class="post-metadata">

**Author:** ![nandosanchez](https://avatars.discourse-cdn.com/v4/letter/n/ac8455/32.png) [@nandosanchez](https://foros.velneo.com/u/nandosanchez)\
**Post date:** [26 Enero, 2018 10:29 UTC](https://foros.velneo.com/t/plan-de-cuentas-con-treeview/9259/8 "2018-01-26T10:29:01Z")

</div>

Hola Paco, te agradezco mucho el aporte, sólo una cuestión, la tabla CUENTAS es de tipo Maestra arbolada o simplemente Maestra?

Gracias

---

<div class="post-metadata">

**Author:** ![pacosatu](https://yyz1.discourse-cdn.com/flex035/user_avatar/foros.velneo.com/pacosatu/32/5131_2.png) [@pacosatu](https://foros.velneo.com/u/pacosatu)\
**Post date:** [26 Enero, 2018 15:42 UTC](https://foros.velneo.com/t/plan-de-cuentas-con-treeview/9259/9 "2018-01-26T15:42:55Z")

</div>

Hola nandosanchez.

Es Maestra arbolada, el campo ID es Alfa40(8).  
Aunque para el ejemplo del TreeView con javascript no es necesario que sea arbolada, ya que uso el campo PADRE para establecer las subramas del árbol y podrían ser campos numéricos perfectamente.

La ventaja de las tablas arboladas es solo para Velneo porque disponemos del objeto Visor tablas arboladas que nos construye un árbol él solito.

Saludos  
Paco Satué

---

<div class="post-metadata">

**Author:** ![arturomiranda](https://yyz1.discourse-cdn.com/flex035/user_avatar/foros.velneo.com/arturomiranda/32/5116_2.png) [@arturomiranda](https://foros.velneo.com/u/arturomiranda)\
**Post date:** [16 Mayo, 2018 04:07 UTC](https://foros.velneo.com/t/plan-de-cuentas-con-treeview/9259/10 "2018-05-16T04:07:10Z")

</div>

Estimado Paco , ahora si me sorprendiste , ¿como haces para que de manera intencional cachear una tabla?

---

<div class="post-metadata">

**Author:** ![pacosatu](https://yyz1.discourse-cdn.com/flex035/user_avatar/foros.velneo.com/pacosatu/32/5131_2.png) [@pacosatu](https://foros.velneo.com/u/pacosatu)\
**Post date:** [16 Mayo, 2018 06:55 UTC](https://foros.velneo.com/t/plan-de-cuentas-con-treeview/9259/11 "2018-05-16T06:55:30Z")

</div>

Hola arturomiranda.

Muy sencillo.

Ejecutas en Segundo Plano y en el PRE\_INI del Autoexec un comando Cargar lista y Ordenar lista.  
Con esto consigues tener en caché la tabla, y el primer acceso es mucho más rápido.

Se deberían precargar en caché todas las tablas de la aplicación que vayan a ser de solo lectura.

Saludos  
Paco Satué
