Ver la Versión Completa : [Sintaxis] Guardar/cargar jerarquía de nodos en TreeView
dmosca
8 de agosto de 2017, 17:32
Hola Foro:
consulta: se puede leer el contenido de un TreeView en forma secuencial?
como posicionar el primer nodo y hacer una lectura secuencial, y como llevar el control de ultimo nodo?
Powercobol V9
Kuk
16 de agosto de 2017, 17:28
dmosca, normalmente este tipo de cosas de hace con recursión. Aunque, en teoría, se puede hacer a base de iteraciones también.
¿Conoces el formato (la profundidad máxima y la estructura) del contenido del TreeView o puede variar y es a descubrir en el proceso?
dmosca
17 de agosto de 2017, 00:39
Kuk, gracias por contestar
quiero generar un menú, donde el usuario final pueda configurar sus opciones.
el menú tendría una parte fija, y otra donde el usuario pueda agregar o eliminar sus opciones.
ya pude cargar el treeview desde un archivo, pero no se como leer los nodos en forma sequencial para poder guardar las modificaciones.
saludos
Kuk
17 de agosto de 2017, 09:04
dmosca, publica el código de cómo estás cargando los datos actualmente para que lo vea.
¿El usuario puede cargar nuevos nodos de 1 nivel o de varios niveles?
Creo recordar que hay algoritmos para ello. Como he dicho antes, lo más fácil es hacerlo con recursión, pero para ello hay que estar en modo OO (Orientado Objetos). Así que dependiendo de tu respuesta, miraremos cómo lo podemos hacer con iteraciones.
dmosca
18 de agosto de 2017, 01:25
Kuk buenas tardes
el usuario deberia poder generar nivel 1 y 2, en el nivel 1 deberia poder cargar el nombre de un programa o crear una carpeta. (este ultimo tema no lo tengo resuelto).
adjunto el txt (es un ejemplo)
codigo para cargar el treeview desde un txt:
WORKING-STORAGE SECTION.
01 RETURNVALUE PIC S9(5) COMP-5.
01 WK-IDX PIC S9(9) COMP-5.
01 POW-PCMNODE OBJECT REFERENCE POW-CNODE.
01 WK-TEXT PIC X(100).
01 DEM PIC 99 VALUE 0.
01 I PIC 999 VALUE 0.
01 T1 PIC 999 VALUE 0.
01 TCHILD PIC S9(9) COMP-5 GLOBAL EXTERNAL.
01 TROOT PIC S9(9) COMP-5 GLOBAL EXTERNAL.
01 ELNODO1 PIC S9(9) COMP-5.
01 ELNODO2 PIC S9(9) COMP-5.
01 ELNODO3 PIC S9(9) COMP-5.
01 ELNODO4 PIC S9(9) COMP-5.
01 ELNODO5 PIC S9(9) COMP-5.
PROCEDURE DIVISION.
INVOKE POW-SELF "CallForm" USING "Apertura".
INVOKE Menu_Ppal "clear".
TAREA.
OPEN INPUT PROGRAMAS.
PERFORM VARYING T1 FROM 1 BY 1 UNTIL DEM = 99
READ PROGRAMAS AT END MOVE 99 TO DEM END-READ
IF DEM = ZEROES
EVALUATE NIVEL
WHEN 0
INVOKE Menu_Ppal "Add" USING PROG 1 3 4 RETURNING ELNODO1
WHEN 1
MOVE 'Root'(ELNODO1) OF Menu_Ppal TO POW-PCMNODE
INVOKE POW-PCMNODE 'Add' USING PROG 1 3 4 RETURNING ELNODO2
WHEN 2
MOVE 'Child'(ELNODO2) OF 'Root'(ELNODO1) OF Menu_Ppal TO POW-PCMNODE
INVOKE POW-PCMNODE 'Add' USING PROG 1 3 4 RETURNING ELNODO3
WHEN 3
MOVE 'Child'(ELNODO3) OF
'Child'(ELNODO2) OF 'Root'(ELNODO1) OF Menu_Ppal TO POW-PCMNODE
INVOKE POW-PCMNODE 'Add' USING PROG 1 3 4 RETURNING ELNODO4
WHEN 4
MOVE 'Child'(ELNODO4) OF
'Child'(ELNODO3) OF
'Child'(ELNODO2) OF 'Root'(ELNODO1) OF Menu_Ppal TO POW-PCMNODE
INVOKE POW-PCMNODE 'Add' USING PROG 1 3 4 RETURNING ELNODO5
END-EVALUATE
END-IF
END-PERFORM.
CLOSE PROGRAMAS.
EXIT PROGRAM.
Kuk
18 de agosto de 2017, 09:10
o crear una carpeta. (este ultimo tema no lo tengo resuelto).
Para ello será necesario guardar también el tipo del nodo, si es carpeta o no. Pero en realidad es ficticio, técnicamente no hay diferencia. Con lo cual, se puede decir que si el nodo tiene hijos, es una carpeta, o por ejemplo si usas iconos en el TreeView, según el índice del icono, sabrás si es carpeta o no.
En cuanto al algoritmo, voy a meditarlo y hacer pruebas. Cuando tenga resultados convincentes, te los pasaré por aquí ;)
Kuk
23 de agosto de 2017, 22:19
dmosca, he aquí la solución. El truco consiste en darle un ID ficticio a cada Nodo, y guardar ese ID ficticio del padre. Luego se lee por capas/niveles comprobando si hay hijos o no, y así hasta que ningún nodo del nivel tenga hijos.
Aquí va el código de cómo guardar la jerarquía:
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT OPTIONAL TREE-FILE
ASSIGN TO "TREE.DB"
ORGANIZATION INDEXED
ACCESS MODE DYNAMIC
RECORD KEY IS TRE-ID
FILE STATUS IS SW-FS.
DATA DIVISION.
FILE SECTION.
FD TREE-FILE.
01 TRE-REC.
05 TRE-ID PIC S9(4) COMP-5.
05 TRE-ID-PADRE PIC S9(4) COMP-5.
05 TRE-NIVEL PIC S9(4) COMP-5.
05 TRE-NODE OBJECT REFERENCE POW-CNODE.
05 TRE-NODE-N REDEFINES TRE-NODE PIC S9(9) COMP-5.
05 TRE-TEXT PIC X(50).
05 TRE-ImageIndex PIC S9(9) COMP-5.
05 TRE-SelectedImageIndex PIC S9(9) COMP-5.
05 TRE-ExpandedImageIndex PIC S9(9) COMP-5.
WORKING-STORAGE SECTION.
01 SW-FS PIC X(2).
88 SW-FS-EOF VALUE "10".
01 SV-NIVEL PIC S9(4) COMP-5.
01 SV-N PIC S9(4) COMP-5.
01 SV-COUNT PIC S9(4) COMP-5.
01 IDX-MAX PIC S9(4) COMP-5.
01 IDX-1 PIC S9(4) COMP-5.
01 IDX-2 PIC S9(4) COMP-5.
01 IDX-3 PIC S9(4) COMP-5.
01 IDX-T PIC S9(4) COMP-5.
01 TBL-TREE.
05 TB-TREE OCCURS 0 TO 5000 TIMES DEPENDING ON IDX-T.
10 TB-ID PIC S9(4) COMP-5.
10 TB-ID-PADRE PIC S9(4) COMP-5.
10 TB-NIVEL PIC S9(4) COMP-5.
10 TB-NODE OBJECT REFERENCE POW-CNODE.
10 TB-NODE-N REDEFINES TB-NODE PIC S9(9) COMP-5.
10 TB-TEXT PIC X(50).
10 TB-ImageIndex PIC S9(9) COMP-5.
10 TB-SelectedImageIndex PIC S9(9) COMP-5.
10 TB-ExpandedImageIndex PIC S9(9) COMP-5.
01 SW-CHILDS PIC X.
88 SW-CHILDS-SI VALUE "S".
88 SW-CHILDS-NO VALUE "N".
PROCEDURE DIVISION.
CALL "CBL_DELETE_FILE2" USING BY CONTENT "TREE.DB"
OPEN I-O TREE-FILE
MOVE ZEROS TO IDX-T
MOVE "Count" OF CmTreeView1 TO IDX-MAX
MOVE 1 TO IDX-1, SV-NIVEL
PERFORM UNTIL IDX-1 > IDX-MAX
ADD 1 TO IDX-T
MOVE IDX-T TO TB-ID(IDX-T)
MOVE ZEROS TO TB-ID-PADRE(IDX-T)
MOVE SV-NIVEL TO TB-NIVEL(IDX-T)
MOVE "Root"(IDX-1) OF CmTreeView1 TO TB-NODE(IDX-T)
MOVE "Text" OF TB-NODE(IDX-T) TO TB-TEXT(IDX-T)
MOVE "ImageIndex" OF TB-NODE(IDX-T) TO TB-ImageIndex(IDX-T)
MOVE "SelectedImageIndex" OF TB-NODE(IDX-T) TO TB-SelectedImageIndex(IDX-T)
MOVE "ExpandedImageIndex" OF TB-NODE(IDX-T) TO TB-ExpandedImageIndex(IDX-T)
PERFORM WRITE-TRE-REC
ADD 1 TO IDX-1
END-PERFORM
SET SW-CHILDS-SI TO TRUE
PERFORM UNTIL SW-CHILDS-NO
SET SW-CHILDS-NO TO TRUE
MOVE 1 TO IDX-2
MOVE IDX-T TO SV-N
PERFORM UNTIL IDX-2 > SV-N
IF TB-NIVEL(IDX-2) = SV-NIVEL
PERFORM CHILDS
END-IF
ADD 1 TO IDX-2
END-PERFORM
ADD 1 TO SV-NIVEL
END-PERFORM
CLOSE TREE-FILE
GOBACK
.
CHILDS.
IF "Count" OF TB-NODE(IDX-2) > 0
SET SW-CHILDS-SI TO TRUE
MOVE 1 TO IDX-3
MOVE "Count" OF TB-NODE(IDX-2) TO SV-COUNT
PERFORM UNTIL IDX-3 > SV-COUNT
ADD 1 TO IDX-T
MOVE IDX-T TO TB-ID(IDX-T)
MOVE IDX-2 TO TB-ID-PADRE(IDX-T)
ADD 1 TO SV-NIVEL GIVING TB-NIVEL(IDX-T)
MOVE "Child"(IDX-3) OF TB-NODE(IDX-2) TO TB-NODE-N(IDX-T)
MOVE "Text" OF TB-NODE(IDX-T) TO TB-TEXT(IDX-T)
MOVE "ImageIndex" OF TB-NODE(IDX-T) TO TB-ImageIndex(IDX-T)
MOVE "SelectedImageIndex" OF TB-NODE(IDX-T) TO TB-SelectedImageIndex(IDX-T)
MOVE "ExpandedImageIndex" OF TB-NODE(IDX-T) TO TB-ExpandedImageIndex(IDX-T)
PERFORM WRITE-TRE-REC
ADD 1 TO IDX-3
END-PERFORM
END-IF
.
WRITE-TRE-REC.
WRITE TRE-REC FROM TB-TREE(IDX-T)
IF SW-FS NOT = "00"
INVOKE POW-SELF "DisplayMessage" USING "Error" SW-FS 48
CLOSE TREE-FILE
GOBACK
END-IF
.
Y aquí el código de cómo cargar los datos en el TreeView:
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT OPTIONAL TREE-FILE
ASSIGN TO "TREE.DB"
ORGANIZATION INDEXED
ACCESS MODE SEQUENTIAL
RECORD KEY IS TRE-ID
FILE STATUS IS SW-FS.
DATA DIVISION.
FILE SECTION.
FD TREE-FILE.
01 TRE-REC.
05 TRE-ID PIC S9(4) COMP-5.
05 TRE-ID-PADRE PIC S9(4) COMP-5.
05 TRE-NIVEL PIC S9(4) COMP-5.
05 TRE-NODE OBJECT REFERENCE POW-CNODE.
05 TRE-NODE-N REDEFINES TRE-NODE PIC S9(9) COMP-5.
05 TRE-TEXT PIC X(50).
05 TRE-ImageIndex PIC S9(9) COMP-5.
05 TRE-SelectedImageIndex PIC S9(9) COMP-5.
05 TRE-ExpandedImageIndex PIC S9(9) COMP-5.
WORKING-STORAGE SECTION.
01 SW-FS PIC X(2).
01 IDX-A PIC S9(4) COMP-5.
01 IDX-NOD PIC S9(4) COMP-5.
01 IDX-T PIC S9(4) COMP-5.
01 TBL-TREE.
05 TB-TREE OCCURS 0 TO 5000 TIMES DEPENDING ON IDX-T.
10 TB-NODE OBJECT REFERENCE POW-CNODE.
10 TB-NODE-N REDEFINES TB-NODE PIC S9(9) COMP-5.
01 swEof PIC X.
88 swEof-SI VALUE "S".
88 swEof-NO VALUE "N".
01 CNT-READ PIC S9(4) COMP-5.
PROCEDURE DIVISION.
INVOKE CmTreeView1 "Clear"
SET swEof-NO TO TRUE
OPEN INPUT TREE-FILE
IF SW-FS NOT = "00"
INVOKE POW-SELF "DisplayMessage" USING "Error OPEN" SW-FS 48
END-IF
PERFORM READ-FILE
MOVE ZEROS TO IDX-T
PERFORM UNTIL swEof-SI
IF TRE-ID-PADRE = ZEROS
ADD 1 TO IDX-T
INVOKE CmTreeView1 "Add" USING TRE-TEXT RETURNING IDX-NOD
MOVE "Root"(IDX-NOD) OF CmTreeView1 TO TB-NODE(IDX-T)
PERFORM ICONOS
ELSE
ADD 1 TO IDX-T
INVOKE TB-NODE(TRE-ID-PADRE) "Add" USING TRE-TEXT RETURNING IDX-NOD
MOVE "Child"(IDX-NOD) OF TB-NODE(TRE-ID-PADRE) TO TB-NODE(IDX-T)
MOVE POW-TRUE TO "Expanded" OF TB-NODE(TRE-ID-PADRE)
PERFORM ICONOS
END-IF
PERFORM READ-FILE
END-PERFORM
CLOSE TREE-FILE
IF SW-FS NOT = "00"
INVOKE POW-SELF "DisplayMessage" USING "Error CLOSE" SW-FS 48
END-IF
GOBACK
.
READ-FILE.
READ TREE-FILE
IF SW-FS = "00"
CONTINUE
ELSE
IF SW-FS = "10"
SET swEof-SI TO TRUE
ELSE
INVOKE POW-SELF "DisplayMessage" USING "Error" SW-FS 48
GOBACK
END-IF
END-IF
.
ICONOS.
MOVE TRE-ImageIndex TO "ImageIndex" OF TB-Node(IDX-T)
MOVE TRE-SelectedImageIndex TO "SelectedImageIndex" OF TB-Node(IDX-T)
MOVE TRE-ExpandedImageIndex TO "ExpandedImageIndex" OF TB-Node(IDX-T)
.
Adjunto proyecto de ejemplo. El código no está optimizado, no tengo tiempo, se puede sacar fuera código repetido, pero bueno, la idea está ahí y funciona.
Kuk
24 de agosto de 2017, 09:34
Esta parte del código para la carga:
PERFORM UNTIL swEof-SI
IF TRE-ID-PADRE = ZEROS
ADD 1 TO IDX-T
INVOKE CmTreeView1 "Add" USING TRE-TEXT RETURNING IDX-NOD
MOVE "Root"(IDX-NOD) OF CmTreeView1 TO TB-NODE(IDX-T)
PERFORM ICONOS
ELSE
ADD 1 TO IDX-T
INVOKE TB-NODE(TRE-ID-PADRE) "Add" USING TRE-TEXT RETURNING IDX-NOD
MOVE "Child"(IDX-NOD) OF TB-NODE(TRE-ID-PADRE) TO TB-NODE(IDX-T)
MOVE POW-TRUE TO "Expanded" OF TB-NODE(TRE-ID-PADRE)
PERFORM ICONOS
END-IF
PERFORM READ-FILE
END-PERFORM
Queda mucho mejor así:
PERFORM UNTIL swEof-SI
ADD 1 TO IDX-T
IF TRE-ID-PADRE = ZEROS
INVOKE CmTreeView1 "Add" USING TRE-TEXT RETURNING IDX-NOD
MOVE "Root"(IDX-NOD) OF CmTreeView1 TO TB-NODE(IDX-T)
ELSE
INVOKE TB-NODE(TRE-ID-PADRE) "Add" USING TRE-TEXT RETURNING IDX-NOD
MOVE "Child"(IDX-NOD) OF TB-NODE(TRE-ID-PADRE) TO TB-NODE(IDX-T)
MOVE POW-TRUE TO "Expanded" OF TB-NODE(TRE-ID-PADRE)
END-IF
PERFORM ICONOS
PERFORM READ-FILE
END-PERFORM
Kuk
28 de agosto de 2017, 22:53
Pequeño pantallazo para ilustrar un poco de lo que se trata.
vBulletin v3.8.7, Derechos ©2000-2026, Jelsoft Enterprises Ltd.