Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Otros entornos y lenguajes > C++ Builder
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 29-07-2014
Yugo Yugo is offline
Miembro
NULL
 
Registrado: jul 2014
Posts: 25
Poder: 0
Yugo Va por buen camino
Buscar coincidencia datos con dos tablas Paradox BCB6

Hola a todos/as, me gustaría pediros consejo sobre una tarea. Os explico un poco...

Tengo 2 tablas paradox, tal que así:

tabla1
Nombre1-----Frec1---------Id1
dato1.1------dato1.2-------dato1.3
···
dato20.1-----dato20.2-----dato20.3

tabla2
Frec2.1------------Id2.1-------------Frec2.2--------------Id2.2 ················· Frec2.13------------Id2.13
dato1.1-----------dato1.2-----------dato1.3-------------dato1.4 ·············· dato1.25-----------dato1.26
···
dato1000.1-------dato1000.2-------dato1000.3--------dato1000.4 ········ dato1000.25-------dato1000.26

NOTA: La tabla2 consta de 26 campos (13 pares Frec2.x---Id2.x)

La idea es visualizar en un Form los registros de la tabla2 (de manera individual mediante TDBEdits), pero de forma que, conforme voy desplazándome registro a registro mediante un TDBNavigator, tengo que comparar los datos de cada par de campos Frec2.x---Id2.x con el par Frec1---Id1 de cada uno de los registros de la tabla1 para buscar posibles coincidencias. Y si son coincidentes ese par a par, entonces visualizar en dicho Form el dato correspondiente al campo Nombre1 de la tabla1 (mediante un TLabel, por ejemplo).

Como podeis ver, tengo la duda de cuál es la manera más eficiente de realizar esta tarea.

PD: Si en la tabla1 se diese la casualidad de tener dos registros con distinto Nombre pero iguales Frec e Id, para decidir que el nombre a visualizar en el Form en caso de coincidencia fuese el que estuviese el primero por orden alfabético, ¿sería la solución ordenar previamente por orden alfabético dicha tabla1, no?

Gracias por vuestro tiempo. Un saludo.
Responder Con Cita
  #2  
Antiguo 31-07-2014
Avatar de lmpadron
lmpadron lmpadron is offline
Miembro
 
Registrado: feb 2009
Ubicación: Habana, Cuba
Posts: 204
Poder: 16
lmpadron Va por buen camino
Saludos Yugo y bienvenido al ClubDelphi

Cita:
Empezado por Yugo Ver Mensaje
Hola a todos/as, me gustaría pediros consejo sobre una tarea. Os explico un poco...
Amigo mio mientras mas clara sea la pregunta mas fácil podrá ser darte una respuesta, eso que pones no explica mucho, al contrario enreda bastante !!! Pero bueno vamos a ver si podemos ayudar.

En esencia tienes una Tabla1 y una tabla2. Necesitas recorrer los campos de la tabla2 y mientras se hace (usando el DBNavigator) ir comprobando ese valor de la tabla2 con todos los de la Tabla1 buscando posibles coincidencias en los campos ID y FREC.

Bueno vamos a ver si podemos ser de ayuda, BCB usa en el BDE como SG el SQL lo que facilita bastante la vida, en caso de que estés usando el BDE para conectarte a la tabla, si estas usando ADO pues también tienes SQL.

Por lo tanto lo que debes hacer es obtener el momento en que se ejecuta la acción, eso bien lo podrías hacer programando directo en el DBNavigator, detectando el botón que se presiona

Código:
AnsiString BtnName;
  switch (Button)
  {
    case nbFirst:
    {
        //aki va tu código 
        break;
    }
    case nbPrior:
    {
        //aki va tu código
        break;
    }
    case nbNext:
    {
        //aki va tu código
        break;
    }
    case nbLast:
    {
        //aki va tu código
        break;
    }
  }
o mas directo en el componente que uses para mostrar la tabla ya sea ADOQuery o Query en su evento AfterScroll que en esencia siempre se activará cuando el usuario se mueva del registro actual, ya sea al anterior, próximo, primero o ultimo.

Una ves detectada la acción solo nos queda programar la comparación que puede ser un sencillo SELECT de SQL (aquí te dejo la lógica de como debería ser)

Código SQL [-]
SELECT * FROM  tabla1 WHERE tabla1.Frec1 = tabla2.Frec2.2 AND  tabla1.Id1 = tabla2.Id2.2;

Una ves hecho esto solo debes mostrar el resultado de la comparación en un componente de tu elección para que tu usuario pueda determinar que hacer

Espero que esto te sea de ayuda, si quieres mas detalles entonces debes dar mas detalles tu también, hay uno de los miembros de la comunidad que tiene en su pie de firma una frase estupenda (a mi en lo personal me encanta) que dice "La calidad de la respuesta es directamente proporcional a la calidad de la pregunta". Saludos
__________________
Nunca esta de más volver a ver la "Guia de Estilo" o "La Otra Guia de Estilo". Recuerda siempre usar los "Tags" para una mejor legibilidad de tu código.


Cuando miras fijamente al abismo, este te devuelve la mirada


oo______ooo_____ooo_ooooooo_____ooo____oooooo____ooooooo______oooo____ooo____oo_
oo______oooo___oooo_oo____oo__oo___oo__oo____oo__oo____oo___oo____oo__oooo___oo_
oo______oo_oo_oo_oo_oo____oo_oo_____oo_oo_____oo_oo____oo__oo______oo_oo_oo__oo_
oo______oo__ooo__oo_oooooo___ooooooooo_oo_____oo_ooooooo___oo______oo_oo__oo_oo_
oo______oo_______oo_oo_______oo_____oo_oo____oo__oo____oo___oo____oo__oo___oooo_
ooooooo_oo_______oo_oo_______oo_____oo_oooooo____oo_____oo____oooo____oo____ooo_
________________________________________________________________________________

Última edición por lmpadron fecha: 31-07-2014 a las 18:21:43.
Responder Con Cita
  #3  
Antiguo 07-08-2014
Yugo Yugo is offline
Miembro
NULL
 
