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