PDA

Ver la Versión Completa : Cargar datos en un VirtualStringTree


Angel.Matilla
04-02-2019, 10:47:21
Imagino que terminaréis mandánome a freir espárragos con este elemento, pero me está ocurriendo una cosa que no acabo de comprender. A ver si me explico bien.

Tengo un formulario con un TPageControl que tiene dos pestañas. En cada una de ellas hay un TVirtualStringTree y tengo definidas estas dos estructuras:
typedef struct tagTTreeMun
{
AnsiString Municipio;
int Padron;
int Censo;
double Relacion;
int Codigo;
} TTreeMun, *PTreeMun;

typedef struct tagTTreePro
{
AnsiString Proceso;
int Padron;
int Censo;
double Relacion;
int Codigo;
}TTreePro, *PTreePro;Ya lo sé: son iguales; luego lo explico. La primera de ellas se carga a partir de cuatro querys anidados y lo hace sin ningún problema, pero la segunda... ¡No hay manera!

Para cargar esta segunda necesito dos querys:
SELECT DISTINCT Fecha FROM Elecciones ORDER BY Fecha DESCese campo Fecha contiene sólo el año y se ejecuta sin ningún problema.
SELECT A.Codigo, B.Nombre, SUM(C.Padron) Padron, SUM(C.Censo) Censo, A.Cerrado
FROM Elecciones A, Proceso B, HisElec C
WHERE A.CodPrv = (SELECT Literal FROM Instalacion WHERE Etiqueta = 'Provincia')
AND A.CodPrv = B.CodPrv AND B.Codigo = A.Proceso AND A.Cerrado = 1
AND A.CodPrv = C.CodPrv AND A.Codigo = C.Eleccion
AND A.Fecha = :Fecha
GROUP BY 1, 2, 5
UNION
SELECT A.Codigo, B.Nombre, SUM(C.Padron) Padron,
(SELECT SUM(Censo) FROM Mesas WHERE CodPrv = (SELECT Literal FROM Instalacion WHERE Etiqueta = 'Provincia')) Censo,
A.Cerrado
FROM Elecciones A, Proceso B, Dl01 C
WHERE A.CodPrv = (SELECT Literal FROM Instalacion WHERE Etiqueta = 'Provincia')
AND A.CodPrv = B.CodPrv AND A.Proceso = B.Codigo AND A.Cerrado = 0
AND A.Fecha = :Fecha
GROUP BY 1, 2, 5
ORDER BY 1 DESC, 3También se ejecuta sin problemas ni errores. El problema viene al tratar de pasar esos datos al correspondiente TVirtualStringTre.
PTreePro DatPro;
PVirtualNode Nodo1, Nodo2, Nodo3, Nodo4;

LisPro->NodeDataSize = sizeof(TTreePro);
LisPro->BeginUpdate();
LisPro->Clear();
for (; !qTemp1->Eof; qTemp1->Next())
{
Nodo1 = LisPro->AddChild(NULL);
DatPro = (PTreePro) LisPro->GetNodeData(Nodo1);
DatPro->Proceso = IntToStr(qTemp1->FieldByName("Fecha")->AsInteger);

qTemp2->Close();
qTemp2->ParamByName("Fecha")->AsInteger = qTemp1->FieldByName("Fecha")->AsInteger;
qTemp2->Open();
for (; !qTemp1->Eof; qTemp1->Next())
{
Nodo2 = LisPro->AddChild(Nodo1);
DatPro = (PTreePro) LisPro->GetNodeData(Nodo2);
DatPro->Proceso = qTemp1->FieldByName("Nombre")
[...]
}
}Al tratar de crear ese Nodo1 en este query, las líneas Nodo1 = ... y DatPro = (PTreePro)... se ejecutan sin mayor problema, salvo que Nodo1, tras ejecutarse el AddChild, tiene valor NULL y por lo tanto de ahí para adelante únicamente puede dar un error ya que al tratar de dar valor a Proceso automáticamente da un error de ejecución.

He probado poniendo la carga de cada uno de los árboles en una función diferente, por aislar código; he probado con la misma estructura (al fin y al cabo son idénticas) o como en el ejemplo con dos estructuras, a cambiar el orden de ejecución. Por más vueltas que he dado no soy capaz de que se carguen ambos árboles, en LisPro SIEMPRE me hace lo mismo.

Angel.Matilla
05-02-2019, 11:02:57
No sé que es lo que habré hecho. Para probar que estaba haciendo mal abrí un formulario nuevo y copié tanto el TVirtualStringTree como el código que estaba usando ¡y funcionó a la perfección! Total que volví a copiar lo que había en este nuevo formulario y ahora funciona sin errores. No entiendo nada.

Casimiro Notevi
05-02-2019, 11:40:52
No sé que es lo que habré hecho. Para probar que estaba haciendo mal abrí un formulario nuevo y copié tanto el TVirtualStringTree como el código que estaba usando ¡y funcionó a la perfección! Total que volví a copiar lo que había en este nuevo formulario y ahora funciona sin errores. No entiendo nada.
Es que con tan solo poner la pregunta en clubdelphi, ya se solucionan automáticamente :D