Registrado: jul 2014
Posts: 25
Poder: 0
Yugo Va por buen camino
Hola lmpadron, quería agradecerte tu interés en responder a mi duda y por supuesto que trataré de seguir el consejo acerca de la claridad en la explicación de las dudas.

Básicamente has entendido bastante bien la cuestión, pero para que quede aún más claro voy a tratar de explicarlo de otra manera sólo para un registro de la tabla2, por ejemplo:

1.- Uso estos componentes: TTable1, TTable2, TDataSource1, TDBNavigator1, 13 TLabels, 26 TDBEdits (uno por cada campo de la tabla2 para ver los datos del registro actual) y un TQuery1 para realizar la consulta.
2.- Uso BDE para trabajar con bases de datos locales.
3.- En la tabla2, recorrer todos los campos del registro actual y tomando cada par de Frec2.x---Id2.x
para comparar sus datos con el par Frec1---Id1 de todos los registros de la tabla1. Por lo tanto, tendría
que usar un bucle for, tal que así:
Código:
for(x=1;x<=13;x++)
{
  Query1->Close();
  Query1->SQL->Clear();   
     String sConsulta = "  SELECT * FROM  tabla1 WHERE tabla1.Frec1 =  tabla2.Frec2.x AND  tabla1.Id1 = tabla2.Id2.x  ORDER BY Nombre1";
     Query1->SQL->Add(sConsulta);
     Query1->Open();
   
     //Si la consulta devuelve alguna coincidencia
       if(!Query1->IsEmpty())
     {
            //Hacer que la etiqueta contenga el nombre (ordenado alfabeticamente)
            Labelx->Caption = Query1->FieldByName("Nombre1")->AsString; 
      }
  //Si la consulta no devuelve ninguna coincidencia
      else
      {
    Labelx->Caption = "Ninguna coincidencia encontrada.";
       }
}
4.- En este caso, ¿debería insertar dicho código de actuación en el evento AfterScroll del componente TTable2? que es verdaderamente el componente que enlaza con la tabla que voy recorriendo con el TDBNavigator, ¿cierto?
5.- Por otro lado, si al abrir la aplicación también se debe realizar esta operación con el primer registro de la tabla2, que sería el registro actual, ¿qué debería hacer para ello?

Un saludo compañero!!

Última edición por ecfisa fecha: 07-08-2014 a las 07:38:14. Razón: Agregar etiquetas [code]
Responder Con Cita
  #4  
Antiguo 07-08-2014
Avatar de ecfisa
ecfisa ecfisa is offline
Moderador
 
Registrado: dic 2005
Ubicación: Tres Arroyos, Argentina
Posts: 10.508
Poder: 36
ecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to behold
Hola Yugo, bienvenido a ClubDelphi

Por favor, cuando pongas código C++ usa las etiquetas code, su uso es:
[code]
...
aqui tu código
...
[/code]
(ya las agregué a tu mensaje anterior)

Al ejecutar la sentencia:
Código SQL [-]
SELECT * FROM  tabla1 
WHERE tabla1.Frec1 =  tabla2.Frec2.x AND  tabla1.Id1 = tabla2.Id2.x  
ORDER BY Nombre1
Los datos que se encuentren disponibles en Query1 ya han cumplido la condición que deseas, por lo que sólo tendrías que recorrerlo. No es necesario hacer nada en su evento AfterScroll.

Saludos
__________________
Daniel Didriksen

Guía de estilo - Uso de las etiquetas - La otra guía de estilo ....
Responder Con Cita
  #5  
Antiguo 07-08-2014
Avatar de lmpadron
lmpadron lmpadron is offline
Miembro
 
Registrado: feb 2009
Ubicación: Habana, Cuba
Posts: 204
Poder: 16
lmpadron Va por buen camino
Saludos Yugo ... Ecfisa

Cita:
Empezado por Yugo Ver Mensaje
(...) Por lo tanto, tendría que usar un bucle for
también puedes usar WHILE

Código:
while (TuQuery->Eof)
        {
           //todo tu codigo
           TuQuery->Next();
        }
Otra cosa, no tienes que crear una variable de tipo String, asignarle un valor (en este caso la sentencia SQL) y después asignarle esa variable al Query1->SQL->Text.

Cita:
Empezado por Yugo Ver Mensaje
(...) Por lo tanto, tendría que usar un bucle for
Código:
Query1->SQL->Add(sConsulta);
Puedes hacerlo de esta manera

Código:
  Query1->SQL->Clear();
  Query1->SQL->Add("SELECT * FROM  tabla1 WHERE tabla1.Frec1 =  tabla2.Frec2.x AND  tabla1.Id1 = tabla2.Id2.x  ORDER BY Nombre1");
Cita:
Empezado por ecfisa Ver Mensaje
Los datos que se encuentren disponibles en Query1 ya han cumplido la condición que deseas
Como dice Ecfisa, en el SQL ya haces la comparación cuando usas el WHERE y los resultados obtenidos son solo aquellos que cumplen la condición, en el evento AfterScroll solo debes escribir si las comparaciones son secundarias y no puedes reducir los datos a mostrar.

Cita:
Empezado por Yugo Ver Mensaje
(...)//Hacer que la etiqueta contenga el nombre (ordenado alfabéticamente)
Código:
Labelx->Caption = Query1->FieldByName("Nombre1")->AsString;
Has probado usar un DBGrid enlazado al Query1 en vez de tantos Label??? De esta forma si la consulta devuelve alguna coincidencia ya el usuario la ve directo en el DBGrid, sino entonces este permanece vació o puedes si quieres lanzar algún mensaje o algo parecido.
Espero haber sido de ayuda

Ecfisa ... un gusto verte !!! Saludos
__________________
Nunca esta de más volver a ver la "Guia de Estilo" o "La Otra Guia de Estilo". Recuerda siempre usar los "Tags" para una mejor legibilidad de tu código.


Cuando miras fijamente al abismo, este te devuelve la mirada


oo______ooo_____ooo_ooooooo_____ooo____oooooo____ooooooo______oooo____ooo____oo_
oo______oooo___oooo_oo____oo__oo___oo__oo____oo__oo____oo___oo____oo__oooo___oo_
oo______oo_oo_oo_oo_oo____oo_oo_____oo_oo_____oo_oo____oo__oo______oo_oo_oo__oo_
oo______oo__ooo__oo_oooooo___ooooooooo_oo_____oo_ooooooo___oo______oo_oo__oo_oo_
oo______oo_______oo_oo_______oo_____oo_oo____oo__oo____oo___oo____oo__oo___oooo_
ooooooo_oo_______oo_oo_______oo_____oo_oooooo____oo_____oo____oooo____oo____ooo_
________________________________________________________________________________

Última edición por lmpadron fecha: 07-08-2014 a las 20:59:53.
Responder Con Cita
  #6  
Antiguo 14-08-2014
Yugo Yugo is offline
Miembro
NULL
 
Registrado: jul 2014
Posts: 25
Poder: 0
Yugo Va por buen camino
Hola, si me lo permitís voy a responderos a ambos en este mismo mensaje para no sobrecargarlo.

ecfisa, muchas gracias por la bienvenida y la información que me aportas. Procuraré usar las etiquetas que mencionas para escribir código en futuras ocasiones. También decirte que entiendo que al usar la instrucción:

Cita:
SELECT * FROM tabla1 WHERE tabla1.Frec1 = tabla2.Frec2.x AND tabla1.Id1 = tabla2.Id2.x ORDER BY Nombre1
en el Query1 está el/los resultados de dicha consulta bajo las condiciones del WHERE. Sin embargo, la idea no es recorrer dichos resultados, sino coger el dato del campo Nombre del primero de ellos. Lo que debo recorrer son los campos de la tabla2 (pares Frec2.x---Id2.x), de ahí la duda de dónde usar el código para ir recorriendo cada registro de dicha tabla mediante el TDBNavigator.

lmpadron, debo decirte que como estoy experimentando con esto, estoy usando un TDBGrid3 para visualizar los resultados de la consulta SQL (para comprobar visualmente si los resultados de la consulta se adecúan a lo que busco). Pero la idea de usar tantos TLabels es porque, al mismo tiempo que visualizo los registros originales de la tabla2 en otro TDBGrid2, también necesito hacer visible que las cosultas se realizan correctamente, puramente informal.

La cuestion es que escribo el siguiente código en un botón (a modo de prueba para comprobar si funciona o no) sólo para comprobar posibles coincidencias únicamente en el primer par de campos de la tabla2 (Frec2.1---BSIC):
Código:
  Query1->Close();
  Query1->SQL->Clear();

  Query1->SQL->Add("SELECT * ");
  Query1->SQL->Add("FROM tabla1 ");
  Query1->SQL->Add("WHERE tabla1.BSIC = tabla2.BSIC ");  
  //He renombrado el campo Id1 de la tabla1 a BSIC y el campo Id2.1 de la tabla2 tambien a BSIC por simple comodidad.
  //Los campos BSIC de ambas tablas son del mismo tipo (A) y mismo tamaño (6). 
  Query1->SQL->Add("AND tabla1.Frec1 = tabla2.Frec2.1 ");
  Query1->SQL->Add("ORDER BY Nombre1");

  Query1->Open();
y me salta la siguiente excepción:
Cita:
Exception class EDBEngineError with message 'Invalid field name.BSIC'
He probado de todo, y no doy con la tecla. A ver si vosotros veis algo que yo no veo. Así que de momento estoy tratando de solucionar este inconveniente, para posteriormente ya poder realizar el resto de consultas (mediante el bucle) para el resto de pares de campos de un registro de la tabla2 y luego poder aplicar ello para cuando cambie de un registro a otro en la tabla2.

Muchas gracias. Un saludo!!
Responder Con Cita
  #7  
Antiguo 14-08-2014
Avatar de lmpadron
lmpadron lmpadron is offline
Miembro
 
Registrado: feb 2009
Ubicación: Habana, Cuba
Posts: 204
Poder: 16
lmpadron Va por buen camino
El error debe estar en el SQL, ahora mismo, te digo !!!
__________________
Nunca esta de más volver a ver la "Guia de Estilo" o "La Otra Guia de Estilo". Recuerda siempre usar los "Tags" para una mejor legibilidad de tu código.


Cuando miras fijamente al abismo, este te devuelve la mirada


oo______ooo_____ooo_ooooooo_____ooo____oooooo____ooooooo______oooo____ooo____oo_
oo______oooo___oooo_oo____oo__oo___oo__oo____oo__oo____oo___oo____oo__oooo___oo_
oo______oo_oo_oo_oo_oo____oo_oo_____oo_oo_____oo_oo____oo__oo______oo_oo_oo__oo_
oo______oo__ooo__oo_oooooo___ooooooooo_oo_____oo_ooooooo___oo______oo_oo__oo_oo_
oo______oo_______oo_oo_______oo_____oo_oo____oo__oo____oo___oo____oo__oo___oooo_
ooooooo_oo_______oo_oo_______oo_____oo_oooooo____oo_____oo____oooo____oo____ooo_
________________________________________________________________________________

Última edición por lmpadron fecha: 14-08-2014 a las 22:45:38. Razón: lo envié mal por error y no puedo eliminarlo ... si alguin moderador ve este post POR FAVOR ELIMINELO. Graciasl
Responder Con Cita
  #8  
Antiguo 14-08-2014
Avatar de lmpadron
lmpadron lmpadron is offline
Miembro
 
Registrado: feb 2009
Ubicación: Habana, Cuba
Posts: 204
Poder: 16
lmpadron Va por buen camino
Cita:
Empezado por Yugo Ver Mensaje
(...)y me salta la siguiente excepción: 'Invalid field name.BSIC'
Hola Yugo ... por lo que veo, me imagino el error este en que no haces referencia a la tabla2 para abrirla, por lo que al llamarla en el WHERE te dice q el campo BSIC no existe.

Prueba lo siguiente

Código SQL [-]
Query1->Close();
  Query1->SQL->Clear();

  Query1->SQL->Add("SELECT * ");
  Query1->SQL->Add("FROM tabla1, tabla2 "); // AKI AGREGAMOS LA TABLA2 !!!
  Query1->SQL->Add("WHERE tabla1.BSIC = tabla2.BSIC ");  
  //He renombrado el campo Id1 de la tabla1 a BSIC y el campo Id2.1 de la tabla2 tambien a BSIC por simple comodidad.
  //Los campos BSIC de ambas tablas son del mismo tipo (A) y mismo tamaño (6). 
  Query1->SQL->Add("AND tabla1.Frec1 = tabla2.Frec2.1 ");
  Query1->SQL->Add("ORDER BY Nombre1");

  Query1->Open();

Tambien puedes probar con un JOIN

Código SQL [-]
Query1->Close();
  Query1->SQL->Clear();

  Query1->SQL->Add("SELECT tabla1.* ");
  Query1->SQL->Add("FROM tabla1 ");
  Query1->SQL->Add("INNER JOIN tabla2 ON tabla2.BSIC = tabla1.BSIC ");  
  //He renombrado el campo Id1 de la tabla1 a BSIC y el campo Id2.1 de la tabla2 tambien a BSIC por simple comodidad.
  //Los campos BSIC de ambas tablas son del mismo tipo (A) y mismo tamaño (6). 
  Query1->SQL->Add("AND tabla1.Frec1 = tabla2.Frec2.1 ");
  Query1->SQL->Add("ORDER BY Nombre1");

  Query1->Open();

... Claro esto también podrías hacerlo así

Código SQL [-]
  Query1->Close();
  Query1->SQL->Clear();
  Query1->SQL->Add("SELECT tabla1.* FROM tabla1, tabla2"
                                  " WHERE tabla1.BSIC = tabla2.BSIC"
                                  " AND tabla1.Frec1 = tabla2.Frec2.1 "
                                  " ORDER BY tabla1.Nombre1");
   Query1->Open();

... o
Código SQL [-]
  Query1->Close();
  Query1->SQL->Clear();
  Query1->SQL->Add("SELECT * FROM tabla1"
                                  " INNER JOIN tabla2 ON tabla2.BSIC = tabla1.BSIC"
                                  " AND tabla1.Frec1 = tabla2.Frec2.1 "
                                  " ORDER BY tabla1.Nombre1");
   Query1->Open();

... o incluso una mejor

Código SQL [-]
  Query1->Close();
  Query1->SQL->Clear();
  Query1->SQL->Add("SELECT t1.* FROM tabla1 t1, tabla2 t2"
                                  " WHERE t1.BSIC = t2.BSIC"
                                  " AND t1.Frec1 = t2.Frec2.1 "
                                  " ORDER BY t1.Nombre1");
   Query1->Open();

... o
Código SQL [-]
  Query1->Close();
  Query1->SQL->Clear();
  Query1->SQL->Add("SELECT * FROM tabla1 t1"
                                  " INNER JOIN tabla2 t2 ON t2.BSIC = t1.BSIC"
                                  " AND t1.Frec1 = t2.Frec2.1 "
                                  " ORDER BY t1.Nombre1");
   Query1->Open();

un poco mas limpio verdad !!!
__________________
Nunca esta de más volver a ver la "Guia de Estilo" o "La Otra Guia de Estilo". Recuerda siempre usar los "Tags" para una mejor legibilidad de tu código.


Cuando miras fijamente al abismo, este te devuelve la mirada


oo______ooo_____ooo_ooooooo_____ooo____oooooo____ooooooo______oooo____ooo____oo_
oo______oooo___oooo_oo____oo__oo___oo__oo____oo__oo____oo___oo____oo__oooo___oo_
oo______oo_oo_oo_oo_oo____oo_oo_____oo_oo_____oo_oo____oo__oo______oo_oo_oo__oo_
oo______oo__ooo__oo_oooooo___ooooooooo_oo_____oo_ooooooo___oo______oo_oo__oo_oo_
oo______oo_______oo_oo_______oo_____oo_oo____oo__oo____oo___oo____oo__oo___oooo_
ooooooo_oo_______oo_oo_______oo_____oo_oooooo____oo_____oo____oooo____oo____ooo_
________________________________________________________________________________

Última edición por lmpadron fecha: 14-08-2014 a las 22:49:09.
Responder Con Cita
  #9  
Antiguo 15-08-2014
Yugo Yugo is offline
Miembro
NULL
 
Registrado: jul 2014
Posts: 25
Poder: 0
Yugo Va por buen camino
Qué tal lmpadron!! justo acabo de probar todos los posibles códigos que me aportas y es fantástico comprobar que para ninguno de ellos salta la excepción, sin embargo, las consultas no devuelven nigún resultado visible en el DBGrid. Incluso probando con:
Código:
ShowMessage(Query1->FieldByName("Nombre1")->AsString);
para ver el dato del campo Nombre del primer registro del Query1, resulta ser una cadena vacía.

También he probado a realizar una consulta únicamente sobre la tabla1 con datos numéricos directamente tal que así:
Código:
  Query1->Close();
  Query1->SQL->Clear();
  Query1->SQL->Add("SELECT * FROM tabla1 WHERE BSIC = '47' and BCCH = '751' ORDER BY Nombre1");  
  Query1->Open();
y en este caso si se visualizan los resultados de la consulta en el DBGrid.

Estoy usando Database desktop 7.0, y no sé si será por esto por lo que no logro conseguir lo que busco.
Responder Con Cita
  #10  
Antiguo 16-08-2014
Avatar de ecfisa
ecfisa ecfisa is offline
Moderador
 
Registrado: dic 2005
Ubicación: Tres Arroyos, Argentina
Posts: 10.508
Poder: 36
ecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to behold
Cita:
Empezado por lmpadron Ver Mensaje
Ecfisa ... un gusto verte !!! Saludos
Hola Impadron, también me alegra mucho verte por aca


Hola Yugo, si no entendí todo mal, del modo que te pongo en este ejemplo hace lo que solicitas en el primer mensaje. Para probarlo agrega 3 Querys, 3 DataSources y 3 DBGrids
Código:
void __fastcall TForm1::FormCreate(TObject *Sender)
{
  // NOMBRE, RE1, ID1
  QueryTabla1->Close();
  QueryTabla1->SQL->Text = "SELECT * FROM TABLA1";
  QueryTabla1->Open();
  DataSource1->DataSet = QueryTabla1;

  // ID - RE1, ID1, RE2, ID2, RE3, ID3, ...
  QueryTabla2->Close();
  QueryTabla2->SQL->Text = "SELECT * FROM TABLA2";
  QueryTabla2->Open();
  DataSource2->DataSet = QueryTabla2;

  // Ocurrencia de nombres
  DataSource3->DataSet = QueryNames;
}
void __fastcall TForm1::DataSource2DataChange(TObject *Sender,TField *Field)
{
  QueryNames->Close();
  QueryNames->SQL->Clear();
  QueryNames->SQL->Add("SELECT T1.NOMBRE");
  QueryNames->SQL->Add("FROM TABLA1 T1 JOIN TABLA2 T2 ON T2.ID = :PID AND");
  QueryNames->SQL->Add("( (T1.ID1 = T2.ID1 AND T1.RE1 = T2.RE1) OR");
  QueryNames->SQL->Add("(T1.ID1 = T2.ID2 AND T1.RE1 = T2.RE2) OR");
  QueryNames->SQL->Add("(T1.ID1 = T2.ID3 AND T1.RE1 = T2.RE3) OR");
  QueryNames->SQL->Add("(T1.ID1 = T2.ID4 AND T1.RE1 = T2.RE4) OR");
  //
  //  Aquí irían las comprobaciones faltantes...
  //
  QueryNames->SQL->Add("(T1.ID1 = T2.ID26 AND T1.RE1 = T2.RE26) )");
  QueryNames->ParamByName("PID")->AsInteger = QueryTabla2->FieldByName("ID")->AsInteger;
  QueryNames->Open();
}
Pero si te fijas, en la Tabla2 agregué un campo ID (T2.ID) de tipo integer que no se repite (UNIQUE).
Esto es necesario para poder distinguir unívocamente en que registro estamos parados, ya que los nombres a mostrar, corresponden a las comparaciones entre los pares de columnas (REx / IDx) de Tabla1 y las columnas (RE1/ID1 - RE26/ID26) de ese registro de Tabla2 y no otro.

Probé la Tabla2 con un ID y cuatro pares de valores (8 columnas) y funciona correcto, se me hacía pesado escribir las 22 comprobaciones restantes...

Saludos
__________________
Daniel Didriksen

Guía de estilo - Uso de las etiquetas - La otra guía de estilo ....
Responder Con Cita
  #11  
Antiguo 18-08-2014
Yugo Yugo is offline
Miembro
NULL
 
Registrado: jul 2014
Posts: 25
Poder: 0
Yugo Va por buen camino
Qué tal ecfisa!! El código que me aportas funciona a la perfección si lo que buscamos es listar todos los nombres de la TABLA1 que cumplen la condición de que su par ID1/RE1 coincide con alguno de los pares ID1/RE1---ID26/RE26 de la TABLA2 del registro actual.

Sin embargo, la cuestion era otra. Disculpa si no me expliqué bien anteriormente.

1.- Supongamos que en el DBGrid estamos visualizando el registro nº1 de la TABLA2 (registro actual).

2.- Tomamos los dos datos del par ID1/RE1 (TABLA2).

3.- Comparar dicho par de datos ID1/RE1 (TABLA2) con el par de datos ID1/RE1 (TABLA1) de cada uno de los registros que tiene la TABLA1.

4.- Si la consulta devuelve algún resultado coincidente, visualizar en un TLabel el Nombre del primer resultado ordenado alfabéticamente que se obtiene. Y si no obtenemos ningún resultado pues, el TLabel contendrá un texto: "No coincidente", por ejemplo.

#NOTA: En la TABLA1 puede haber dos ó más registros con los mismos datos ID1/RE1 pero con Nombre diferentes. (De ahí el hecho de ordenar el resultado de la consulta por Nombre, puesto que sólo interesa el primero de ellos en caso de mútliples coincidencias).

5.- Tomar los siguientes dos datos del registro nº1 de la TABLA2, es decir, el par ID2/RE2 (TABLA2).

6.- Repetir los pasos 3 y 4 para el par ID2/RE2 (TABLA2).
...

Y así sucesivamente hasta el último par ID13/RE13 (TABLA2).

Como puedes ver ecfisa la tarea es diferente. De todas formas, tu mensaje anterior no sólo me aclara bastante las ideas, sino que me soluciona la duda de cómo hacer cuando se cambia de un registro de la TABLA2 a otro.

PD1: Como recordatorio, los campos de ambas tablas son...

TABLA1
Nombre......ID1......RE1

TABLA2
ID ...... ID1......RE1 ...... ID2......RE2 ...... ID3......RE3 ··· ID13......RE13


PD2: No os podeis imaginar lo agradecido que se siente uno cuando hay personas como vosotros que se toman la molestia y gastan su tiempo en ayudar a los que lo necesitamos, muchas gracias.
Responder Con Cita
  #12  
Antiguo 19-08-2014
Avatar de lmpadron
lmpadron lmpadron is offline
Miembro
 
Registrado: feb 2009
Ubicación: Habana, Cuba
Posts: 204
Poder: 16
lmpadron Va por buen camino
Cita:
Empezado por Yugo Ver Mensaje
PD2: No os podeis imaginar lo agradecido que se siente uno cuando hay personas como vosotros que se toman la molestia y gastan su tiempo en ayudar a los que lo necesitamos, muchas gracias.
No estamos gastando nuestro tiempo... estamos pagando el tiempo que otros gastaron en ayudarnos a nosotros !!! ... al menos eso es lo que hago yo hehehe ... incluyendo todo el que se gasto ecfisa conmigo hehehehhee !!!

A ver si esto te sirve .. pon un DBGRID con su DataSource y apuntalo a un Query (Query1) con este SQL

Código SQL [-]
SELECT * FROM table2

Una ves hecho esto en el DBGrid1 debes ver todos los valores de la "tabla 2", ahora si entiendo bien quieres comprobar los valores que están en los campos desde el ID1 RE1 hasta el ID13 RE13 con los contenidos en la "tabla 1" en los campos ID1 RE1.

Para esto pon otro DBGrid con su DataSource apuntando a un segundo Query (Query2). En el DataSource1 en su evento DataChange pones lo siguiente

Código:
void __fastcall TForm1::DataSource1DataChange(TObject *Sender,TField *Field)
{

Query2->Close();
Query2->SQL->Clear();
Query2->SQL->Add("SELECT "
"(SELECT nombre FROM tabla1 WHERE ID1 IN (SELECT ID1 FROM table2 WHERE ID = '"Query1->FieldByName("id")->Text"') AND RE1 IN (SELECT RE1 FROM table2 WHERE ID = '"Query1->FieldByName("id")->Text"') ORDER BY nombre ASC) AS PAR_ID1RE1, "
"(SELECT nombre FROM tabla1 WHERE ID1 IN (SELECT ID2 FROM table2 WHERE ID = '"Query1->FieldByName("id")->Text"') AND RE1 IN (SELECT RE2 FROM table2 WHERE ID = '"Query1->FieldByName("id")->Text"') ORDER BY nombre ASC) AS PAR_ID2RE2, "
"(SELECT nombre FROM tabla1 WHERE ID1 IN (SELECT ID3 FROM table2 WHERE ID = '"Query1->FieldByName("id")->Text"') AND RE1 IN (SELECT RE3 FROM table2 WHERE ID = '"Query1->FieldByName("id")->Text"') ORDER BY nombre ASC) AS PAR_ID3RE3, "
"(SELECT nombre FROM tabla1 WHERE ID1 IN (SELECT ID4 FROM table2 WHERE ID = '"Query1->FieldByName("id")->Text"') AND RE1 IN (SELECT RE4 FROM table2 WHERE ID = '"Query1->FieldByName("id")->Text"') ORDER BY nombre ASC) AS PAR_ID4RE4, "
"(SELECT nombre FROM tabla1 WHERE ID1 IN (SELECT ID5 FROM table2 WHERE ID = '"Query1->FieldByName("id")->Text"') AND RE1 IN (SELECT RE5 FROM table2 WHERE ID = '"Query1->FieldByName("id")->Text"') ORDER BY nombre ASC) AS PAR_ID5RE5, "
"(SELECT nombre FROM tabla1 WHERE ID1 IN (SELECT ID6 FROM table2 WHERE ID = '"Query1->FieldByName("id")->Text"') AND RE1 IN (SELECT RE6 FROM table2 WHERE ID = '"Query1->FieldByName("id")->Text"') ORDER BY nombre ASC) AS PAR_ID6RE6; "
);  
Query2->Open();

}
Es mas menos lo inverso a lo que te propuso ecfisa, según recorras la tabla 2 se efectuará la comprobación de los primeros 6 pares (no seguí mas allá por razones obvias !!!), si para esos primeros 6 pares funciona, pues entonces va a funcionar para todos !!! Cada columna lleva como nombre el numero del par que analiza y en caso de encontrar resultados solo te mostrara el campo nombre.

Saludos
__________________
Nunca esta de más volver a ver la "Guia de Estilo" o "La Otra Guia de Estilo". Recuerda siempre usar los "Tags" para una mejor legibilidad de tu código.


Cuando miras fijamente al abismo, este te devuelve la mirada


oo______ooo_____ooo_ooooooo_____ooo____oooooo____ooooooo______oooo____ooo____oo_
oo______oooo___oooo_oo____oo__oo___oo__oo____oo__oo____oo___oo____oo__oooo___oo_
oo______oo_oo_oo_oo_oo____oo_oo_____oo_oo_____oo_oo____oo__oo______oo_oo_oo__oo_
oo______oo__ooo__oo_oooooo___ooooooooo_oo_____oo_ooooooo___oo______oo_oo__oo_oo_
oo______oo_______oo_oo_______oo_____oo_oo____oo__oo____oo___oo____oo__oo___oooo_
ooooooo_oo_______oo_oo_______oo_____oo_oooooo____oo_____oo____oooo____oo____ooo_
________________________________________________________________________________
Responder Con Cita
  #13  
Antiguo 19-08-2014
Avatar de lmpadron
lmpadron lmpadron is offline
Miembro
 
Registrado: feb 2009
Ubicación: Habana, Cuba
Posts: 204
Poder: 16
lmpadron Va por buen camino
Si no te es molestia ponme el SQL para crear las tablas tuyas y algunos juegos de datos con los que verificar ... no es que no lo pueda hacer yo mismo... es q soy muy vago !!!
__________________
Nunca esta de más volver a ver la "Guia de Estilo" o "La Otra Guia de Estilo". Recuerda siempre usar los "Tags" para una mejor legibilidad de tu código.


Cuando miras fijamente al abismo, este te devuelve la mirada


oo______ooo_____ooo_ooooooo_____ooo____oooooo____ooooooo______oooo____ooo____oo_
oo______oooo___oooo_oo____oo__oo___oo__oo____oo__oo____oo___oo____oo__oooo___oo_
oo______oo_oo_oo_oo_oo____oo_oo_____oo_oo_____oo_oo____oo__oo______oo_oo_oo__oo_
oo______oo__ooo__oo_oooooo___ooooooooo_oo_____oo_ooooooo___oo______oo_oo__oo_oo_
oo______oo_______oo_oo_______oo_____oo_oo____oo__oo____oo___oo____oo__oo___oooo_
ooooooo_oo_______oo_oo_______oo_____oo_oooooo____oo_____oo____oooo____oo____ooo_
________________________________________________________________________________
Responder Con Cita
  #14  
Antiguo 24-08-2014
Yugo Yugo is offline
Miembro
NULL
 
Registrado: jul 2014
Posts: 25
Poder: 0
Yugo Va por buen camino
Qué tal Impadron!! muchas gracias por tu comentario. Después de analizar un poco tu código, hay algo que no entiendo muy bien:

Básicamente, para el primer par de campos de la TABLA2, esa subconsulta que expones devuelve por un lado el campo ID1 de la TABLA2 del registro actual (con la comparación),

Código:
ID ='"Query1->FieldByName("id")->Text"'
por otro lado devuelve el campo RE1 de la TABLA2 del registro actual (con la misma comparación anterior) y finalmente, devuelve el campo Nombre de la TABLA1 que coincide tanto con ID1 como con RE1 y dicha columna la renombra como PAR_ID1RE1... No sé si estoy en lo cierto o no.

Código:
"(SELECT nombre FROM tabla1 WHERE ID1 IN (SELECT ID1 FROM table2 WHERE ID = '"Query1->FieldByName("id")->Text"') AND RE1 IN (SELECT RE1 FROM table2 WHERE ID = '"Query1->FieldByName("id")->Text"') ORDER BY nombre ASC) AS PAR_ID1RE1, "
Esa parte de la subconsulta SELECT entiendo que nos sirve para determinar la operación sobre el registro actual y no sobre otro cualquiera ¿cierto? Si es así, esa comparación de datos debería realizarse entre números enteros porque el campo ID de la TABLA2 es de tipo INTEGER. Si estoy equivocado te agradecería que pudieses sacarme de la duda.

Por otro lado, he probado tu código pero al compilar me salta un error E2121. Function call missing ) y por más que le doy vueltas al código no encuentro dónde puede faltar ese paréntesis de cierre que se supone que falta.

En cuanto al asunto de pasarte el código SQL de creación de las tablas, debo decir que las creé directamente desde el Database Desktop y rellené con datos desde él. Pero no te preocupes, trato de crear el código y pasártelo, ¿te parece bien? Bueno me pongo a ello compañero. Hasta luego y muchísimas gracias de nuevo.

PD: Ecfisa compañero, he estado también trabajando sobre el código que expusistes para ajustarlo a lo que necesito pero aún no doy con la tecla. Puedo encontrar las posibles coincidencias sobre el primer par ID1-RE1, así que traté de hacerlo usando un bucle de 13 repeticiones (para los 13 pares de campos de un registro), pero nada, de momento no tengo resultado. Seguiré experimentando para tratar de dar con la solución con vuestra ayuda. Saludos!!
Responder Con Cita
  #15  
Antiguo 24-08-2014
Avatar de ecfisa
ecfisa ecfisa is offline
Moderador
 
Registrado: dic 2005
Ubicación: Tres Arroyos, Argentina
Posts: 10.508
Poder: 36
ecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to behold
Hola Yugo.
Cita:
Empezado por Yugo Ver Mensaje
...
PD: Ecfisa compañero, he estado también trabajando sobre el código que expusistes para ajustarlo a lo que necesito pero aún no doy con la tecla. Puedo encontrar las posibles coincidencias sobre el primer par ID1-RE1, así que traté de hacerlo usando un bucle de 13 repeticiones (para los 13 pares de campos de un registro), pero nada, de momento no tengo resultado. Seguiré experimentando para tratar de dar con la solución con vuestra ayuda. Saludos!!
Mira, lo que yo entendí es que hay que comparar cada par de columnas REx ~ IDx del registro actualmente posicionado en TABLA2 con cada par de columnas RE1 ~ ID1 de cada registro de la TABLA1 y mostrar la columna NOMBRE de TABLA1 cuando se halle una coincidencia.

Te adjunto las fuentes de un demo que hace lo anterior para que puedas revisarlo con tranquilidad. Crea una carpeta en tu disco y descomprimí el archivo ZIP allí. (incluye las tablas).

Saludos
Archivos Adjuntos
Tipo de Archivo: zip Yugo.zip (620,7 KB, 1 visitas)
__________________
Daniel Didriksen

Guía de estilo - Uso de las etiquetas - La otra guía de estilo ....
Responder Con Cita
  #16  
Antiguo 26-08-2014
Yugo Yugo is offline
Miembro
NULL
 
Registrado: jul 2014
Posts: 25
Poder: 0
Yugo Va por buen camino
Hola ecfisa, tu código está genial. El resultado de la búsqueda devuelve las posibles coincidencias entre los pares ID1/RE1 de la TABLA1 con todos los pares IDx/REx de la TABLA2 listando todos los nombres coincidentes en ese registro actual. Pero lo que estoy tratando de averiguar, basándome en ese código sería tratar cada par IDx/REx como un par independiente del resto de pares de la TABLA2. ¿Para qué hacer eso? Pues al considerar dichos pares como independientes unos de otros, tomo el primero de ellos, busco posibles coincidencias con la TABLA1 y si las hay, sólo me interesa coger el primer nombre del resultado de la consulta (por ejemplo, añadiendo en la TABLA1 que me facilitas otro registro como [Armando]-[1]-[1] habría dos registros con el mismo ID1-RE1 pero con nombre distinto). Entonces, si nos situamos sobre un registro cualquiera de la TABLA2, empezamos con una primera consulta sobre el primer par independiente ID1-RE1 de la TABLA2:
Código:
  QueryNames->Close(); 
  QueryNames->SQL->Clear(); 
  QueryNames->SQL->Add("SELECT T1.NOMBRE"); 
  QueryNames->SQL->Add("FROM TABLA1 T1 JOIN TABLA2 T2 ON T2.ID = :PID AND"); 
  QueryNames->SQL->Add("(T1.ID1 = T2.ID1 AND T1.RE1 = T2.RE1)"); 
  QueryNames->SQL->Add("ORDER BY Nombre"); 
  QueryNames->ParamByName("PID")->AsInteger = QueryTabla2->FieldByName("ID")->AsInteger; 
  QueryNames->Open();
Obtendríamos en el resultado de la consulta dos coincidencias ID1 = 1 y RE1 = 1, los nombres Pedro y Armando. De los cuales sólo me interesaría tomar el de Armando por ser el primero en orden alfabético.

Después de esto, pasaría al segundo par independiente de la TABLA2 (con los campos ID2-RE2) para volver a realizar la consulta en busca de posibles coincidencias con la TABLA1:
Código:
  QueryNames->Close(); 
  QueryNames->SQL->Clear(); 
  QueryNames->SQL->Add("SELECT T1.NOMBRE"); 
  QueryNames->SQL->Add("FROM TABLA1 T1 JOIN TABLA2 T2 ON T2.ID = :PID AND"); 
  QueryNames->SQL->Add("(T1.ID1 = T2.ID2 AND T1.RE1 = T2.RE2)"); 
  QueryNames->SQL->Add("ORDER BY Nombre"); 
  QueryNames->ParamByName("PID")->AsInteger = QueryTabla2->FieldByName("ID")->AsInteger; 
  QueryNames->Open();

Y así sucesivamente para los 13 pares de forma independientes.

Yo he tratado de hacer un bucle for de 13 repeticiones tal que así:
Código:
  for(int x = 1; x <= 13; x++) { 
    QueryNames->Close(); 
    QueryNames->SQL->Clear(); 
    QueryNames->SQL->Add("SELECT T1.NOMBRE"); 
    QueryNames->SQL->Add("FROM TABLA1 T1 JOIN TABLA2 T2 ON T2.ID = :PID AND"); 
    QueryNames->SQL->Add("(T1.ID1 = T2.ID"+IntToStr(x)+" AND T1.RE1 = T2.RE"+IntToStr(x)+")"); //(T1.ID1 = T2.IDx AND T1.RE1 = T2.REx) 
    QueryNames->SQL->Add("ORDER BY Nombre"); 
    QueryNames->ParamByName("PID")->AsInteger = QueryTabla2->FieldByName("ID")->AsInteger; 
    QueryNames->Open(); //Aquí tomaría el primer nombre del resultado 
  }
Pero de momento no doy con la tecla. Un saludo y muchísimas gracias!!

Última edición por ecfisa fecha: 26-08-2014 a las 20:35:38. Razón: corregir problema WYSWYG
Responder Con Cita
  #17  
Antiguo 04-09-2014
Yugo Yugo is offline
Miembro
NULL
 
Registrado: jul 2014
Posts: 25
Poder: 0
Yugo Va por buen camino
Hola chicos!! después de hacer varias pruebas, gracias a vuestra ayuda he podido conseguir lo que buscaba en un principio con el siguiente código situado en el evento OnDataChange del TDataSource2:

Código:
 for(int x = 1; x <= 13; x++)
 {
    Query2->Close();
    Query2->SQL->Clear();
    Query2->SQL->Add("SELECT T1.NOMBRE");
    Query2->SQL->Add("FROM TABLA1 T1 JOIN TABLA2 T2 ON T2.ID = :PID AND");
    //(T1.ID1 = T2.IDx AND T1.RE1 = T2.REx)
    Query2->SQL->Add("(T1.ID1 = T2.ID"+IntToStr(x)+" AND T1.RE1 = T2.RE"+IntToStr(x)+")"); 
    Query2->SQL->Add("ORDER BY Nombre");
    Query2->ParamByName("PID")->AsInteger = Query1->FieldByName("ID")->AsInteger;
    Query2->Open();

    if(!Query2->FieldByName("Nombre")->AsString.IsEmpty())  //Si la consulta devuelve un resultado
   {
     //aquí quiero cambiar la propiedad Caption del TLabel que corresponde a Label[x] ya previamente situado
     //en el Form.
   }
   else
   {
     //No hacemos nada. No modificar la propiedad Caption que previamente tiene el TLabel nº [x]
   }

 }
Mi duda está en cómo hacer referencia a cada objeto TLabel situado en el Form para modificar su propiedad Caption dentro del bucle for, donde el índice de cada etiqueta corresponde con la vble. x de dicho bucle, es decir,
Labelx ..... [Label1..Label13].

Gracias de nuevo.
Responder Con Cita
  #18  
Antiguo 04-09-2014
Avatar de ecfisa
ecfisa ecfisa is offline
Moderador
 
Registrado: dic 2005
Ubicación: Tres Arroyos, Argentina
Posts: 10.508
Poder: 36
ecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to behold
Hola Yugo.

Me alegro mucho que hayas solucionado ese tema, pero por favor publica esta nueva consulta en un nuevo hilo como indica la guía de estilo

Saludos
__________________
Daniel Didriksen

Guía de estilo - Uso de las etiquetas - La otra guía de estilo ....
Responder Con Cita
  #19  
Antiguo 04-09-2014
Yugo Yugo is offline
Miembro
NULL
 
Registrado: jul 2014
Posts: 25
Poder: 0
Yugo Va por buen camino
De acuerdo ecfisa. Voy a ello y muchas gracias por vuestra ayuda!!
Responder Con Cita
  #20  
Antiguo 16-09-2014
Avatar de lmpadron
lmpadron lmpadron is offline
Miembro
 
Registrado: feb 2009
Ubicación: Habana, Cuba
Posts: 204
Poder: 16
lmpadron Va por buen camino
hahaha que gusto ver que encontraste la solución !!!, disculpen por desaparecer toda la semana pasada pero estaba "fuera de toda tecnología" en un curso !!!. Saludos Yugo, Ecfisa
__________________
Nunca esta de más volver a ver la "Guia de Estilo" o "La Otra Guia de Estilo". Recuerda siempre usar los "Tags" para una mejor legibilidad de tu código.


Cuando miras fijamente al abismo, este te devuelve la mirada


oo______ooo_____ooo_ooooooo_____ooo____oooooo____ooooooo______oooo____ooo____oo_
oo______oooo___oooo_oo____oo__oo___oo__oo____oo__oo____oo___oo____oo__oooo___oo_
oo______oo_oo_oo_oo_oo____oo_oo_____oo_oo_____oo_oo____oo__oo______oo_oo_oo__oo_
oo______oo__ooo__oo_oooooo___ooooooooo_oo_____oo_ooooooo___oo______oo_oo__oo_oo_
oo______oo_______oo_oo_______oo_____oo_oo____oo__oo____oo___oo____oo__oo___oooo_
ooooooo_oo_______oo_oo_______oo_____oo_oooooo____oo_____oo____oooo____oo____ooo_
________________________________________________________________________________
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Migrar version BCB6 Toni C++ Builder 6 20-10-2014 14:44:32
TurboPower Systool bcb6 eldonfsr C++ Builder 0 15-01-2008 04:11:35
Coincidencia?? vtdeleon Debates 2 28-04-2006 13:43:17
Exportación de datos de Excel a Tablas Paradox Mone Conexión con bases de datos 1 31-10-2005 21:15:40
Como buscar en una tabla Paradox ? gregorio Tablas planas 2 25-04-2005 18:54:29


La franja horaria es GMT +2. Ahora son las 18:31:19.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi